The boss said to me "Mr developer, I want Google ads to show in between my articles. One above and another below an article is just not good enough". In my mind, I held my head with my both hands and thought to myself how the heck am I suppose to do that? An article is one very long string of text saved in a relational database. Anyway, I said I'll figure out a way to do it and continued with other tasks.
While I was on other things, like every programmer knows, my subconscious was at work trying to figure out a way to achieve that task. Then boom! it dawned on me that I could just break the long string into an array and loop over it slotting the ads in using some kind of condition. Now the question is how do I break an article into an array (pieces). I went looking around the database to see how exactly the articles are stored.
Turns out each paragraph of an article is stored as an HTML
. I thought to myself perfect, I'll just use "
" as the delimiter to split the long string to paragraph bits. Since it was Laravel, PHP has this convenient "explode()" method, what a name right? π Also, I've always wondered by the delimiter has to be the first argument, I think it's intuitive to have the string as first arg though.$content = explore("</p>", $post->content);
Now, I have a way to break the string. But doing so would remove the closing tags for all "
"s. The solution is to loop over each array item and add the close tag back, using array_map() function.
$content = array_map(function ($c) {
return $c . "</p>";
}, $content);
I successfully made each paragraph an array item. Now, how do I slot in the ad? First, some articles are really short so I should make sure not to add ads in those. 5 became the number, if I split (aka explode) an article and the array items are not up to 5, no ad needs be there. Pass $content as a string in that case.
...
if (count(explode("</p>", $post->content)) >= 5) {
$content = explode("</p>", $post->content);
$content = array_map(function ($c) {
return $c . "</p>";
}, $content);
} else {
$content = "";
}
...
Alright, this would do for my controller method. Let's pass it down to blade.
...
return view('posts.show', [
'post' => $post,
'content' => $content,
]);
...
$post has all the properties of an article - title, categories, tags, author, etc
Enter Blade
...
@if (is_array($content))
@foreach ($content as $key => $i)
@if ($key > 0 && Str::length($i) >= 300 && $key % 5 === 0 && count($content) >= 10)
@include('google_ad')
@elseif(!(Str::length($i[floor($key / 5) * 5 -1]) >= 300) && $key % 8 === 0 && count($content) >= 12)
@include('google_ad')
@endif
<div class="post-content">
{!! $i !!}
</div>
@endforeach
@else
<div class="post-content">
{!! $post->content !!}
</div>
@endif
...
Here, the outer @if is checking if an article even qualifies for ads, else show normal $post->content
If an article qualifies I'm then checking if a paragraph is up to 300 characters and that paragraph is divisible by 5 (5th, 10th, 15th,...), lastly, if it passes the previous tests, the total paragraphs must be up to 10, then include an ad.
If the 5th (10th, 15th,...) paragraph isn't long enough (that calc is wild I know) let's insert an ad after every 8th paragraph, provided the article is up to 12 paragraphs this time. The idea is if I've printed ad at position 15, 16th shouldn't even bother, 20th should have 24th skip, you get idea.
Well, there you go. In case, you've wondered how to slot ads or anything in between a long string of text.
Top comments (0)