Loading page list entries via AJAX

Permalink
Hi All,

I'm trying to put a block together that will load and display a list of blog posts, with a button to load more posts via AJAX. Funnily enough, just using a modified version of the Page List core block gets me 70% of the way there, but I can't quite figure out how to call additional results and have them be properly formatted.

I'm using v5.5 as the composer seems to handle the creation of blog pages nicely.

My current theory is this, I could use the pagination function within that block to call the next set of posts($paginator->getNext), but I just can't work out how to use this to just pull out the data that I need and not trigger a page refresh.

I'm sure the answer to this isn't that difficult, but I'm chasing my tail at this stage. Can anyone point me in the right direction?

Cheers!

 
jordanlev replied on at Permalink Reply
jordanlev
Unfortunately this is not a totally straightforward thing to do. I don't think it's possible without some custom coding, and it will probably be easier to create your own block (or a single_page) for this purpose as opposed to modifying the built-in Page List block.
First you need to create the proper javascript on your front-end that handles the ajax loading. Then you need a "tools" file (which is C5's term for ajax responders -- they are files that you can call with a certain URL and they can return any data or chunks of HTML you want, without putting it inside the theme wrapper).

If you're a programmer, how comfortable are you with PHP and creating custom functionality in Concrete5? (This will let people here know how specific to get on any suggestions for building this out). If you're not a programmer at all, I unfortunately don't think it will be possible to do this yourself. You might try this addon in the marketplace, although I'm not sure if it fits exactly with that you're trying to do:
http://www.concrete5.org/marketplace/addons/ajax-page-tools/...
ZeroGodForce replied on at Permalink Reply
Hi Jordan, thanks for your response.

I expected that I would need to write some custom functions along the the way. I am a programmer, but as you can probably tell, I don't extend concrete all that often.

Before I got on the pagination trail, I was going to write a function to just call the posts manually from the database. However, I couldn't quite track down all of the tables and columns I would need to call. I reasoned that if I could use the cID to get the aID I could just write out the blocks inside the Main area (where the blog content block is).

However, I have observed that the blog index template of the page list achieves similar results by passing the page object for each page, and simply calling the area (as would normally happen in the template for a page). So its almost like the page list block literally "renders" each page its calling inside it. Have I understood that correctly? And if so, could I achieve a similar result if I write a custom function to query the database in the same way?

Cheers
jordanlev replied on at Permalink Best Answer Reply
jordanlev
Okay, if you're a programmer then this shouldn't be too hard.

The thing about the blog index template is that it's doing something the normal page list template doesn't: it's actually showing content excerpts from the page itself (whereas the normal page list template just shows titles and optionally the "description" attribute). This is kind of a separate issue from the ajax loading thing, so I would set that aside for the time being and then go back and implement that later after you've figured out the ajax stuff (if you even want that functionality, that is). If/when you do that, you might want to look at this custom template for the page list block I made:
https://github.com/jordanlev/c5_clean_block_templates/blob/master/pa...
...and also my free "Page List Teasers" addon, which does this in an even more robust fashion:http://www.concrete5.org/marketplace/addons/page-list-teasers... .

Anyway, to do the ajax stuff, what you'll want to do is create your tools file (put a file in your site's top-level "tools" directory), and in that tools file check the $_GET parameters for something that tells you which pages to list (I presume a parent page cID might be appropriate, or maybe a page type / collection type id -- depends on what it is you're listing), and then also some number indicating which page of the pagination you want. Then retrieve the appropriate page data using the "Page List" data model (which is *not* the page list block -- instead it's the lower-level API that lets you query pages -- it's what the page list block uses in its own code).

For example, you might create a file called "page_list_more.php" in your site's top-level "tools" directory, which some code like this:
<?php defined('C5_EXECUTE') or die("Access Denied.");
//Get your arguments from the querystring
// (You will want to make this more robust -- check for empty / non-numbers, etc.)
$page = intval($_GET['page_num']);
$page = empty($page) ? 1 : $page;
$parentCID = intval($_GET['parent_page_id']);
$collectionTypeHandle = $_GET['page_type'];
//Retrieve pages
Loader::model('page_list');
$pl = new PageList();
$pl->sortByDisplayOrder();
$pl->setItemsPerPage(10); //<--or whatever
if (!empty($collectionTypeHandle) {
    $pl->filterByCollectionTypeHandle($collectionTypeHandle);
}


Now, on the page itself, you'll need to figure out how to do the ajax calls (this is not difficult, just the same way you'd do it anywhere else, using jQuery). The one tricky part is getting the url for that tools file you made, which you can do like so:
<?php
$tools_url = Loader::helper('concrete/urls')->getToolsURL('page_list_more');
?>

Note that we're passing "page_list_more" as the tools name, because we named the tools file "page_list_more.php" -- if you use a different file name, pass a different name into this function -- but withOUT the ".php" extension.

Best of luck!

-Jordan
ZeroGodForce replied on at Permalink Reply
That makes way more sense than my previous approach. Thanks for taking the time to explain this Jordan, I really appreciate it!
ZeroGodForce replied on at Permalink Reply
Jordan, you're a legend! After a bit of tinkering and some help from your very useful teaser template, I've got what I needed working.

You have my thanks! :)
jordanlev replied on at Permalink Reply
jordanlev
You're welcome -- glad you got it figured out.
Tony replied on at Permalink Reply
Tony
this block will ajaxify page list block links in about a minute for you:
http://concrete5packages.com/toolbox/rapid-paging...

you can even target it to work just with the pagination links if you want.
ZeroGodForce replied on at Permalink Reply
Thanks Tony, I'll take a look!