Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

125
Visualizações
Replace multiple placeholders with their corresponding values in string

I have a command to make a custom welcome message so when someone say changes the title to the custom placeholder {user.id} it would change the title to the joining users ID

I tried ${(cardText, placeholders)} but that just returns [object Object] in the embed

So cardText is {user.tag} so i want it to look in placeholders and see if there is a placeholder in the string and if there is change it to the right value so in this case it would change it to member.user.tag

Code:

module.exports = async (client, member) => {
    
    const guildSchema = require('../../models/guildSchema');
    const data = await guildSchema.findOne({
        id: member.guild.id
    });
 
    const placeholders = {
        '{client.avatar}': client.user.displayAvatarURL(),
        '{client.username}': client.user.username,
        '{client.mention}': client.user,
        '{client.tag}': client.user.tag,
        '{client.id}': client.user.id,
 
        '{user.avatar}': member.user.displayAvatarURL(),
        '{user.username}': member.user.username,
        '{user.mention}': member.user,
        '{user.tag}': member.user.tag,
        '{user.id}': member.user.id,
 
        '{guild.memberCount}': member.guild.memberCount,
        '{guild.icon}': member.guild.iconURL,
        '{guild.name}': member.guild.name,
        '{guild.id}': member.guild.id,
    };
    
    const cardTitle = (data.welcome.title === null) ? 'Welcome To The Server' : data.welcome.title;
    const cardText = (data.welcome.text === null) ? '{user.tag}' : data.welcome.text;
    const cardSubtitle = (data.welcome.subtitle === null) ? 'Member Count: {guild.memberCount}' : data.welcome.text;
 
        const embed = new Discord.MessageEmbed()
        .setTitle(`${(cardTitle, placeholders)}`),
        .setDescription(`${(cardText, placeholders)}`),
        .setFooter(`${(cardSubtitle, placeholders)}`),
 
        channel.send({ embeds: [embed] });
}
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

The problem with OP's code was that the example they were following had some conventions that let users have templating in their message text denoted by {}.

For example, in 'Member Count: {guild.memberCount}', the {guild.memberCount} would be replaced to give us 'Member Count: 123' or something.

But the function to replace this placeholders was missing from their source.

Hence, a parsing function such as:

const replacePlaceholder = (template, placeholders) => {
  //if there is no placeholder, return.
  if (template.indexOf('{') === -1) return template;
  //get the string inside the {}
  const toReplace = template.slice(
    template.indexOf('{'),
    template.indexOf('}') + 1
  );

  //keep replacing until { character is not found.
  return replacePlaceholder(
    template.replace(toReplace, placeholders[toReplace]),
    placeholders
  );
};

was needed. In this context, it also makes sense why OP was using:

const embed = new Discord.MessageEmbed()
  .setTitle(`${(cardTitle, placeholders)}`),
  .setDescription(`${(cardText, placeholders)}`),
  .setFooter(`${(cardSubtitle, placeholders)}`),

They were originally function calls such as:

const embed = new Discord.MessageEmbed()
  .setTitle(`${replacePlaceholder(cardTitle, placeholders)}`),
  .setDescription(`${replacePlaceholder(cardText, placeholders)}`),
  .setFooter(`${replacePlaceholder(cardSubtitle, placeholders)}`),
about 4 years ago · Juan Pablo Isaza Relatório

0

Let's use regular expressions to do the matching for us. Because your keys have characters that have special meaning in regular expressions ({ and }), we'll need to escape those.

Pulled from escape-string-regexp:

const escapeRegex = (string) => string
    .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
    .replace(/-/g, '\\x2d');

Then let's write a function that takes a template and the placeholders. We should create a regular expression from the placeholder like this:

const regex = new RegExp("(" + Object.keys(placeholders).map(escapeRegex).join("|") + ")", "g");

For each key in the placeholders object, we escape the special characters, and join it all with |, wrapping the result in parentheses. Then we give it the g (global) flag so it provides us all the matches.

For you, this generated regex would look something like:

/(\{client.avatar\}|\{client.username\}|...|\{guild.id\})/g

Lastly, we want to use this regex and replace all occurrences of placeholders with their corresponding value.

return template.replace(regex, (_, match) => placeholders[match]);

So the full code looks like this:

const escapeRegex = (string) => string
    .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
    .replace(/-/g, '\\x2d');

function fill(template, placeholders) {
    const regex = new RegExp("(" + Object.keys(placeholders).map(escapeRegex).join("|") + ")", "g");

    return template.replace(regex, (_, match) => placeholders[match]);
}

Example usage:

fill("My name is {name}!", { "{name}": "Kelly" }); // "My name is Kelly!"

You can try it out here, just click the link and hit "Run". To the right you'll see the output.


Why don't we just use something like this:

template
    .replaceAll("{client.avatar}", placeholders["{client.avatar}"])
    .replaceAll("{client.username}", placeholders["{client.username}"])
    .replaceAll(...)
    // ...

Well first of all, that's not really DRY, is it? You could help with that using a loop:

for (const [place, value] of Object.entries(placeholders)) {
    template = template.replaceAll(place, value);
}

But then there's a catch! What if some placeholder's value contained another placeholder? Then you'd replace the new placeholder with a new value! This might lead to unexpected behavior, which is why I suggested using this solution instead; replace all matches at once, preventing this from happening.

Placeholders:

{bar} => i love {foo}
{foo} => 42

And then:

say {bar}
say i love {foo}
say i love 42

Uh oh!

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda