Jump to content
awesomolocity

Optimal Way To Structure Pages... (Page Reference vs Children)

Recommended Posts

Alright. So I'm converting a site I already have to Processwire (really enjoying it so far!). I wanted to convert the previous tables that I had data in to Processwire pages. But I'm wondering what the optimal way to structure pages would be.

 

So basically, I have three main tables.

Users (and all accompanying information)

Items (and all accompanying information)

Aquariums (each user only has 1 aquarium. Currently, user_id is a FK)

Fish (type of item. Aquariums may have multiple fish)

Aqua_settings (Things like lightness, temperature, etc)

 

So in my current setup, there are a lot of Foreign Keys. I could accomplish essentially the same thing by using the Page Reference field.

Alternatively, I could make fish and aqua_settings both be children of Aquarium. I could differentiate by doing $aquarium->children('template=aqua_settings'); or something.

 

So my question is...should I be using the Page Reference field or structuring the pages as children? (Or are both equally fine depending on how I want to go about doing things)

Share this post


Link to post
Share on other sites

Welcome to the Forums @awesomolocity

The simplest setup utilizes the fact that setting up the Page Tree also means setting up ProcessWire's default router. If you do now want to implement "fancy" routing then I recommend using the Page Tree for that and that will also define what needs to be accomplished with page reference fields.

Share this post


Link to post
Share on other sites

Child pages can be good when:

  1. You think it will be helpful for the relationship to be shown in the URL to the pages: /manufacturers/dodge/challenger/
    Although it is also possible to 'fake' a page URL using URL segments.
  2. The child will exclusively belong to that parent (it doesn't belong to multiple categories).

If either of these is not the case then you are better off with Page Reference fields. So in your example, you have fish in an aquarium. If by "fish" you mean "species of fish" then you wouldn't want to have these as child pages of an aquarium, because multiple aquariums might have the same species of fish and you don't want to duplicate the species pages.

 

  • Like 1

Share this post


Link to post
Share on other sites

@Robin S Actually the fish will be unique. Users will be able to name their fish, they'll sorta be unique. (But all from a list of species). But you did just help me visualize what I was thinking about. xD

 

I could do User -> Aquarium -> Fish (with PageReference to Species)

Share this post


Link to post
Share on other sites

I have kind of the same website like you about turtles. https://chrysemys.nl

I have a mix of parent/child pages and page references. Alle depending on the specific needs.

 

If a fish could change owner or change aquarium, I would use page reference. User can change this themselves, otherwise you would need to give them too much permissions.

 

I have the taxonomy for turtles. order -> sub order -> family -> species. This is a parent/child tree as these a vast routes that are always the same for a turtle.

The same goes for the country or origin: region -> country.

 

Page reference can also be bidirectional. This is very usefull!

If you have books on your site you can reference to the fish in that book. In the admin you will see on the fish page all books and on the book page all fish.

If you add a new book and select a few fish, that book is also added to those fish in the admin fish page.

 

That way you can make an amazing flexible website

To be honest it took me a while to figure it all out. I used to have all page references but later changes some part to parent/child. This because it would make it less possible to make mistakes. For example, I added some countries to a turtle but also referenced the wrong region. Therefor that turtle would appear on wrong pages. Using the parent/child for this made it more dummy proof ;)

 

 

  • Like 1

Share this post


Link to post
Share on other sites
On 10/2/2017 at 10:09 PM, webhoes said:

Page reference can also be bidirectional. This is very usefull!

If you have books on your site you can reference to the fish in that book. In the admin you will see on the fish page all books and on the book page all fish.

If you add a new book and select a few fish, that book is also added to those fish in the admin fish page.

Can you please elaborate on this? Besides using this one: https://modules.processwire.com/modules/connect-page-fields/ what else is available? Also, there is this no longer maintained module http://modules.processwire.com/modules/page-references-tab/ ?

Am I misunderstanding something here?

Share this post


Link to post
Share on other sites

I use ConnectPageFields and it works on the latest version.

Let's say you have 50 types of fish on your site.

You add a new book and reference all these fish to that book. If add a new fish and you want to reference it to that same book you would also need to edit that book.

With bidirectional link you reference the book when you add the fish. No need to go to the book afterwards.

With a few fish and books that's would not be a problem, but if you have more of 50 of each, this would make you live easier.

