Jump to content
usualCommission

[SOLVED] Pagination links render but do not work.

Recommended Posts

Hey everyone,

I'm pretty experienced with pagination and haven't seen this before. I have my pages pulled using $pages->find, which is working fine however using renderPager() generates pagination where the links do not work. Here are some details.

  • All templates needing pagination have pagination enabled in the admin.
  • URL Segments are not enabled.
  • Clicking on the "Next" or numbered links merely reloads the current page.
  • The link href values are properly being output with the urls being /page2, /page3, /page4, etc.
  • Manually entering the paginated urls has the same effect of reloading the current page with no new content.
  • Pages are being returned from the ->find function properly and with the proper limit.

A few other details:

  • ProcessWire v3.0.98
  • Multi-language is enabled, 2 languages implemented.
  • Pagination does not work on either language
  • Have very few modules installed (few enough to list), none of which I could see interfering:
    • ProFields, ProDrafts, ListerPro, DB Backups, Cronjob DB Backup, Upgrades, Upgrade Checker, Force Password Change, Markup Sitemap XML

I'm stumped. For the sake of being overly-thorough, here's the code:

<?php
  $articleTemplates = [
    'template_news_article',
    'template_news_video',
    'template_news_press_release'
  ];

  $searchParams = [
    'template=' . implode('|', $articleTemplates),
    'sort=-published',
    'limit=' . $pages->get('template=template_news')->list_count
  ];

  $articles = $pages->find(implode(',', $searchParams));
  
  echo $articles->renderPager();
?>

 

Share this post


Link to post
Share on other sites

So I figured out the source of the issue. I wrote some code that detects a user's preferred language either from their browser language setting, or from a cookie that is created when they have visited and chose a language last time.

If a preferred language detected and the current page URL does not match it, it will redirect to the same page but in the proper language.

My problem is finding a way to get the URL that includes the pagination to compare. Right now my idea is to use $input->pageNum to build the URL myself... is there a way to get the URL including the page number?

Lesson learned...

Share this post


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

is there a way to get the URL including the page number?

I'm not 100% I understand your question. Maybe you can try combination of $input->pageNum and $pager->getURL()? E.g.:

$articles->getURL($input->pageNum());

Note the caveat in the $pager->getURL() method at the above link.

Could this topic be of interest?

 

 

Edited by kongondo

Share this post


Link to post
Share on other sites

Yeah, I'm not explaining my situation well enough and it's becoming a little more complex.

I'm working on abstracting localization to a class where one of the methods is used to redirect the user to their preferred language. That preferred language is either the language preference they have set in their browser, or a language cookie that was set last time they visited and selected a language via a select dropdown in the nav. That said, since the method is run on page load it will not have any access to specific pagination instances because they don't exist yet.

I read the link above and didn't see a solution that covers all of the bases and the module reference in a link to another post is no longer maintained, so I am going to write a custom implementation.

Here's my solution:

  • Language detection will be tied to a unique session variable.
  • On page load, the script checks for that session variable, if it exists- it exits because the language has been checked/redirected if necessary on ingress already.
  • If no language session variable exists, then compare the destination URL against the URL of that page for their preferred language.
  • If the URLs do not match then build a new URL
  • The destination URL is checked for page numbering using $input->pageNum(), if  > 1 then create a URL string for that. Any GET variables are extracted and rebuilt into a string- this preserves any possible incoming variables like UTM trackers.
  • Get localized URL for user's preferred language, re-add page number, re-add any GET variables that existed.
  • Set unique language session variable, then properly redirect to the localized page using the build URL.

I kind of wish that there was a built in method that could wrap most of this up and preserve URL details while redirecting to a given translated page, but this should work and also only redirect once.

I may be over-complicating this but it's what I've got. I really appreciate your help!

Share this post


Link to post
Share on other sites

Something like this would be the easiest way, I can think of, to do what you are doing. Redirect to a another language, including urlSegments, Pagenumber and optional QueryStrings;

if($user->language->isDefault) {
	$user->language = $languages->get("de");
	$session->redirect($input->url($withQueryString = true));
}

 

  • Like 2

Share this post


Link to post
Share on other sites

That sets the user language properly but getting the $input->url(true) still gets the non-localized version of the URL so it doesn't redirect to the translated page. It loops and fails the redirect.

Also the language move has been a little rough because using the code below seems to lead to a possible solution but is where I was hitting the paging/GET issues.

$languages->setLanguage(-lang str here-); // Also sets the language as a $user->language assignment does
$page->localHttpUrl($user->language); // Returns the proper localized URL, but does not include pagination or GET vars

I've seen many posts in the forums about redirection to a language and all of them use $page->localUrl($user->langauge) and none consider GET vars. Multi-language documentation says that the $page->localUrl() will automatically adjust to pagination but I haven't seen it. Would still have to manually build GET vars.

 

Share this post


Link to post
Share on other sites

How about getting the url-segments/page-num/get-vars suffix and then appending that to $page->localUrl?

$url_suffix = str_replace($page->url, '', $input->url(true));
$redirect_url = $page->localUrl() . $url_suffix;

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Added that to a comparison and that did the trick! Here's the method after adding your trick:

private function doInitLocalization() {
  $page = wire('page');
  $user = wire('user');
  $input = wire('input');

  // Get/set user language from either browser or cookie
  $user->language = $this->getLangFromCookie() ?: $this->getValidBrowserPrefLang();

  $urlSuffix = str_replace($page->url, '', $input->url(true));
  $userUrl = $page->localUrl($user->language) . $urlSuffix;

  if ($_SERVER['REQUEST_URI'] !== $userUrl) {
    header("Location: {$userUrl}");
  }
}

getLangFromCookie() checks if the user has visited previously and selected a language from a dropdown.
getValidBrowserPrefLang() gets the language pref sent by the browser, if it exists as a language in the CMS, returns the value.

By setting the language for the user this checks against what the browser request asked for/server is delivering vs. what the CMS knows it should be delivering. If they differ, then redirect.

This is executed in _init.php so any point of ingress is checked for url vs. preference.

Thanks @kongondo for introducing me to $input->url and the good idea for direction.
Thanks @Soma for concluding my head->desk marathon. Your solution is the simple one I couldn't see.

 

Share this post


Link to post
Share on other sites

When you change the $user->language, all following API returns stuff in that language also, the $page->url or $input->url. No need to do str_eplace on something already the same.

So if $this.>getLangFromCookie does return the language object then you can change it to this.

private function doInitLocalization() {
  $user = wire('user');
  $input = wire('input');

  // Get/set user language from either browser or cookie
  $language = $this->getLangFromCookie() ?: $this->getValidBrowserPrefLang();
  if($language !== $user->language) {
    $user->language = $language;
    $this->wire("session")->redirect($input->url(true));
  }
}

 

  • Like 1

Share this post


Link to post
Share on other sites

Good to know.

$this->getLangFromCookie() returns a string and is shared by other methods in the same/other classes. I could probably refactor it to work directly with the language object, but I'll have to come back to that sometime. Appreciate that info.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By brdje
      Greetings,
       
      I've created a product database which all use the template product.php and are published on the website.
      I'm trying to create an overview table with pagination of all the products, but using $pages->get does not return an object, only the object title.
      $products = $pages->get("template=product, limit=10"); This returns 10 strings in the frontend but not the object. When looping over the result set to get product fields, i get the following error:
      Notice: Trying to get property 'title' of non-object
       
      Because the product database is fairly large, i've added a pagination using the same query and this does return all the pages, but i can't click on the links that the paginator renders.
      $results = $pages->find("template=product, limit=10"); if($results->getTotal() > 10) { echo $results->renderPager(array( "nextItemLabel" => "Volgende", "previousItemLabel" => "Vorige", "currentItemClass" => 'active' )); }
      I've added the option in the template to allow page numbers. When i navigate to the link manually, i still end up seeing the 10 first products.
       
      I've tried changing several settings around, but i'm a bit stuck on how to resolve these issues. Do you have any advice what I need to adjust?
      Thanks in advance for your feedback.
       
       
    • By Peter Troeger
      Hello Community 🙂
      Has anyone ever tried having multiple elements on one page that get their info with $pages->find('selector, limit=n') and tried using pagination on one of these elements without effecting the other?
      I have a slider on a page where I display content with pagination. But when I go to page two, the slider content also goes to page two, which I don't want it to do 🙂
      Any tips are greatly appreciated!
      Thanks!
      -Peter
    • By Peter Troeger
      Hello 🙂
      I have set up pagination on a mulitlanguage site.
      I've done this before, but this time I have a problem I can't solve.
      Pagination is activated on 'parent-template' and 'child-template' just to be sure 🙂
      This is my code:
      $children = $page->children('limit=1'); foreach($children as $child) { $title = $child->title; echo $title; } echo $children->renderPager(); The navigation is output correctly and the link look correct as well 'parent-page/page2/'.
      But when I click the link, the site seems to redirect back to 'parent-page/
      Any help would be greatly appreciated 🙂
      - Peter
    • By MateThemes
      Hello everyone!
      I have a problem with pagination. I have following code:
      <div class="uk-section"> <?php $results = $pages->find("template=gallery, limit=10, sort=title"); $pagination = $results->renderPager(); echo $pagination; echo "<ul class='uk-pagination uk-flex-center'>"; foreach($results as $result) { echo "<li><a href='{$result->url}'>{$result->title}</a></li>"; } echo "</ul>"; echo $pagination; ?> </div> Which works fine. And this markup results in following html code:
      <div class="uk-section"> <ul class='uk-pagination uk-flex-center'> <li> <a href='/galerie-bisheriger-projekte/'>Galerie bisheriger Projekte</a> </li> <li> <a href='/galerie-bisheriger-projekte/galerie-1/'>galerie-1</a> </li> </ul> </div> But instead of "Galerie bisheriger Projekte" and "galerie-1" I want to have a number.
      And as last question, how can I add a previous and next button?
      Thanks for your help!
    • By Liam88
      Hi all,
      Quick question as I haven't found anything from my Googling. 
      I have a blog on the site which utilises pagination. On the standard blog page I have a custom header which has featured posts.
      Below that I then have recent posts like mosts blogs.
      Now if i click to page two or three I want the header to disappear and just show a continuation of the standard posts.
      I'm not sure how to go about this so any direction would be helpful.
      Thanks
×
×
  • Create New...