ov3rtak3r

Render other Page depending on URL Segments

Recommended Posts

Hello everyone!

I am new to Processwire and really like it, but now I have a problem that I can't solve by myself.

I have created following templates:

data_people (no template-file)
person_listing (person_listing.php)
person_detail (person_detail.php)

I have added the following Pages:

Actor, Director, Stuff using template person_listing.php [visible in frontend]
"People" using template data_people [not visible, only for data]
-> "Georg Klonee" using template person_detail [is visible, but should not be shown using path /en/person/georg-klonee]

Example Person: Georg Klonee

The Problem:

He is a Actor and a Director, so I want him to be shown in the Listing of /en/actors and /en/directors. No problem until here - it works. But now, when I click him, the URL for the Detail-Page is unfortunately /en/person/georg-klonee. But I want it to be /en/actors/georg-klonee, if i open the details from Actors-Page (and of course /en/directors/georg-klonee when on Directors-Page).

How can I get this to work? I am also using TemplateEngine-Module with TemplateTwigEngine-Module, hopefully this won't be a problem? I tried it with URL-Segments for person_listing.php. But how can I abort the rendering of people_listing and start rendering person_detail.php?

 

Thanks for your help in advance. :)

Share this post


Link to post
Share on other sites

I found a way to solve my problem, the Post helped me too:

Quote

 

The code looks the following and works with the TemplateEngineModule. If you want my solution to work without the TemplateEngineModule, remove the line $view->setFilename('person');.

Template person_listing Settings in Backend:

The allowed Page URL Segments:

regex:^[0-9a-zA-Z\-\_]+$

Template person_listing.php Code:

if ($input->urlSegment1) {
  
  $pagename = $input->urlSegment1;
  $match = $pages->get('name='.$pagename);
  if (!$match->id) throw new Wire404Exception();
  $view->setFilename('person'); // Remove this line if you don't use TemplateEngineModule!
  echo $match->render();
	
  return $this->halt();
}

