Snippet not loading without its php wrapper also within snippet

I am building a blog site. Each blog post has links to other recommended internal blog posts. There are also links to internal blog posts when readers do a search for a term, select a tag, or go to the archives page. I want all of these blog post links to be identical, and they each include title, date, tags, and image specific to the post they link to.

So I made a single snippet I was hoping to apply to each of the locations a link like this might appear. It won’t call anything though. The only way it works if if the php wrapper is present in the actual snippet. For example:

<!-- THIS IS THE PHP WRAPPER START, FOR CALLING TAG RESULTS -->
<?php foreach($site->page('blog')
                   ->children()
                   ->visible() 
                   ->filterBy('tags', param('tag'), ',')
                   ->flip() as $result): ?>

<!-- THIS IS THE SNIPPET CONTENT (simplified to just call title for demonstration purposes here) -->
  <p>
    <a href="<?php echo $result->url() ?>">
      <?php echo $result->title()->html() ?>
    </a>
  </p>

<!-- THIS IS THE PHP WRAPPER START
  <?php endforeach ?>

This defeats the point of having a snippet, since the php wrapper is different for each page/location the link (snippet content) would need to appear, so I’d need to have that many individual snippets. I want one piece of code to keep track of these links to internal blog posts, since I want them to be identical everywhere.

Hope this is making sense! I have tried lots of things, I suspect it may be something to do with the concept of “passing variables to snippets” (https://getkirby.com/docs/templates/snippets) but I haven’t figured out how to make that work. I could be doing something wrong. Thanks in advance so so so very much for any and all help!

Could you share your snippet code or at least what variables you are using in your snippet that are defined outside of your snippet?

Hi, thanks for the quick reply! What I shared earlier was the snippet in the only form I can get it to work.

Ideally, it would only have to be like this:

      <p>
        <a href="<?php echo $result->url() ?>">
          <?php echo $result->title()->html() ?>
        </a>
      </p>

…at least to call the title (and then I also have similar for calling the date, image, etc for each post they’d link to, but just showing title for simplicity).

And what I’d like is for the original templates to house the php wrappers that define “$result”, and call the snippet within them.

For instance, from the blog posts that link to other relevant internal blog posts (listed in a section in the .txt file called relevantreading):

<?php foreach($page->relevantreading()->pages() as $result): ?>
  <?php snippet('result') ?>
<?php endforeach ?>

When you select a tag of a post, the results that appear bearing the same tag should also be able to call that same snippet:

<?php foreach($site->page('blog')
                   ->children()
                   ->visible() 
                   ->filterBy('tags', param('tag'), ',')
                   ->flip() as $result): ?>
  <?php snippet('result') ?>
<?php endforeach ?>

And the archive list of all existing posts should too:

<?php foreach($site->page('blog')
                   ->children()
                   ->visible() 
                   ->flip() as $result): ?>
  <?php snippet('result') ?>
<?php endforeach ?>

It’s just that this way is not working. Let me know if you need more clarification! Thanks very, very much!

I think what you are asking here are different use cases.

When you click on a link for a tag, you would usually be redirected to the list of articles, i.e. the blog page, with the only difference that this time, the articles should be filtered by tag.

So in your blog.php controller, you would use an if-statement, which checks if you filter by tag or not.

// blog.php controller
return function($site, $pages, $page) {
 
 if($tag = param('tag')) {
  $articles = page('blog')->children()->visible() ->filterBy('tags', $tag, ',');
} else {
  $articles = page('blog')->children()->visible();
}

  return compact('articles', 'pagination');

};

Unless you want to show these articles on the same page as the article page that is currently loaded, but then you would have to use some ajax script to load the articles into the same page when the tag is clicked?

As regards your archive, I’m not quite sure what you want to filter by, but in general, if would work in the same way and this thread could also be useful: Blog archive - filtering articles by months

Your related pages problem could be solved by passing the page variable:

<?php foreach($page->relevantreading()->pages() as $result): ?>
<?php snippet('result', array('result' => $result)) ?>
<?php endforeach ?>

BTW: Pls. wrap blocks of code within three backticks on a separate line before and after each block of code. Thank you.

Edit: in your archive list you can do the same

<?php foreach($site->page('blog')
                   ->children()
                   ->visible() 
                   ->flip() as $result): ?>
  <?php snippet('result', array('result' => $result)) ?>
<?php endforeach ?>

Actually for the tags, I am having the matching blog posts with the selected tag show up on their own “tags” page. When you click on a tag, it will take you to a new page with all the blog posts filtered to just show those with the selected tag.

I don’t think it accounts for the issue I was encountering either way, though.

Ok, but that does not really make a difference, I showed above how you can pass the variable to the snippet, so that should work. If the problem persists, pls. let me know.

THANK YOU! That worked! I guess I just needed some help passing the proper variables the correct way; this is a huge help. :grin:

Glad that it helped. If you need any further assistance, please feel free to ask :slight_smile: