Jump to content
tiagoroldao

Possible buggy url Segments / Page Numbers Interaction

Recommended Posts

It's possible that I'm missing something, but I think I have found an small bug.

I am doing a simple page list template (/photos) that is paginated and has url segments on, to allow for filtering through tags. As there are multiple different lists, and they all share the same tags, I need to list the tags that are relevant to this particular list (i.e. the tags that are in any of the list's pages). 

I attempted:

foreach ($pages->get("/tags")->children() as $key => $tag) {
  if($pages->count("parent=$page, tags=$tag") > 0){
    echo "<li><a href='$page->url$tag->name' $active>$tag->title</a></li>";
  }
}

And it seemed to work... BUT it broke on my final page (on page 3 of a 3 page pagination). After doing some testing, I found that this selector, when using pagination, correctly counts all the pages that have the given tag, only if there is at least one in the current page.

So:

  • If tag A is in 10 pages, and in the current pagination segment there are any of them, the selector returns 10, as expected
  • If tag B is in another 10 pages, but none of them are in the current pagination segment, the selector returns 0.
  • If I change the selector to address all pages, removing the parent selector, the problem goes away but:
    • Any parent selector pointing to the current parent (being paginated) break this, be it $page, $page->id, or the url or id entered manually
  • The problem occurs without any url segments actually being used. Haven't tested thoroughly enough to be able to tell if it has the same behaviour with url Segments set (i.e. on a tag-filtered subselection of the pages)
  • This was using a page field with multiple pages (as it was for tags)

I solved the problem using:

foreach ($pages->get("/tags")->children() as $key => $tag) {
  if($pages->find("parent=$page, tags=$tag")->count() > 0){
    echo "<li><a href='$page->url$tag->name' $active>$tag->title</a></li>";
  }
} 

Which works well. I can only think of this as a bug, but I may be missing something.

Share this post


Link to post
Share on other sites

Hi there

Could you try it with getTotal() instead of count() - click on getTotal on this page as it seems to explain this in relation to pagination: http://cheatsheet.processwire.com/

Hope that helps!

Share this post


Link to post
Share on other sites

You could also do this:

foreach ($pages->get("/tags")->children() as $key => $tag) {
    if ($pages->find("parent=$page, tags=$tag")->getTotal() > 0) {
        echo "<ul>";
        foreach ($pages->find("parent=$page, tags=$tag") as $tagpage){
            echo "<li><a href='$tagpage->url$tag->name' $active>$tag->title</a></li>";
        }
        echo "</ul>";
    }
}

I just threw in the wrapping UL elements, but if you want to paginate the results it needs some more work anyway :)

Share this post


Link to post
Share on other sites

Thanks for the reply  :rolleyes: I've simplified the markup for illustration purposes, yeah :P

There is a difference between $pageArray->count() and $pages->count("selector") - for my purposes, $pageArray->count() and $pageArray->getTotal() are functionally the same, and they both work. The issue is with $pages->count("selector"), that works as a getTotal() call, without the need to actually return the array of pages (and thus, getting less overhead). But it seems to bug out in this instance.

Share this post


Link to post
Share on other sites

You can do a call with your selector but with a limit=2 for the getTotal() call. This has less overhead.

Share this post


Link to post
Share on other sites

I'm still concerned about this - I solved my problem, but I still consider the original issue to be a probably fixable bug.. Where should I submit it?

Share this post


Link to post
Share on other sites

When you are using pagination, PW assumes all of your selectors are paginated (see the side effects section on the pagination docs page). As a result, you need to tell it which ones are not by adding a "start=0" to it. I'm thinking this will fix the issue in your case?

Share this post


Link to post
Share on other sites

:rolleyes: Yes, I solved it with:

$pages->find("parent=$page, tags=$tag, limit=1, start=0")->count()

The "start=0" was just to make sure it went well, as PW 2.3, as far as I know, doesn't paginate queries with limit=1.

I don't think that's it. But I may be looking at it wrong:

Shouldn't $pages->count() not be paginated?

And I find it strange that this scenario occurs: If I have 100 pages spread out across 10 pages, 50 "a's" and 50 "b's", and do a $pages->count("parent=theParentOfThe100Pages, tags=a") in one of the 10 pagination pages, if there is at least one "a" page, the $pages->count() returns 50, but if there is no "a" page in this particular set of 10, $pages->count() returns 0.

One extra question:

If all queries are paginated, imagining I'm in /page10 of the pagination, showing pages 91~100 of my list. If I were to do a $pages->find() on an unrelated group of pages, using the same limit=10, but on a group of pages with 50 pages (effectively having 5 pages of results), what would happen? would the result be an empty array, from page6 onward?

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 ICF Church
      Hi 👋
      Anyone else having this problem?
      Requirements:
      - Repeater (matrix & normal) with mutlilanguage fields (text, textarea…) 
      - Backend language set to something other than default (ie. German) 
      Reproduce:
      - Add a new repeater Item (ajax, I found no way to possible to disable it with matrix)

      (Notice how the default language tab is active instead of the backend language…)
      - Write something into the (default language) field
      - Try to save, if field is required, this will not work. If not required, then when reloading, the content will be inside the backend language field, instead of the default language field who was (presumably) active
      Analysis:
      When  loading  a new repeater element with ajax, the default langue tab is active, but the backend language inputfield is visible (with no visual indication). When writing into the field, it will populate the backend language. When manually clicking on the default language tab (which is already active), the field will switch to the actual default language field (which is [now] empty) (that can now be populated…)
      Also Notice, the labels of the elements to be added are in default language as well instead of the translated label (images instead of Bilder)…
      ProcessWire 3.0.148, Profields 0.0.5…
      Is it my system configuration, or does anyone else have the same issue? This is a screen recording of the problem:

      Screen Recording 2020-02-25 at 14.18.31.mov
    • By Atlasfreeman
      So im doing a website. and i put on multi language on the website and uploaded some new images when i decide to make a new page...
      This i can't do anymore...

      It sais : 
      Add New
      The process returned no content.
      Unknown template.

      Well the website is showing fine, but i can't make new pages 😞

      Do any have any idea what to do?
    • By louisstephens
      So I have been hard at work creating url segments for a template (api) and everything is working swimmingly in creating a simple end point for svelte.js. I have however, run into a few questions that I can wrap my head around.
      In my api template I have:
      if($input->urlSegment1 === 'clients') { header('Content-Type: application/json'); $clients = $pages->find("template=clients"); $client_array = array(); foreach ($clients as $client) { $id = $client->id; $title = $client->title; $url = $client->url; $clientName = $client->client_name; $clientColor = $client->client_color->value; $assigned = $client->assigned_to->user_full_name; $client_array[] = array( 'id' => $id, 'code' => $title, 'name' => $clientName, 'associated_users' => $assigned, 'url' => $url ); } $client_json = json_encode($client_array, true); echo $client_json; } The output json from this is:
      [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was curious is it possible to add in "clients" before this output json so it would appear as 
      clients: [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was not really sure of how to tackle this in my php code, and have spent more time than I care to admit trying to figure it out. Another question I have is that "associated_users" is returning null, which in this instance is correct. It is a multi page field that is set to pull a custom name field from the users template, ie "Louis Stephens" would be associated with the first page. I understand that I need to use a foreach to get the correct data, but I was really unsure of how to place this inside an array, or update the array with the new data. Any help with any of this would greatly be appreciated.
    • By Moritz Both
      Greetings!
      For our PW project we use markup regions and, for one template, url segments. The documentation recommends throwing a new Wire404Exception() from the template when the code concludes that the url segments from the request are invalid, and so we do.
      However, the 404 page is not displayed properly. Viewing the page source in the browser we can see that the original, unmodified markup region contents from our _init.php file is prepended to the correct html output, messing the whole page up.
      Any advice is greatly appreciated.
    • By hansv
      Hi everybody
      I want to catch a variable from outside processwire into _main.php
      if(isset($_GET['u']) && $_GET['u'] !== ''){ $gebruikersnaam = $_GET['u']; ... ... This is working fine in a php file in a non processwire environment. 
      In a processwire environment, I get the variable when I refer to /site/templates/_main.php but a great part of my template-code is not shown. 
      From outside processwire I refer to    mydomain/index.php.  If I place   $gebruikersnaam = $_GET['u'];  in index.php, how can I pass through my variable to _main.php?   Or is there an other solution?
      thx
      hansv
×
×
  • Create New...