Hope this helps someone else.

  • Like 2

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 Noel Boss
      Page Query Boss
      Build complex nested queries containing multiple fields and pages and return an array or JSON. This is useful to fetch data for SPA and PWA.
      You can use the Module to transform a ProcessWire Page or PageArray – even RepeaterMatrixPageArrays – into an array or JSON. Queries can be nested and contain closures as callback functions. Some field-types are transformed automatically, like Pageimages or MapMarker.
      Installation
      Via ProcessWire Backend
      It is recommended to install the Module via the ProcessWire admin "Modules" > "Site" > "Add New" > "Add Module from Directory" using the PageQueryBoss class name.
      Manually
      Download the files from Github or the ProcessWire repository: https://modules.processwire.com/modules/page-query-builder/
      Copy all of the files for this module into /site/modules/PageQueryBoss/ Go to “Modules > Refresh” in your admin, and then click “install” for the this module. Module Methods
      There are two main methods:
      Return query as JSON
      $page->pageQueryJson($query); Return query as Array
      $page->pageQueryArray($query); Building the query
      The query can contain key and value pairs, or only keys. It can be nested and 
      contain closures for dynamic values. To illustrate a short example:
      // simple query: $query = [ 'height', 'floors', ]; $pages->find('template=skyscraper')->pageQueryJson($query); Queries can be nested, contain page names, template names or contain functions and ProcessWire selectors:
      // simple query: $query = [ 'height', 'floors', 'images', // < some fileds contain default sub-queries to return data 'files' => [ // but you can also overrdide these defaults: 'filename' 'ext', 'url', ], // Assuming there are child pages with the architec template, or a // field name with a page relation to architects 'architect' => [ // sub-query 'name', 'email' ], // queries can contain closure functions that return dynamic content 'querytime' => function($parent){ return "Query for $parent->title was built ".time(); } ]; $pages->find('template=skyscraper')->pageQueryJson($query); Keys:
      A single fieldname; height or floors or architects 
      The Module can handle the following fields:
      Strings, Dates, Integer… any default one-dimensional value Page references Pageimages Pagefiles PageArray MapMarker FieldtypeFunctional A template name; skyscraper or city
      Name of a child page (page.child.name=pagename); my-page-name A ProcessWire selector; template=building, floors>=25
      A new name for the returned index passed by a # delimiter:
      // the field skyscraper will be renamed to "building": $query = ["skyscraper`#building`"]  
      Key value pars:
      Any of the keys above (1-5) with an new nested sub-query array:
      $query = [ 'skyscraper' => [ 'height', 'floors' ], 'architect' => [ 'title', 'email' ], ]  
      A named key and a closure function to process and return a query. The closure gets the parent object as argument:
      $query = [ 'architecs' => function($parent) { $architects = $parent->find('template=architect'); return $architects->arrayQuery(['name', 'email']); // or return $architects->explode('name, email'); } ] Real life example:
      $query = [ 'title', 'subtitle', // naming the key invitation 'template=Invitation, limit=1#invitation' => [ 'title', 'subtitle', 'body', ], // returns global speakers and local ones... 'speakers' => function($page){ $speakers = $page->speaker_relation; $speakers = $speakers->prepend(wire('pages')->find('template=Speaker, global=1, sort=-id')); // build a query of the speakers with return $speakers->arrayQuery([ 'title#name', // rename title field to name 'subtitle#ministry', // rename subtitle field to ministry 'links' => [ 'linklabel#label', // rename linklabel field to minlabelistry 'link' ], ]); }, 'Program' => [ // Child Pages with template=Program 'title', 'summary', 'start' => function($parent){ // calculate the startdate from timetables return $parent->children->first->date; }, 'end' => function($parent){ // calculate the endate from timetables return $parent->children->last->date; }, 'Timetable' => [ 'date', // date 'timetable#entry'=> [ 'time#start', // time 'time_until#end', // time 'subtitle#description', // entry title ], ], ], // ProcessWire selector, selecting children > name result "location" 'template=Location, limit=1#location' => [ 'title#city', // summary title field to city 'body', 'country', 'venue', 'summary#address', // rename summary field to address 'link#tickets', // rename ticket link 'map', // Mapmarker field, automatically transformed 'images', 'infos#categories' => [ // repeater matrix! > rename to categories 'title#name', // rename title field to name 'entries' => [ // nested repeater matrix! 'title', 'body' ] ], ], ]; if ($input->urlSegment1 === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Module default settings
      The modules settings are public. They can be directly modified, for example:
      $modules->get('PageQueryBoss')->debug = true; $modules->get('PageQueryBoss')->defaults = []; // reset all defaults Default queries for fields:
      Some field-types or templates come with default selectors, like Pageimages etc. These are the default queries:
      // Access and modify default queries: $modules->get('PageQueryBoss')->defaults['queries'] … public $defaults = [ 'queries' => [ 'Pageimages' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus', ], 'Pagefiles' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'filesize', 'filesizeStr', 'hash', ], 'MapMarker' => [ 'lat', 'lng', 'zoom', 'address', ], 'User' => [ 'name', 'email', ], ], ]; These defaults will only be used if there is no nested sub-query for the respective type. If you query a field with complex data and do not provide a sub-query, it will be transformed accordingly:
      $page->pageQueryArry(['images']); // returns something like this 'images' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus'=> [ 'top', 'left', 'zoom', 'default', 'str', ] ]; You can always provide your own sub-query, so the defaults will not be used:
      $page->pageQueryArry([ 'images' => [ 'filename', 'description' ], ]); Overriding default queries:
      You can also override the defaults, for example
      $modules->get('PageQueryBoss')->defaults['queries']['Pageimages'] = [ 'basename', 'url', 'description', ]; Index of nested elements
      The index for nested elements can be adjusted. This is also done with defaults. There are 3 possibilities:
      Nested by name (default) Nested by ID Nested by numerical index Named index (default):
      This is the default setting. If you have a field that contains sub-items, the name will be the key in the results:
      // example $pagesByName = [ 'page-1-name' => [ 'title' => "Page one title", 'name' => 'page-1-name', ], 'page-2-name' => [ 'title' => "Page two title", 'name' => 'page-2-name', ] ] ID based index:
      If an object is listed in $defaults['index-id'] the id will be the key in the results. Currently, no items are listed as defaults for id-based index:
      // Set pages to get ID based index: $modules->get('PageQueryBoss')->defaults['index-id']['Page']; // Example return array: $pagesById = [ 123 => [ 'title' => "Page one title", 'name' => 123, ], 124 => [ 'title' => "Page two title", 'name' => 124, ] ] Number based index
      By default, a couple of fields are transformed automatically to contain numbered indexes:
      // objects or template names that should use numerical indexes for children instead of names $defaults['index-n'] => [ 'Pageimage', 'Pagefile', 'RepeaterMatrixPage', ]; // example $images = [ 0 => [ 'filename' => "image1.jpg", ], 1 => [ 'filename' => "image2.jpg", ] ] Tipp: When you remove the key 'Pageimage' from $defaults['index-n'], the index will again be name-based.
       
      Help-fill closures & tipps:
      These are few helpfill closure functions you might want to use or could help as a
      starting point for your own (let me know if you have your own):

      Get an overview of languages:
          $query = ['languages' => function($page){         $ar = [];         $l=0;         foreach (wire('languages') as $language) {             // build the json url with segment 1             $ar[$l]['url']= $page->localHttpUrl($language).wire('input')->urlSegment1;             $ar[$l]['name'] = $language->name == 'default' ? 'en' : $language->name;             $ar[$l]['title'] = $language->getLanguageValue($language, 'title');             $ar[$l]['active'] = $language->id == wire('user')->language->id;             $l++;         }         return $ar;     }]; Get county info from ContinentsAndCountries Module
      Using the [ContinentsAndCountries Module](https://modules.processwire.com/modules/continents-and-countries/) you can extract iso
      code and names for countries:
          $query = ['country' => function($page){         $c = wire('modules')->get('ContinentsAndCountries')->findBy('countries', array('name', 'iso', 'code'),['code' =>$page->country]);         return count($c) ? (array) $c[count($c)-1] : null;     }]; Custom strings from a RepeaterTable for interface
      Using a RepeaterMatrix you can create template string for your frontend. This is
      usefull for buttons, labels etc. The following code uses a repeater with the
      name `strings` has a `key` and a `body` field, the returned array contains the `key` field as,
      you guess, keys and the `body` field as values:
          // build custom translations     $query = ['strings' => function($page){         return array_column($page->get('strings')->each(['key', 'body']), 'body', 'key');     }]; Multilanguage with default language fallback
      Using the following setup you can handle multilanguage and return your default
      language if the requested language does not exist. The url is composed like so:
      `page/path/{language}/{content-type}` for example: `api/icf/zurich/conference/2019/de/json`
       
          // get contenttype and language (or default language if not exists)     $lang = wire('languages')->get($input->urlSegment1);     if(!$lang instanceof Nullpage){         $user->language = $lang;     } else {         $lang = $user->language;     }     // contenttype segment 2 or 1 if language not present     $contenttype = $input->urlSegment2 ? $input->urlSegment2 : $input->urlSegment1;     if ($contenttype === 'json') {         header('Content-type: application/json');         echo $page->pageQueryJson($query);         exit();     } Debug
      The module respects wire('config')->debug. It integrates with TracyDebug. You can override it like so:
      // turns on debug output no mather what: $modules->get('PageQueryBoss')->debug = true; Todos
      Make defaults configurable via Backend. How could that be done in style with the default queries?
      Module in alpha Stage: Subject to change
      This module is in alpha stage … Query behaviour (especially selecting child-templates, renaming, naming etc)  could change
    • By rareyush
      <?php namespace ProcessWire; $form = $modules->get('FormTemplateProcessor');$form->template = $templates->get('book-now'); // required $form->requiredFields = array('title', 'email', 'number','body'); //$form->email = 'your@email.com'; // optional, sends form as email $form->parent = $page('template=book-now'); // optional, saves form as page //$form->render(); // draw form or process submitted form ?> <?php echo $form->render(); ?>  
       
      using this to for a contact on new processwire version 3  and I am receiving this error
       
      Error: Uncaught Error: Call to undefined method stdClass::render() in C:\wamp64\www\mbs\site\templates\book-now.php:9  
      tried following but none of them works
       
      render(array('name','email','body',))
      wireRender()
       
      Render()
      wire()
       
      anyone ?  
    • By Lance O.
      I've built a site that uses parent pages as the "container" for child pages:
      Parent page [page.php] -- Child page [unit-child-a.php] -- Child page [unit-child-b.php] ---- Grandchild page [subunit-grandchild-a.php] ---- Grandchild page [subunit-grandchild-b.php] -- Child page [unit-child-c.php] The child pages are displayed as content on the corresponding parent page using the render method. Some child pages also include their own child pages. (Internally the child page template names start with "unit-" and the grandchild page template names start with "subunit-".)
      Example:
      foreach ($page->children("template=template-name,sort=sort") as $child) echo $child->render(); This approach allows content administrators to add and reorder child pages as necessary, but I've come across an issue that I'm not sure how to address.
      The site includes search functionality, but when a visitor searches for content and it is found in a child or grandchild page, the Parent page should be the one that is displayed in the search results, since the child and grandchild pages are not directly viewable. Since some searches could include more than one child or grandchild page of a parent page, this sometimes means that a parent page could be included more than once.
      How do I easily redirect the child and grandchild pages to the parent page, and only include the parent page once in the search results?
       
    • By matsn0w
      Hey everyone, hope you're all doing well!
      I'm building my first ProcessWire website at the moment, which is of course a very good way to understand all of the possibilities ProcessWire has to offer. But that also means that I'm facing some troubles now and then, and so is the case right now.
      I made a template for a couple of pages, like the homepage, the contact page, etc. I am using Bootstrap 4.0 for the layout. 
      So here's the deal: I want to show an alert box on top of every page, warning the user that the website is still under construction. Of course, I can just include the code and add the fields I made for the alert into the template, but that means I have to do that for every page, which I obviously don't want. So I made a template with the code and fields for the alert. When I did this, I realised that I can create multiple alerts this way, so I made two pages, containing different alerts. (And converted the code into a foreach-loop in the template).
      But now my question; how can I include these pages in a different template? Can I make a field or something to insert a page or is this simply not possible? Or do I have to approach this in a different way?
      I hope I explained my problem clear!
      Thank you in advance,
      matsn0w
    • By kaba86
      Hello PW Community, really glad that discovered this CMS recently, it is very strange it took so long That idea of no front design limitations is just awesome!
      Need to say that I have a bit of knowledge of html and css, but almost no php, so I need your help.
      What I want to do is an article posting  cms, with this structure:
       
      - Homepage - Projects - Articles -- Category 1 --- Articles of category 1 -- Category 2 --- Articles of category 2 - About - Contact Found this ProcessWire Profile https://github.com/tutsplus/how-to-create-an-ajax-driven-theme-for-processwire
      It covers almost all my needs, except the menu. When I add a childpage for this page http://artist.nicegrp.com/publications/world-world/ , World:World doesn't appear under Writings & Publications.
      I need a menu that works like a breadcrumb, that shows on the menu the category that you are viewing. So when I'm in articles page, on the menu it shows only articles and it's categories. When I get into a category, that category takes state active link but doesn't show on the menu links and titles for contained articles. How can I do that?
      Sorry for my long writing and English, it is not my native but I hope you understood what I need. Can you help me with that?
      Thank you