Jump to content
MilenKo

Filter pages by "category"

Recommended Posts

Hello my friends. Today I started working on my recipe website again and it was the turn to show recipes (pages) that has a specific category assigned in a field.

In my NowKnow project for categories I used a parent page where inside of it I had the children and everything seemed to be super easy. This time, however, I decided to change the approach so I created a parent page Recipe categories and assigned to it my 'category' template. Inside the parent I added a few categories that I want to be able to select via PageReferrence field 'recipe_category'.

The parent template would show all the categories represented by a title and an image - that part is done and works fine. 

Now what I am trying to achieve is to have a few recipes having the 'recipe_category' field equal to Bakery for example, and then when I point to the category URL to get only the recipes that have Breakfast selected in. From what I know the perfect approach to achieve that would be to use $input->urlSegment as to select the name of the category from the URL and then filter the pages adding to selectors: recipe_category=$category.  Following Ryans earlier instructions about the urlSegment and an example found here in the forum, I got this code to fit my fields names:

<?php if($input->urlSegment1 == 'category' && $input->urlSegment2) {
$name = $sanitizer->pageName($input->urlSegment2);
$category = $pages->get("template=categories-list, title=$name"); 
  if($category->id) {
  	$q = $pages->find("template=recipes-inner, recipe_category=$category"); 
  }
} ?>

After adding the code, I enabled the URL segments for both: 'category' and 'category-list' templates. Browsing the URL for the Bakery category:

http://food.pw/category/bakery/ (the domain name is not a typo, but PW is on my local server) I was supposed to get the $category to get the value of 'bakery'. However instead of that I am getting nothing.

What am I missing in the big picture as I am sure it is again something silly but I spent almost the whole day trying to figure it out and still got no progress?

P.S. trying to change the urlSegment number to 3 did not help either :(

Share this post


Link to post
Share on other sites

Hello @MilenKo,

first of all I noticed that you search for a pageName value in a title field. When you want to search a pageName I think you should search in the name value:

name=$name

Second you are talking about the template category-list and searching for categories-list. I hope this is just a typo, but if not you should correct this.

I would suggest you to dump everything step by step for example with TracyDebugger to get to the collection of pages you are looking for. ;)

Regards, Andreas

  • Like 1

Share this post


Link to post
Share on other sites

Hello AndZyk.

I must have changed name with title while trying to figure what is happening. So I changed the code to:

<?php if($input->urlSegment1 == 'category' && $input->urlSegment2) {
$name = $sanitizer->pageName($input->urlSegment2);
$category = $pages->get("template=categories-list, name=$name"); 
if($category->id) {
$q = $pages->find("template=recipes-inner, recipe_category=$category"); 
}
} ?>

And made sure that all template names are correct, however when I echo the $category it shows empty. It feels to me that $input->urlSegment does not get results. I have the tracy debugger installed and it shows no errors so I need to figure out what else I am missing. I tripple checked the urlSegment settings are enabled for 'category' and 'caegories-list' .. Will try to take it step by step and figure out what is stopping the urlSegment to resolve the proper name and assign it to the $category.

Share this post


Link to post
Share on other sites

Ok, I tested the if-query for $input->urlSegment1 and found out that something gets wrong in there:

<?php if($input->urlSegment1 == 'category' && $input->urlSegment2) {
echo 'urlSegment statement works';
} ?>

So nothing shows as a result.

I attached a screenshot of the URL settings of the template. Anything else seems to stop the proper resolving. Could the reason of not working be the fact that I work on a localhost instead of having FQDN for proper resolving?

Spoiler

categories-list-segmenturl.jpg

P.S. I even tried to allow category, bakery and other category segments in the allow url segments field but still got nothing...

Share this post


Link to post
Share on other sites

@fbg13 I used the following code to print the segments:

<?php if($input->urlSegment1 == 'category' && $input->urlSegment2) {
$segment1 = $sanitizer->pageName($input->urlSegment1);
$segment2 = $sanitizer->pageName($input->urlSegment2);
echo $segment1;
echo $segment2;
} ?>

and it shows nothing for segment1 and segment2

 

Share this post


Link to post
Share on other sites

Do it outside the if statement and without sanitizing them.

  • Like 1

Share this post


Link to post
Share on other sites

Ok. This time removed the if statement and tested the following code:

