ManoMahe's avatar

How to write a common function or file for replaceable placeholder text in Laravel 9

Hello, I'm creating a project for email content editor with some default placeholders which will be replaceable with the user data stored in database. I have created & completed the content editor part, after that I don't get any proper clue to start a common function or file which will replace the placeholder's text with the dynamic relation model values and this function or file need to be reusable with entire project.

For better understanding, I'm having a content with placeholders like,

"Hello {customer_name}, This is your content of the day {content_date}"

Which should be replaced with the database values dynamically,

"Hello Mano, This is your content of the day 3-Feb-2023"

Please note, I'm using One to Many relation model to get the content data. I need to use the same structural to be followed.

Sample code 1:

$contents = EmailContent::all();
foreach($contents as $inv)
{
    $message = $inv->email_content;
    $message = str_replace('{customer_name}' , $inv->customer->name, $message);
    $message = str_replace('{content_date}', $inv->content_date, $message);
}

The above sample code is working fine, but I need to be maintain the replaceable placeholders in a common file or function for other placeholders too.

Sample code 2:

$contents = EmailContent::all();
foreach($contents as $inv)
{
    $userData = User::find($inv->user_id);
    $message = $inv->email_content;
    $message = str_replace('{user_fullname}', $userData->fullname, $emailBody);
    $message = str_replace('{user_company_name}' , $userData->company_name, $emailBody);
}

So, what I want to achieve here is the placeholders are need to group together and maintain in a common place. Those records going to used for future add or update.

In the result of the file or function,

$message = str_replace('{customer_name}' , $inv->customer->name, $message);
$message = str_replace('{content_date}', $inv->content_date, $message);
$message = str_replace('{user_fullname}', $userData->fullname, $emailBody);
$message = str_replace('{user_company_name}' , $userData->company_name, $emailBody);
// return $message;
// or 
// echo $message;
0 likes
6 replies
Sinnbeck's avatar

That looks fine, except you overwrite the $message after every loop. Will it only be those two keys ?

ManoMahe's avatar

@Sinnbeck Sorry, I have updated my question with more details. Please check once again.

Sinnbeck's avatar

@ManoMahe Ok this is how you could do it. Set up an array of keys somewhere (a property on the model, or a config file, or an enum, or pass it in to the method)

$keys = [
    'customer_name',
    'content_date', //add more and move it somewhere that makes sense for you
];
$contents = EmailContent::all();
foreach($contents as $inv)
{
    $message = $inv->email_content;
    foreach ($keys as $key) {
        $message = str_replace('{' . $key . '}' , $inv->{$key}, $message);
    }
    
    $messages[] = $message;
}

In the case of ->customer->name, you will need to add an accessor on the $inv to get that. The same for any others that cannot be replicated. This system will allow you to pass in any array to replace, as long as you can resolved it on the $inv

1 like
ManoMahe's avatar

@Sinnbeck Yeah, I understand and this approach may works. But for the ->customer->name, there is any demo workaround or examples available? because I'm new being to Laravel, I don't familiar with this concept

Please or to participate in this conversation.