Forum

Thread tagged as: Question, Problem

Search and multiple item regions

Hi,

I am using multiple item regions set up in a list/detail arrangement with perch_content_custom, but I am not using a slug to get the name of the content, but instead using perch_item_index to allow the list navigation to get the correct content as the slug route was not applicable....there was a good reason, but for the life of me I cannot remember why now !

The issue I am having is returning search results with the correct URL.

I have noticed in the documentation that I need to adjust the Region Options, with an arrangement such as:

/page1.php?page={slug}

However, as stated, this is not applicable to me as the URL is generated and retrieved as:

<a href="<perch:content id="_page" />?page=<perch:content id="perch_item_index" />">

I tried using:

/page1.php?page={perch_item_index}

but, managed to get things working by using:

/page1.php?page={_id}

However, I have a series of these list / detail pages and of course whilst _id matches perch_item_index for the first set of entries, the url generates a new set of links for the new page and _id no longer matches, i.e I have:

page1.php?page=1
page1.php?page=2.....etc etc

page2.php?page=1
page3.php?page=2.....etc etc

So, my question after all of the above is, can I somehow 'inject' the perch_item_index which is unique to each page, i.e. runs from 1 - however many entries, into the Region Options as some form of dynamic field.

I tried capturing the perch_item_index in a slug, but again, this just gives me the url safe version of the title, which is what I would expect.

Can I do something like:

$var = perch_item_index;

and then 

/page1.php?page={$var}

I will have another go at implementing something like this, but I'm just not sure if this is something that can be achieved.

Any ideas, greatly welcome !

Thanks, Andy

Andrew Kennedy

Andrew Kennedy 0 points

  • 7 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

perch_item_index is a count of items as they are output by the templating engine. It's not suitable or practical to use it for filtering.

I think you need to start by sorting out the root problem with the list/detail page configuration.

Ok, I 've just put everything back to using a slug etc and I have two problems.

The first one is that if I go to the page initially, there is no value for 's', so I do not see the detail page. I presume I can somehow tell perch that I need to retrieve the value of the first story to display initially ?

The second issue is to do with pagination and infinite scroll. I have found a previous post and I have tried to implement your suggested solution of how to implement pagination in this situation, but I cannot get it working.

My list and details are all on one page and my current code within the 'detail' div is:

perch_content_create('Articles', array(
    'template'  => 'article-content.html',
    'multiple'  => true,
    'edit-mode' => 'listdetail',
));

perch_content_custom('Articles', array(
    'paginate' => true,         
    'template' => 'article-content.html',
    'filter'   => 'slug',
    'value' => perch_get('s'),
    'match' => 'eq',
    'sort'=>'_id',
    'sort-type' => 'numeric',
    'count' => 1,
));


// current item - not for display
$opts = array(
'filter'=>'slug',
'match'=>'eq',
'value' => perch_get('s'),
'count'=>1,
'skip-template'=>true
);

$current_item = perch_content_custom('Articles', $opts);
$id = $current_item[0]['_id'];


// previous item - for display
$opts = array(
'filter'=>'_id',
'match'=>'lt',
'value'=>$id,
'count'=>1,
'sort'=>'_id',
'sort-type' => 'numeric',
'template'=>'article-content.html'
);
perch_content_custom('Articles', $opts);


// next item - for display
$opts = array(
'filter'=>'_id',
'match'=>'gt',
'value'=>$id,
'count'=>1,
'template'=>'article-content.html'
);
perch_content_custom('Articles', $opts); 

Bizarrely, with all the added code (for pagination) the first article appears even if the url is just /page1.php.

Currently, what happens is that if I am at the first article, it seems to load in the first two articles into the details area and does not use pagination and shows pagination, 1 of 1. Clicking the second article seems to load in that article and another two etc etc. Of which it always seems to be the first article and another.

Sorry, but I am totally confused with what is going on here.

Pagination looks like:

<perch:after>
  <perch:if exists="paging">
    <div class="paging-holder">
        <div class="paging">
          <p>Page <perch:content id="current_page" type="hidden" /> of <perch:content id="number_of_pages" type="hidden" />
          <perch:if exists="not_first_page">
            <a href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" />">Previous</a>
          </perch:if>
          <perch:if exists="not_last_page">
            <a class="cms_next" href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" />">Next</a>
          </perch:if></p>
        </div>
    </div>  
  </perch:if>