<?php 
$segment1 = $input->urlSegment1;
$segment1 = $input->urlSegment2;
echo $segment1;
echo $segment2;
} ?>

but it still shows no results...

Share this post


Link to post
Share on other sites

To what template/template file are you adding the code? Do you have a page with the name "category"?

Share this post


Link to post
Share on other sites

Try to print the entire $input array to show what's inside it:

<?php
print_r($input);
?>

And have you tried the use of regex on the allow url segments field?

regex:^category/[a-z]+$

 

Share this post


Link to post
Share on other sites

@fbg13 I have the following structure and templates;

Recipes (recipes) - /recipes/
    Recipe1 (recipes-inner) - /recipes/recipe1
    Recipe2 (recipes-inner) - /recipes/recipe2
    Recipe3 (recipes-inner) - /recipes/recipe3
    Recipe4 (recipes-inner) - /recipes/recipe4
Categories (categories) - /category/
    Category1 (categories-list) - /category/category1
    Category2 (categories-list) - /category/category2
    Category3 (categories-list) - /category/category3
    Category4 (categories-list) - /category/category4

@Sérgio Jardim When I tried to print_r($input), I got this: ProcessWire\WireInput Object ().

 

Share this post


Link to post
Share on other sites

So you have a category page.

$segment1 = $input->urlSegment1;
$segment1 = $input->urlSegment2;
echo $segment1;
echo $segment2;

You assign both segments to the same variable $segment1, but you echo $segment1 and $segment2.

Since you have a page with the name "category" i assume you are on that page.

In this case your first segment is not a segment but a page and your 2nd segment is actually your first.

So $segment1 points to $input->urlSegment2, which doesn't exist, and $segment2 is not defined/null/empty.

  • Like 1

Share this post


Link to post
Share on other sites

@fbg13 Sorry, it was a typo as I was typing the code manually. The proper code is:

<?php 
$segment1 = $input->urlSegment1;
$segment2 = $input->urlSegment2;
echo $segment1;
echo $segment2;
} ?>

The url I am trying to access is: http://food.pw/category/bakery/  where I guess the $input->urlSegment1 should be 'category' and the $input->urlSegment2 should be 'bakery' which is what I need to run a query and show all the recipes which has the 'bakery' assigned in the recipe-inner template through field 'recipe_category' which is a Page reference (Page Autocomplete) pulling data from Categories page children.

@Sérgio Jardim I tried using your suggested regex expression to allow the URL Segments and after refreshing the page I got the same reply: ProcessWire\WireInput Object () 

when trying to echo $segment1 & $segment2

 

Share this post


Link to post
Share on other sites
19 minutes ago, MilenKo said:

I guess the $input->urlSegment1 should be 'category' and the $input->urlSegment2 should be 'bakery'

But you have a page named category, which is the same as the urlsegment you want to use, don't know how PW handles that exactly.

If you wanna share the code (site profile) i can take a look.

 

  • Like 1

Share this post


Link to post
Share on other sites

Well I renamed the page name to Recipe Categories which points to /category/ but that did not change much the result.

Do you know of any profile example I could have a look for filtering pages by a field value using urlSegment? As I checked the SkyScrapers but the buildings are organized differently and I do not find some logic similar to my case I could use.

For sure I could switch the categories to become parents inside the Recipes and then just point to childrens but I would like to extend my knowledge on using urlSegments and that is why I did not organize it that way.

Share this post


Link to post
Share on other sites

Can't think of anything else.

29 minutes ago, MilenKo said:

Do you know of any profile example

Don't know.

Share this post


Link to post
Share on other sites

As far as I am still bumping my head against the wall I decided to give it a try by moving the profile to my actual domain. Doing so would allow me to eliminate a possible issue with the segments on local server and eventually demonstrate if a need be what is the setup, fields etc.

Share this post


Link to post
Share on other sites

Tried moving the profile to my real domain, but that does not change anything. On one side - I am glad as it is easier for me to work on my local server versus online but on the other end - the saga continues. 

Does anyone know if there are any requirements for apache/php modules in order to make the urlSegments to work? Or any information about the proper way of setting up templates and options would be good for starters. So far it was pinpointed that the $input->urlSegment1 & 2 does not get values of 'category' and 'bakery' while browsing the url: food.pw/category/bakery/ 

Regex allowing expression did not change anything as well.

Share this post


Link to post
Share on other sites
5 hours ago, MilenKo said:

