Get blocks on current page in correct order in code

Permalink
Hey all,

I have a custom block for the headings. Another block should now create an anchor list for these headings on the page automatically.
That works so far, only the order of the anchor list does not match the order of the blocks on the page.

These are the blocks on my page:

| --------------------------
| Headline 1 (custom block)
| Lorem ipusm ... (normal text block)
|
| Headline 2 (custom block)
| Lorem ipusm ... (normal text block)
|
| Headline 3 (custom block)
| Lorem ipusm ... (normal text block)
|
| Headline 4 (custom block)
| Lorem ipusm ... (normal text block)
| ----------------------------

And this is the result after the anchor list is rendered:

| --------------------------
| Headline 1
| Headline 4
| Headline 3
| Headline 2
| ----------------------------


I try this SQL statement to determine the correct order of the blocks:
SELECT DISTINCT CollectionVersionBlocks.bID, cbDisplayOrder, btmytitle.titleText, arHandle
FROM CollectionVersionBlocks
  JOIN Blocks ON Blocks.bID = CollectionVersionBlocks.bID
  JOIN BlockTypes ON BlockTypes.btID = Blocks.btId
  JOIN btmytitle on btmytitle.bID = CollectionVersionBlocks.bID
WHERE CollectionVersionBlocks.cID = $PAGEID
  AND btHandle = 'my_title'
  AND cvID IN (SELECT MAX(cvID) FROM CollectionVersionBlocks WHERE cID = $PAGEID)
ORDER BY cbDisplayOrder;


The result looks something like this:
bID        cbDisplayOrder        titleText        arHandle
2074       0                     Headline 1       Main
2089       0                     Headline 4       Main : 112
851        1                     Headline 3       Main : 110
2110       1                     Headline 2       Main


The field cbDisplayOrder seems to contain the wrong order of the blocks.
But the page can display the blocks in the correct order.

What is wrong here?

Please, anybody point me the correct way to get blocks of a specific type in the correct order they are displayed on the page

Best,
elpado

elpado
 
Gondwana replied on at Permalink Reply
Gondwana
I was working on something similar, although I took a rather simplistic approach. I used
$blocks = $c->getBlocks();
to get the list of blocks on the page, which I then filtered in php (rather than SQL). I don't recall noticing that the blocks were ever in the wrong order, although I probably didn't test extensively for that.

You could try that in your case and see if the order varies from your approach. If it does, you could dig into c5's code to find the SQL behind getBlocks().
elpado replied on at Permalink Reply
elpado
Using the SQL behind "getBlocks" returns a similar result to my SQL.

I've looked a bit deeper (using a debugger) and finally found my solution in the Areas display function.

Now my code looks like this:

/**
     * this function return all blocks from type my_title on the
     * current page.
     * @return array
     */
    public function getPageTitles()
    {
        // get and check current page
        $currentPage = Page::getCurrentPage();
        if (!is_object($currentPage)) {
            return array();
        }
        $titleBlocks = [];
        $areaList = \Area::getListOnPage($currentPage);
        foreach($areaList as $area) {


This solves my problem with the order of the blocks.

Best,
elpado
Gondwana replied on at Permalink Reply
Gondwana
Impressive! Thanks for posting your solution.
elpado replied on at Permalink Reply
elpado
One for all, all for one :)