Jump to content

"Page Reference" field selections change based on template's location?


Lance O.
 Share

Recommended Posts

I'm working on a site that has both a "Blog" and a "News" section.

I'd like to be able to use the same "Post" template for child pages of each of these sections.

The catch is that the "Post" template needs to include a Page Reference field that should display categories specific to "Blog" posts -or- specific to "News" posts. In other words, the categories for these two sections are different.

What is the best approach in displaying a "Categories" field on the "Post" template that would display the appropriate categories based on if the post is located in the "Blog" or the "News" section?

 

Page tree looks like this:

Blog
        Posts
                Blog Post 1 (Categories field should only reference blog categories)
                Blog Post 2
                Blog Post 3
        Categories
                Blog Category 1
                Blog Category 2
                Blog Category 3
News
        Posts
                News Post 1 (Categories field should only reference news categories)
                News Post 2
                News Post 3
        Categories
                News Category 1
                News Category 2
                News Category 3

Link to comment
Share on other sites

I faced with a very similar same issue (here) in the past. There's some good discussion and solutions in that post. To summarize:

If you're not using "Allow new pages to be created from field" feature, you can provide a selector string or hook into "InputfieldPage::getSelectablePages" to return only the pages you want to appear. If you're using Autocomplete inputs or creating new pages from the field it wont work.

There's no elegant solution to this as far as I know. But, you have several options:

  1. Duplicate the page field and add both to the post template. Hide one or the other depending on the parent.
  2. Duplicate the template as well and add a single field to a template (and distinguish it with blog-post & news-post).

Then you can include one template file inside the other to reduce duplication etc. Hope this helps.

  • Like 3
Link to comment
Share on other sites

Thanks for your quick response, abdus, and for providing a link to the earlier discussion. Rather than spend any more time on a solution, I think I'll just create two different templates based on your suggestion. Thank you!

  • Like 1
Link to comment
Share on other sites

14 hours ago, abdus said:

If you're not using "Allow new pages to be created from field" feature, you can provide a selector string or hook into "InputfieldPage::getSelectablePages" to return only the pages you want to appear. If you're using Autocomplete inputs or creating new pages from the field it wont work.

With a bit of hooking it is possible to both dynamically control the selectable pages for a PageAutocomplete inputfield, and dynamically set the parent/template of new pages created from the inputfield. I have only played around with this and haven't used it in production, so use it at your own risk. :)

Dynamic selectable pages for PageAutocomplete

The idea is that in the field settings you define a broad selector that includes all of the pages you might want to select. It could be something really broad such as "has_parent!=2". Then you modify the selector in a hook according to the page being edited.

In /site/ready.php...

$wire->addHookAfter('Field::getInputfield', function(HookEvent $event) {
    $field = $event->object;
    $inputfield = $event->return;

    // Only for this one Page Reference field
    if($field->name !== 'test_page_field') return;

    // Only for ProcessPageEdit
    if($this->process != 'ProcessPageEdit') return;
    $page = $this->process->getPage();

    // Get findPagesSelector (or findPagesSelect if you used that)
    $selector = $inputfield->findPagesSelector;

    /*
    Now append to or overwrite $selector however you like, depending on $page maybe.
    You can even define some $allowed PageArray like with the "Custom PHP code" option that is
    possible with other Page inputfields, and then use it in the selector as "id=$allowed".
    But note that there is a 500 character limit enforced on selectors.
    */

    // Set the modified selector back to the property you got it from
    $inputfield->findPagesSelector = $selector;
});

 

Dynamic parent and/or template for pages created from the inputfield

The idea is that in the field settings you do not define a parent or template for allowed pages, but then set these properties in a couple of hooks according to the page being edited.

In /site/ready.php...

$wire->addHookBefore('InputfieldPage::renderAddable', null, 'dynamicParentandTemplate');
$wire->addHookBefore('InputfieldPage::processInputAddPages', null, 'dynamicParentandTemplate');

function dynamicParentandTemplate(HookEvent $event) {
    $inputfield = $event->object;

    // Only for this one Page Reference field
    if($inputfield->hasField->name !== 'test_page_field') return;
    
    // Only for ProcessPageEdit
    if(wire()->process != 'ProcessPageEdit') return;
    $page = wire()->process->getPage();

    // Now set $parent_id and $template_id dynamically depending on $page
    $parent_id = 1234; // demo value
    $template_id = 56; // demo value

    $inputfield->parent_id = $parent_id;
    $inputfield->template_id = $template_id;
}

 Have fun! :)

  • Like 4
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...