Tried moving the profile to my real domain

Meaning you exported it and installed ProcessWire while choosing it during the install process? It should work, however, normally I just copy over all files and the database too, adjust site/config.php and .htaccess and it should work if requirements are met. In some rare cases you might also need to trucate the cache table of the db, see:

urlSegments are integral part of the system, they should work if everything else works too I guess.

 

  • Like 1

Share this post


Link to post
Share on other sites

Your setup is currently a mix of two approaches. The urlSegment approach clashes with your category site structure, since urlSegments only work for sub paths that don't exist in the site tree.

To match up your design with Ryan's events example, the category page wouldn't have a template that is supposed to be rendered on the website. You would assign your categories-list template to /recipes, then url segments would be active for every request for /recipes/something for which there isn't a real "something" page under /recipes. Then you could call /recipes/category/bakery and have "category" in urlSegment1 and "bakery" in urlSegment2. The /category tree would just be there to hold data, not to be rendered.

  • Like 3

Share this post


Link to post
Share on other sites

@szabesz Yes, I just exported the whole profile which would allow me to upgrade easily my PW to 3.0.65 or downgrade if a need be. It all worked the same way it did on the localhost but not with the urlSegments.

@BitPoet What you say makes perfect sense now and explains why it would not work in my scenario. Considering the fact, that I already have a page Recipe Categories which would point to food.pw/categories/ and just need to be able to browse to a specific category showing the pages that have it selected, would you suggest another approach other than creating the categories as parents and placing the recipes as children of them? I did a profile already that way and it worked just fine, but I was trying to extend my knowledge using the present approach.

Thank you guys for sharing your experience. It means a lot to me! Even though PW has been flawless so far for my needs, I am not just trying to make the profile work but have some learning curve I could use in the future to extend my knowledge and have eventually one much smarter, simpler and cleaner sollution.

P.S. Reading your suggested approach, I am afraid that I already gone far in developing the recipe-inner template which is assigned for every recipe and pulls up quite a lot of frontend formatting etc. so I won't be able to assign the category-list template to my recipes and break the functionality that is already at a final stage.

  • Like 1

Share this post


Link to post
Share on other sites

@MilenKo Lets take a step back.

Create a page named "test-url-segments" with home as parent and assign it a template (whichever), edit that template and enable url segments.

Edit the template file for the template assigned to "test-url-segments" and echo $input->urlSegment1.

Now go to domain.tld/test-url-segments/i-am-a-segment and you should see i-am-a-segment and you where you echoed $input->urlSegment1.

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, MilenKo said:

Considering the fact, that I already have a page Recipe Categories which would point to food.pw/categories/ and just need to be able to browse to a specific category showing the pages that have it selected, would you suggest another approach other than creating the categories as parents and placing the recipes as children of them?

If you only ever have one category per recipe, putting the recipes in their category is perfectly fine. One usually uses url segments if one item can belong to multiple categories, like a bread roll recipe belonging to bakery, bread and vegetarian at the same time, and/or if you have (or are expecting to add) other filtering criteria similar to categories (ingredients, preparation time, rating, year...) on the same list page so you might end up with a query link like /recipes/category/bakery/ingredient/flour. It all depends on how complex you plan your site to get.

1 hour ago, MilenKo said:

P.S. Reading your suggested approach, I am afraid that I already gone far in developing the recipe-inner template which is assigned for every recipe and pulls up quite a lot of frontend formatting etc. so I won't be able to assign the category-list template to my recipes and break the functionality that is already at a final stage.

You don't have to touch the recipe template/pages themselves, you could simply assign the categories-list template to the recipes' parent and pull in the found recipes. But, as I wrote above, you can keep with your current approach and do things the straight forward way. It would probably be best to toy around with url segment based searches a bit before you implement them in a real life project. I've always got a few "playground" sites on my dev machine for testing things like that, sites which I just delete when they get too convoluted and replace with a fresh install of PW.

  • Like 2

Share this post


Link to post
Share on other sites

@fbg13 Trying your suggested approach showed properly the url segments. Now I would try to rething the template logic so that if a need be the segments work fine.

@BitPoet You got straight to the point and the reason why I tried implementing the categories by a field in recipe-inner template - as I am expecting to have several cases where a recipe fals into different categories and would need to be listed when a request comes (eg. low sodium, salads, easy recipes etc.) 