With a bidirectional link both references are visible on both pages in the admin. If you delete one, the other will also be deleted.

 

  • Like 1

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 AndZyk
      Hello,
      when you add a page you can see the page name of the page under the page title field. But when you change the page title afterwards, you have to go to the settings tab to also change the page name.
      We have many clients that change the page title afterwards but forget to change the page name, because they don't look in the settings tab or forget it.
      Is it possible to show the page name on the content tab under the page title?
      I hate to say this, but I like how WordPress handles this better:

      Or should I open an GitHub request?
      Regards, Andreas
    • By Harmen
      I want to add a few pages to an AsmSelect Page field inside a repeater using the following code:
      $trialsPage = wire("pages")->get(28422); // Get the page $trialsPage->of(false); $newTrial = $ordersPage->trial_repeater_orders->getNewItem(); // Add item to repeater foreach ($selectedProducts as $selectedProduct){ $productPage = $pages->get("template=product, reference=$selectedProduct"); $newTrial->trial_selected_products->add($productPage); } $newTrial->save(); $trialsPage->save(); However, when I check the page where the field is located it doesn't have the new values as expected. The selected pages exist, the field is in the right location, made sure that the output formatting is turned off: $page->of(false); But it still doesn't work with a variable. No matter what I try, it doesn't work.
      It only works when I replace $selectedProduct with a hardcoded string. Am I doing something wrong here?
    • By David Karich
      The Page Hit Counter module for ProcessWire implements a simple page view counter in backend. Page views of visitors are automatically tracked on defined templates, with monitoring of multiple page views. This gives you a quick overview of how many visitors have read a news or a blog post, for example, without first having to open complex tools such as Google Analytics. This module quickly provides simple information, e.g. for editors. Or, for example, to sort certain news by most page views. For example for "Trending Topics".

       
      Works with ProCache and AdBlockers. With a lightweight tracking code of only ~320 bytes (gzipped). And no code changes necessary! In addition GDPR compliant, since no personal data or IP addresses are stored. Only session cookies are stored without information. 
      In addition, there are some options, for example filtering IP addresses (for CronJobs) and filtering bots, spiders and crawlers. You can also configure the lifetime of the session cookies. Repeated page views are not counted during this period. It is also possible to exclude certain roles from tracking. For example, logged in editors who work on a page are not counted as page views.

      Sort by hits and access page views (hit value)
      Each trackable template has an additional field called phits. For example, you want to output all news sorted by the number of page views.
      // It is assumed that the template, e.g. with the name "news", has been configured for tracking. $news = $pages->find("template=news, sort=-phits"); To output the page views of a tracked page, use:
      echo $page->phits; Example: Tracking a page hit via API and jQuery
      If you want to track a template that does not represent a full page to automatically inject a tracking script, you can define allowed API templates in the module that you can track. Below is an example of how you can track a click on news tag using jQuery. This will allow you to find out which keywords are clicked the most. For example, you can sort and display a tag cloud by the number of hits. Suppose your keywords have the template "news_tag". The template "news_tag" was also configured in the Page Hit Counter Module as a trackable API template.
      Example PHP output of keywords / tags:
      // Required: the data attribute "data-pid" with the ID of the template to be tracked. echo $pages->find("template=news_tag, sort=-phits")->each("<a href='{url}' class='news_tag' data-pid='{id}'>{title}</a>"); Example Tracking Script with jQuery:
      /** * Required: Data attribute "data-pid" with the ID of the news tag template * Required: Send the POST request to the URL "location.pathname.replace(/\/?$/, '/') + 'phcv1'" * Required: The POST parameter "pid" with the ID of the template */ $(function(){ if($('a.news_tag').length > 0) { $('a.news_tag').each(function(){ var tPID = $(this).data("pid"); if(tPID) { $(this).on("click", function(){ $.post(location.pathname.replace(/\/?$/, '/') + 'phcv1', {pid: tPID}); }); } }); } }); So simply every click on a tag is counted. Including all checks as for automatic tracking. Like Bot Filtering, Session Lifetime, etc.
      _______________________________________________________
      Background: This module is the result of a customer requirement, where the editors are overwhelmed with analytics or no tracking tools were allowed to be used. However, a way had to be found to at least count page views in a simple form for evaluations. Furthermore, by using ProCache, a way had to be found to count views of a page without clearing the cache.
      _______________________________________________________
      Pros
      Automatic Page View Tracking Lightweight tracking code, only ~320 bytes (gzipped) No code or frontend changes necessary Works with ProCache! Even if no PHP is executed on the cached page, the tracking works Works with browser AdBlockers No cache triggers (for example, ProCache) are triggered. The cache remains persistent GDPR compliant, session-based cookie only, no personal information Filtering of IPs and bots possible Exclude certain roles from tracking Ability to reset Page Views Works with all admin themes Counter database is created as write-optimized InnoDB API to track events for templates that are not viewable No dependencies on libraries, pure VanillaJS (Automatic tracking script) Works in all modern browsers Pages are sortable by hits Cons
      Only for ProcessWire version 3.0.80 or higher (Requires wireCount()) Only for PHP version 5.6.x or higher No support for Internet Explorer <= version 9 (Because of XMLHttpRequest()) No historical data, just simple summation (Because of GDPR) Planned Features / ToDos
      API access to hit values Since version 1.2.1 Possibility to sort the pages by hits (Request by @Zeka) Since version 1.2.0 Don't track logged in users with certain roles (Request by @wbmnfktr) Since version 1.1.0 Possibility to reset the counter for certain pages or templates (Request by @wbmnfktr) Since version 1.1.0 Better bot filter Since version 1.1.0 Disable session lifetime, don't store cookies to track every page view (Request by @matjazp) Since version 1.2.1 Option to hide the counter in the page tree (Request by @matjazp) Since version 1.2.1 Option to hide the counter in the page tree on certain templates Since version 1.2.1 API to track events for templates that are not viewable Since version 1.2.2 Changelog
      1.2.3
      Bug-Fix: Tracking script triggers 404 if pages are configured without slash (#3) Reported by @maxf5 Enhancement: Reduction of the tracking script size if it's gzipped (~320 bytes) Enhancement: Documentation improvement Enhancement: Corrected few typos 1.2.2
      New feature: API to track events for templates that are not viewable Enhancement: Documentation improvement 1.2.1
      API access to hit values Use $page->phits Bug-Fix: No tracking on welcomepage (Reported by wbmnfktr; Thx to matjazp) Bug-Fix: Tracking script path on subfolders (Reported by matjazp) Bug-Fix: Tracking on pages with status "hidden" Enhancement: Change database engine to InnoDB for phits field Enhancement: Option to disable session lifetime set session lifetime to 0, no cookies Enhancement: Better installation check Enhancement: AJAX Request asyncron Enhancement: Reduction of the tracking script size by ~20% Enhancement: Option to hide the counter in the page tree You can output the counter with the field name "phits" Enhancement: Option to hide the counter in the page tree on certain templates Enhancement: Option for activate general IP validation Enhancement: Reduction of tracking overhead up to ~30ms Enhancement: Better bot list for detection 1.2.0
      New feature: Sort pages by hits – New field phits Migrate old counter data to new field 1.1.0
      New feature: Exclude tracking of certain roles New feature: Reset Page Views Better bot filter and detection 1.0.0
      Initial release Notes
      By default, the page views are stored as INT in the database. This allows a maximum counter value of 4.2 billion views (4,294,967,295) per page. If you need more, change the type to BIGINT directly in the database. But I recommend to use Google Analytics or similar tools if you have such a large number of users.
      _______________________________________________________
      Download GitHub: ProcessWire Page Hit Counter (Version 1.2.3)
      PW Module Directory: ProcessWire Page Hit Counter (Version 1.2.3)
      Install via ProcessWire (Classname): PageHitCounter
      _______________________________________________________
      Update information
      If you have used version 1.2.1 from the DEV branch, please replace it completely with the new master version.
    • By Robin S
      Pages At Bottom
      Keeps selected pages at the bottom of their siblings.
      A "bottom page" will stay at the bottom even if it is drag-sorted to a different location or another page is drag-sorted below it (after Page List is refreshed the bottom page will still be at the bottom).
      Newly added sibling pages will not appear below a bottom page.
      The module also prevents the API methods $pages->sort() and $pages->insertAfter() from affecting the position of bottom pages.
      Note: the module only works when the sort setting for children on the parent page/template is "Manual drag-n-drop".
      Why?
      Because you want some pages to always be at the bottom of their siblings for one reason or another. And someone requested it. 🙂
      Usage
      Install the Pages At Bottom module.
      Select one or more pages to keep at the bottom of their siblings. If you select more than one bottom page per parent then their sort order in the page list will be the same as the sort order in the module config.

       
      https://github.com/Toutouwai/PagesAtBottom
      https://modules.processwire.com/modules/pages-at-bottom/
    • By louisstephens
      So I have a form, once completed, will create new pages. All in all, this is eazy-peezy for me now. I guess I need a bit of guidance on how to actually structure the rest of my code.  I thought I could just write a function (_func.php) and pass the fields to the function and let it do its' thing. However, I am kinda hitting a road block when I do it this way. 
      I currently am passing first name, last name, city, state (options field), and making pages based on the first/last names. I guess where I run into some issues is I am trying to check to see if the "page" already exists, and if it does, throw out an error:
      In the home template:
      if(isset( $_POST['submit'])) { $firstName =Trim (stripslashes($_POST['firstname'])); $lastName = Trim(stripslashes($_POST['lastname'])); $fullName = $firstName . $lastName; $city = Trim(stripslashes($_POST['city'])); $state = Trim(stripslashes($_POST['state'])); $lowerCaseName = strtolower($fullName); $people = $pages->find("template=person"); foreach ($people as $person) { $checkFirstName = $person->first_name; $checkLastName = $person->last_name; $checkFullName = $checkFirstName . $checkLastName; if ($checkFullName === $lowerCaseName) { echo "<p>" . "This person has already created a page. Please choose a different name." . "</p>"; } else { echo "hey"; processNewPerson(need_to_pass_person_details_to_function); } } // end foreach In _func.php:
      function processNewPerson($list) { $u = new Page(); $u->template = "person"; $u->parent = wire('pages')->get("/people/"); $u->title = ; $u->first_name = ; $u->last_name = ; $u->state = ; $u->city = ; $u->save(); $u->setOutputFormatting(false); } I am a little unsure of how to actually pass all the information to the template, as well as if this is even the best approach to do this. Would it make more sense to do this in a class, or keep it the way it is?
×
×
  • Create New...