</perch:after>

I will keep at it, as it seems that even before 'pagination' the calls are not returning the correct results.

Drew McLellan

Drew McLellan 2638 points
Perch Support

What should happen when there's no slug? You just need to test for the slug, and then do whatever is needed in that case:

if (perch_get('s')) {
    ... there is a slug, show the detail ...
} else {
    ... no slug, show the default whatever ...
}

Hi Drew,

Ok, so that would resolve the issue of not returning the initial entry, but I still do not understand how to get the pagination working.

My above code actually does return the first entry, with the pagination stuff added, so I think I must be getting confused with where the elements 'current item - not for display', 'previous item - not for display' and 'next item - not for display' are to be used, as I had presumed these were all separate to the if (perch_get('s')) { statement and purely support the pagination.

Hmmm, still not getting very far.

Teh pagination element just isn't working and I am getting multiple items rendered to the screen.

My detail page looks like this:

if (perch_get('s')) {
        // Detail mode
        perch_content_custom('Articles', array(
         paginate' => true,
         'template' => 'article-content.html',
         'filter'   => 'slug',
         'value' => perch_get('s'),
         'match' => 'eq',
         'sort'=>'_id',
         'sort-type' => 'numeric',
         'count' => 1,
        ));

} else {
    // List mode
    perch_content_custom('Articles', array(
        'paginate' => true,         
        'template' => 'article-content.html',
        'sort'=>'_id',
        'sort-type' => 'numeric',
            'count' => 1,
    )); 

}   

/* PAGINATION OUTSIDE THIS CALL */

// current item - not for display
$opts = array(
'filter'   => 'slug',
'value' => perch_get('s'),
'match' => 'eq',
'sort'=>'_id',
'sort-type' => 'numeric',
'count' => 1,
'skip-template'=>true
);

$current_item = perch_content_custom('Articles', $opts);
$id = $current_item[0]['_id'];


// previous item - for display
$opts = array(
'filter'=>'_id',
'match'=>'lt',
'value'=>$id,
'skip-template'=>true,
'count'=>1
);
perch_content_custom('Articles', $opts);


// next item - for display
$opts = array(
'filter'=>'_id',
'match'=>'gt',
'value'=>$id,
'skip-template'=>true,
'count'=>1
);
perch_content_custom('Articles', $opts); 

I am using 'skip-template'=>true for all elements, as the pagination code is within the item.html page.

The above code displays the 1 of X if I am visiting the page where the lug is empty and is returning 1 of 1, if the slug has a value.

Any ideas ?

the pagination code link I am suing is still

<a href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" for="articleTitle" />">Next</a>

which just returns the current slug. It seems I need to plus or minus 1 somehow from the value so the slug can get updated.

Drew McLellan

Drew McLellan 2638 points
Perch Support

I guess I don't follow what you're trying to do with the pagination. Can you take a step back and explain the over all goal?

Hi Drew,

Basically all I want to do is have a list/detail page that has pagination.

So, if we take it all back to initial basics. My detail page now has the usual.

if (perch_get('s')) {
    ... there is a slug, show the detail ...
} else {
    ... no slug, show the default whatever ...
}

However, what I want to know is, how can I generate the next and previous links, given I am passing a slug value now, not a perch_item_index as I was before.

Ok, been working away at this and I now have the pagination working for if the user selects the pare (page1.php), or selects an article within the page (page1.php?s=my-article), using the following code:

if (perch_get('s')) {
    // Detail mode
    perch_content_custom('Articles', array(
        /*'paginate' => true,*/  // Turn off pagination         
        'template' => 'article-content.html',
        'filter'   => 'slug',
        'value' => perch_get('s'),
        'match' => 'eq',
        'sort'=>'_id',
        'sort-type' => 'numeric',
        'count' => 1,
    ));

    // current item - not displayed
    $opts = array(
        'filter'=>'slug',
        'match'=>'eq',
        'value'=>$_GET['s'],
        'count'=>1,
        'skip-template'=>true
    );

    $current_item = perch_content_custom('Articles', $opts);
    $id = $current_item[0]['_id'];

    // previous item - for display
    $opts = array(
        'filter'=>'_id',
        'match'=>'lt',
        'value'=>$id,
        'count'=>1,
        'sort'=>'_id',
        'sort-order'=>'DESC',
        'template'=>'../pagination/paging-prev.html'
    );

       perch_content_custom('Articles', $opts);

    // next item - for display
    $opts = array(
        'filter'=>'_id',
        'match'=>'gt',
        'value'=>$id,
        'count'=>1,
        'template'=>'../pagination/paging-next.html'
    );

    perch_content_custom('Articles', $opts); 

} else {
    // List mode
    perch_content_custom('Articles', array(
        'paginate' => true,         
        'template' => 'article-content.html',
        'sort'=>'_id',
        'sort-type' => 'numeric',
        'count' => 1,
    )); 
}

So, in order to get this to work, I have had to create two new pagination templates to hold the links in for next and previous, eg:

<a class="cms_next" href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" for="articleTitle" />">Next</a>

I also still have the pagination left in on the item.html page, so that this allows for pagination when the slug is empty:

<perch:after>
  <perch:if exists="paging">
    <div class="paging-holder">
        <div class="paging">
          <perch:if exists="not_first_page">
            <a href="<perch:content id="prev_url" type="hidden" encode="false" />">Previous</a>
          </perch:if>
          <perch:if exists="not_last_page">
            <a class="cms_next" href="<perch:content id="next_url" type="hidden" encode="false" />">Next</a>
          </perch:if></p>
        </div>
    </div>  
  </perch:if>
</perch:after>

Everything is good, until in my pagination/paging-next.html template, I add in the 'class="cms_next"' and the required div classes to get the infinite scroll working.

As soon as I do this, I can return the next item, but then after this, it stops loading any more, with the 'Congratulations, you've reached...', yet as soon as I remove that class from that template, I get the 'next' and 'previous' links and these click through perfectly.

Why does it only auto load the next item, then stop ?

Also, the above solution seems like overkill, with what is intrinsically three templates to control pagination, the item.html page that brings back the content, the prev and next templates for if a slug has been used. Is there a slicker way of doing this ?

Still, I don't mind, so long as I can get the infinite scroll to stop ending after loading only a single item when useing the slug.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Are you paginating the list view, or is the goal to have previous and next links in the detail view?

Hi Drew,

Sorry been away from my desk. I require next/previous links in both detail and list view.

However, I think we may be on cross purposes on the naming, so here is a quick rundown of my set-up.

I have a single page, with two-columns. The first column just returns a list of all the items using:

perch_content_custom('Articles', array(
    'template' => 'article-listing.html',
    'sort'=>'_id',
    'sort-type' => 'numeric',
    'sort-order'=>'ASC',                        
));

My main column uses the previously attached code where I am running:

if (perch_get('s')) {
    // Detail mode
    perch_content_custom('Articles', array(
        /*'paginate' => true,*/  // Turn off pagination         
        'template' => 'article-content.html',
        'filter'   => 'slug',
        'value' => perch_get('s'),
        'match' => 'eq',
        'sort'=>'_id',
        'sort-type' => 'numeric',
        'count' => 1,
    ));

    // current item - not displayed
    $opts = array(
        'filter'=>'slug',
        'match'=>'eq',
        'value'=>$_GET['s'],
        'count'=>1,
        'skip-template'=>true
    );

    $current_item = perch_content_custom('Articles', $opts);
    $id = $current_item[0]['_id'];

    // previous item - for display
    $opts = array(
        'filter'=>'_id',
        'match'=>'lt',
        'value'=>$id,
        'count'=>1,
        'sort'=>'_id',
        'sort-order'=>'DESC',
        'template'=>'../pagination/paging-prev.html'
    );

       perch_content_custom('Articles', $opts);

    // next item - for display
    $opts = array(
        'filter'=>'_id',
        'match'=>'gt',
        'value'=>$id,
        'count'=>1,
        'template'=>'../pagination/paging-next.html'
    );

    perch_content_custom('Articles', $opts); 

} else {
    // List mode
    perch_content_custom('Articles', array(
        'paginate' => true,         
        'template' => 'article-content.html',
        'sort'=>'_id',
        'sort-type' => 'numeric',
        'count' => 1,
    )); 
}

My understanding is that the if (perch_get('s) function is looking to populate this main column area and is just basically a switch to say, if the incoming url has a slug then do this (detail view), else create a list (list view). In my solution, I do not want another list, so I am getting it to return the first item.

So with that in mind, I need pagination for the detail view (slug not empty) and the list view (slug empty).

Does this make sense, or are you referring to the list view as my first column content, i.e. just a simple listing all the articles ?

What I do not understand (well, I can kind of see why it wouldn't work) is that normally, for pagination I can just include the whole <perch:after .....<perch:if exists="paging"....

but because I am passing a slug, I need to use some other way of working out where the item is, relative to the items within the multiple item region. That is why I went down the whole perch_item_index route, as that gave me a number and format that could be paginated, but of course that lead onto my original issue with the search function, which has been resolved now I have gone down the slug route.

Thanks for being patient and trying to sort this out for me. It's important to a job and I really want to understand how I can do this, so I can further my perch knowledge.

Just wondering. Is this due to the fact that if you use a slug, all the pagination links will be of the form:

page1.php?s=mylink

and is the infinite scroll looking for the format:

page1.php?page=mylink

All seems odd, as it will scroll to next page, but then say it has reached the end.

Also, having clicked on a 'slug' link, it still displays the 'previous' link (not hidden).

Just tried changing everything from s to page, but the site just fails to load content.

Strange behaviour. Gutted, as this is the last thing before I can display it to the client and go live.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Is there any way you can show me an example of what you're trying to achieve?

Hi Drew,

Is there an email address I can send a password over to you ?

Thanks

Hi Drew,

Thanks for taking a look at this.

If you visit: https://pelican.kennedydigitalltd.com

and use:

Details Removed

this will get you into the site. To see the content, you need to login to the site, so please use:

Details Removed

Then click the link to view content.

When you initially see the content (spring-2014.php), there is no value to the slug. If you scroll the right-hand-side pane, you will see that the infinite scroll works and all subsequent items are loaded.

Now, if you click an item in the left column, the slug is populated with that items title and the right-hand-side retrieves the content. Now if you scroll the right-hand pane, you will see that the next item loads in, but then it stops after that, claiming to be at the final item.

Also, I think because of this two template set-up for the next and previous links for if the url has a slug, you will see a previous link still being shown.

The odd thing is, that if I remove class="cms_next" from the next link in the paging-next.html template (only used if a slug is there), then the previous and next links work perfectly, cycling through all the items.

Very odd.....

Drew McLellan

Drew McLellan 2638 points
Perch Support

So is the issue purely with the infinite scroll javascript? i.e. if you remove the JS the links work?

Yes, if I remove the Javascript, the 'pure' links work.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Ok, so that suggests it's not a Perch issue, doesn't it? Or am I missing something important?

That's one way of looking at it.......

If I am using a perch feather to provide some functionality, then I would presume the issue is within that add-on. So in your case above, I could say that with the Javascript in-place everything works well, but as soon as I add in pagination with a slug in the URL, the solution fails, therefore that would point me to think that the Perch element is in-correct.

I realise that most of the code has been lifted from the Paul Irish solution, but surely you can see it from my perspective ?

Drew McLellan

Drew McLellan 2638 points
Perch Support

I'm just trying to understand what you're asking my help with.

Thanks Drew, I do understand you are only trying to help.

I am just wondering how it doesn't work, if I seem to have everything correct for utilisation of a slug.

<div class="paging-holder">
    <div class="paging">
        <a class="cms_next" href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" for="articleTitle" />">Next</a>
    </div>
</div>

Maybe somehow when the javascript is passed, the above get's messed up. It's odd that it will load in the next item, so it obvioulsy works, but then stops. Is it potentially something to do with a count being stopped. Yet, without Javascript, the code works fine.

Hmmm, I need to get the little grey matter on this one.

Apologies if I sounded off, I am not very well today and shouldn't be at this computer.