So other than using urlSegments to filter the category, are there any other mechanisms that would allow me to get the name of the category from the url and use it as a filter criteria in my query? As of now the only filtering I would need would be by category as the rest of the website would be listed as a search result.

As far as the url to access categories is not food.pw/recipes/category/subcategory  but  food.pw/category/subcategory I guess I should redo the 'category' template and add some logic there (if there are no subcategories in the url, then list the categories with images and links, but if there is an urlSegment - show filter results).

It gets interesting, however it was proven that urlSegments work, so now it is up to me to find the best approach to make it work.

Thank you all for the knowhow!

Share this post


Link to post
Share on other sites

@MilenKo I'm really confused on what template you're actually working/adding code?

 

Can you echo the template name (echo $page->template->name;) of food.pw/category/subcategory?

Also echo $input->urlSegment1 and go to food.pw/category/subcategory/test, let me know what you get.

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Bacelo
      Hi there,
      I have a bit of trouble on filtering correctly some event pages by some selectors...
      I do have the following 2 date fields:
      - start date (fieldname = date)
      - end date (fieldname = enddate)

      Some events are a single day event (only start date) - some are a multi day event (end date).
      Past single day events should not show up.
      Current multi day events should show up (even if start day is in the past, but end date is future).
      So I have the following selector:
      if ($standort == '') { $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); } else { $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); } This selector
      $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); works fine, but the follwing does not work (all past entries are also shown):
      $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); I have no clue what I'm missing - any ideas?
    • By Aleksey Popov
      Hi! Is it possible to specify explicitly the parent section when creating a new child page with a single template?
      The idea is to save the user from the possibility of mistakenly choosing a section, but not to create unnecessary identical templates
      What I mean:
      Let's say I've got 2 parent categories with names articles & news. Each of them utilized the same admin-template (category) with the category.php file. Also, I have 2 different templates for child pages (article & news).
      Next, I need to add an article page to the articles category with the "create new" button in admin. At that moment, I must choose the category to place (because both categories use the same template). 
      To runaround this (and create a page right into the exact category without the choosing step) I should create 2 templates for each category, and setup parent-children relations for each pair of templates, right?
      But Is any way to use only the one category template and different children templates and at the same time, explicitly specify which section to use for child pages, thereby removing the process of selecting a child section?
       
      articles (category.php) Article page 1 (page-article.php) Article page 2 (page-article.php) Article page 3 (page-article.php) + Add a new article page here without category chooser news (category.php) News page 1 (page-news.php) News page 2 (page-news.php) News page 3 (page-news.php)  Update: found module  but I can't get it work.
       
    • By Moritz Both
      Greetings,
      when I give users the user-admin-* permission to administer users who have a certain role, they can indeed see and edit those users. However the filter / column panel does not show in the admin interface. How can I enable the filter functionality for user-admin-* members?
      ProcessWire 3.0.123
      Moritz
    • By pwFoo
      How to enable urlSegments runtime instead of persistent in template settings? And where to be loaded before the current page returns a 404 error?
      https://processwire.com/docs/front-end/how-to-use-url-segments/#how-do-you-enable-url-segments
       
    • By j00st
      Hi all,

      I've set up a filter on my product-page, which I then use to...filter my products!
      – I've got pagination set up, and 30 items per page.
      – When I active the filter it works perfectly (in my opinion).
       
      Here's what I'm struggling with though:
      When I'm on another page (filtered as well/or the total overview) and I put my GET request in for the filter,
      it gives back the result, but still with the page-number there. In some cases, this is no problem – like a A-Z or Z-A filter,
      but others (say, per location) I might have less pages.
      Visual/code ref: (I DO have 3 pages of authors, but I don't have 3 pages from London)
      url: books/page3?author=ascending url: books/page3?studio=london  
      The current setup for my pages that get rendered are as follows:
      $allbooks = $pages->find("template=book, sort=$sort, $q, $tagged, $select_studio, start=0, limit=$limit"); As you can see I have the start=0 in there, but I read that's for the start of the pagination, not so much where it'll drop me in the search results.
      $q, $tagged and $select_studio are all empty values, unless they're returned from the GET request
      To repeat it, in it's most simplest form:
      When I click a filter, and a GET request is done, I want to 'reset' the page-number to 0, and get my results...
      Perhaps I'm missing something obvious, but I'd be really grateful to have your input.
×
×
  • Create New...