I have a snippet for an article link. That snippet basically creates a box with the title, a content excerpt, and image of a page.
I want to be able to use that snippet inside a KirbyTag aswell. For example, (article: my-article-id)
would render that snippet and use the given article for the page. Here’s how the tag looks:
'tags' => [
'article' => [
'html' => function ($tag) {
$posts = site()->children()->template('blog')->children()->template('post');
$post = $posts->find($tag->value);
if ($post) {
return snippet('article', ['page' => $post], true);
} else {
return '';
}
}
]
]
The problem is that I have indentation in my snippet and the resulting markup also has it. Then, Kirby parses that markup and renders indented code as a code block with <pre>
tags. This breaks the markup. How would I avoid that?
hmmm, that shouldn’t be happening afaik 
What is inside your article
-snippet?
Nothing special:
<a href="<?= $page->url() ?>">
<div class="article flex justify-between my-8 border">
<div class="px-6 py-6">
<h5 class="mb-2 font-bold text-base"><?= $page->title() ?></h5>
<p class="text-sm"><?= $page->text()->excerpt(140) ?></p>
</div>
<?php if (($image = $page->image()) && $image = $image->thumb(['width' => 500])): ?>
<div class="flex-shrink-0 w-1/3 bg-cover bg-center" data-src="<?= $image->url() ?>" mb-image></div>
<?php endif ?>
</div>
</a>
Everything after the blank line is rendered in <pre>
. However, the same thing happens if I replace all that with just:
<strong>test</strong>
If I remove the leading 4 spaces, there is no <pre>
tag. Therefore, the problem is not in the snippet.
I just checked. In a recent project I did it like this to make snippets work in custom tags. Don’t remember the exact reasons any more but perhaps this helps.
'tags' => [
'slider' => [
'html' => function($tag) {
$files = new Files();
foreach (Str::split($tag->value) as $path) {
if ($file = $tag->file($path)) {
$files->append($file);
}
}
$string = snippet('kirbytags/slider', [
'images' => $files,
'style' => 'for-article',
], true);
// replace line breaks with spaces to silence the markdown parser
return str_replace(PHP_EOL, ' ', $string);
}
]
]
2 Likes
I think that removing the newlines makes it work. Whitespace plays an important role in code formatting for markdown. In the snippet that I posted above if I remove the empty new line, the code works.
The problem with that is if you have a <pre>
tag in the snippet that you do want to appear, removing the newlines will effectively change the content. Removing newlines might have other side effects, I suppose. I think Kirby should handle this case itself so there are no surprises like that.
Or perhaps we should get a Html::stripWhitespace()
method that removes whitespace between tags. However, parsing HTML is always a bad idea and I don’t think that would be the best option.
@texnixe should I open an issue?
Yes, why not, but I think its rather a problem with Parsedown: Deactivate Markdown - #10 by texnixe
That was my assumption as well. But you can make use of the kirbytext:before
and kirbytext:after
hooks to overcome this issue.
'hooks' => [
'kirbytext:before' => function ($text) {
$tags = [
'article',
];
return preg_replace_callback('!\((' . implode('|', $tags) . ')+:.*?\)!is', function ($match) {
return '<!--' . substr($match[0], 1, -1) . '-->';
}, $text);
},
'kirbytext:after' => function ($text) {
$tags = [
'article',
];
return preg_replace_callback('!<\!--(' . implode('|', $tags) . ')+:.*?-->!is', function ($match) {
return kirbytags('(' . substr($match[0], 4, -3) . ')');
}, $text);
},
]
1 Like