Perch Content Custom - Combine Page and Sort by Menu Order

  • Is it possible to display regions combined from multiple pages. Then sort the results based upon the order of the pages in the menu?


    So if the user promotes a page upwards in the menu the results of the combined regions are altered to reflect this.

  • drewm

    Approved the thread.
  • Almost there. Excuse my coding, I'm very much a designer, not a programmer.


    I have a navigation template that looks like:


    Code
    1. <perch:if not-exists="perch_item_first">, </perch:if>'<perch:pages id="pagePath" />'

    This produces the comma separated list of pages I need, however when I save this to a variable and pass the variable into perch_content_custom, the system is escaping the single quotes with backslashes.

    Code
    1. regionPage='\'/section/page-01.php\',\'/section/page-02.php\',\'/section/page-03.php\'

    Is there a way to get rid of the backslashes?

  • I don't know how you are getting that variable back into the page but something in the process is escaping the single quotes in your template. Use double quotes instead? I'm sure a dev can explain more - I am a designer too I'm afraid.

  • It escapes double quotes too unfortunately.

    If I echo the variable it looks fine, the only time I see the backslashes is when I inspect the perch debug to see what has failed.

  • As stated in the docs, you need to use an array. However, you are passing a string.

    PHP
    1. // this is an array
    2. $array = ['/section/page-01.php', '/section/page-02.php', '/section/page-03.php'];
    3. // this is a string
    4. $string = "'/section/page-01.php', '/section/page-02.php', '/section/page-03.php'";


    You don't need to use a template for this. Given that you are not dealing with sub-pages, you can use something like this:



    Now you should be able to use 'page' => $paths, in your perch_content_custom() call. No brackets needed around $paths.

  • Thanks Hussein, I tried your solution and it worked getting the page paths in as an array. There was a little bit more for me to work out as Perch sorts the array alphabetically if they are all passed in together, regardless of their order.


    So, I looked into array manipulation and worked out the following solution for anyone that's interested:


    Using Husseins method to get the list of matching pages into an array:

    Code
    1.  $pages = perch_pages_navigation([
    2. 'skip-template' => true,
    3. 'from-path' => '/care-units/',
    4. 'levels' => 1,
    5. 'hide-extensions' => false,
    6. ]);


    This array includes everything about each page that is available perch_pages_navigation. So the following code sorts the array by 'pageTreePosition' which puts the pages in the order they are sorted in admin.

    Code
    1. array_multisort(array_column($pages, 'pageTreePosition'), SORT_ASC, $pages);

    Note: I believe the above requires PHP7.


    As mentioned Perch will sort the array alphabetically no matter what order it receives it, so we cannot pass it in as it is, we need to loop through each value:

    PHP
    1. <ul>
    2. <?php
    3. foreach ($paths as &$path) {
    4. perch_content_custom(array('Unit Details'), array(
    5. 'page' => $path,
    6. 'template' => 'menu_lis.html',
    7. ));
    8. }
    9. ?>
    10. </ul>

    The only downside to this is that as we are essentially processing each value independently perch:before and perch:after will apply to every item, hence I have to lose the before and after markup and code it into the parent page template instead.


    Tip:

    If at any stage you want to see on your page what is being returned (you may wish to sort on a different value), you can use print_r:

    Code
    1. echo '<p>Array: '; print_r($pages); echo '</p>';