Jump to content

Attepting to Fetch Pages Based Off of Field Match in Latte Filter


protro
 Share

Recommended Posts

Hello PW forums,

I have an interesting problem I am trying to solve. I am displaying a list of artists, that are children of the parent page Artists.

{foreach $pages->get("name=artists")->children() as $item}

These children pages act as tags for other pages which have a field 'artist', and are appropriately tagged.
I am trying to send the link's href attribute to the latest project page for that artist, rather than the default, which is a sort of artist index page listing all the projects for that artist.

<a href="{$pages->get('template=concert-visuals|broadcast|music-videos, artist.name={$item->name}')->first->url}"> 
  {$item->title}
</a>

I can't seem to fetch anything. What am I missing here ?

Link to comment
Share on other sites

  • protro changed the title to Attepting to Fetch Pages Based Off of Field Match in Latte Filter

First thing to check is if your $pages->get() call works at all. For example in the tracy console. You are using $pages->get() which will return a single Page object (or NullPage), so your ->first is wrong, i guess.

Next, I think you can't use { } brackets inside { } brackets when you are outputting a string. This will NOT work:

{var $item = $pages->get(2)}
<a href="{$pages->get("name={$item->name}")->url}">
  {$item->title}
</a>

This will work:

{var $item = $pages->get(2)}
{var $url = $pages->get("name={$item->name}")->url}
<a href="{$url}">
  {$item->title}
</a>

And this is what I'd recommend you to do:

Create a Site.module.php in /site/modules/Site

<?php

namespace ProcessWire;

// expose the site module as global site() function
function site(): Site
{
  return wire()->modules->get('Site');
}

// module code
class Site extends WireData implements Module
{

  public static function getModuleInfo()
  {
    return [
      'title' => 'Site',
      'version' => '0.0.1',
      'summary' => 'Site Module',
      'autoload' => true,
      'singular' => true,
      'icon' => 'bolt',
      'requires' => [
        'RockMigrations>=3.34',
      ],
    ];
  }
}

Then add the following method:

public function getShowByArtist(Page $item) {
  return wire()->pages->get('template=concert-visuals|broadcast|music-videos, artist.name={$item->name}');
}

Which cleans up your template a lot and will help you to write better (DRY) code, as you have one place to store the logic. If you need the same link url in another place of your website you simple call the same method and not copy paste the selector. If the selector changes over time (for example adding another template to the selector) all your links will still work by only updating one place in your code (and not many).

<a href="{site()->getShowByArtist($item)->url}"> 
  {$item->title}
</a>

Or even better use Custom Page Classes and add the getShowByArtist method directly to your $page object.

  • Like 3
Link to comment
Share on other sites

thank you so much @bernhard for showing the method for building a module. I really appreciated this answer. I ended up modifying the code to for a simplified extension of a Custom Page Class, in case anyone else want's to see how that works.

in DefaultPage.php

<?php namespace ProcessWire;
class DefaultPage extends Page {

    public function getShowByArtist() {
        return $this->wire()->pages->get("template!=news-item, artist.name='{$this->name}'");
    }
    
}

and in the template like so:

<a href="{$item->getShowByArtist()->url}">
	{$item->title}
</a>


By the way @bernhard, maybe you could elaborate something I encountered that I can't quite piece together. This function `getShowByArtist()` is getting called on the home template, and on the front-end appears on the homepage, but when I tried adding the above function declaration to HomePage.php custom page class, I would get exceptions that the function is unavailable/not call-able.

I am using the Rockfrontend method such that in site/templates/layouts/home.php

<?= $rockfrontend->renderIf("sections/home.latte", "template=home") ?>

And in home.latte is where I am calling the function inside of the a href (as above).

However, it only seems to work when I put the getShowByArtist() function declaration inside of the DefaultPage.php custom page class … even though in Tracy Debugger it shows my template as home and the class as \ProcessWire\HomePage on the page in which this function gets invoked (correctly).

Why could that be ? Any ideas ?
Again, your help has been much appreciated. I might leave the function inside DefaultPage.php for now.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...