Set custom block name programatically / Display block in another block

Permalink
How can I set a custom block name on a page programatically? I have a content block loaded into composer, I need to grab this content from an outside page list object. But I need to reference it somehow. If I can set the custom block name programatically that would be one way. Or if I can somehow get the block ID programatically that would work as well.

ob7dev
 
A3020 replied on at Permalink Reply
A3020
Maybe this could help you?

$a = new Area('Main');
$blocks = $a->getAreaBlocksArray();
foreach ($blocks as $b) {
 if ($b->getBlockTypeID() == 12) {
  //content block
 }
}


I suppose it's also possible to go through the composer fields.
ob7dev replied on at Permalink Reply
ob7dev
I ended up making a new text attribute called 'blockID', then from within the first block I set the attribute to its own block ID. Then in my page list I grab the attribute when looping through the pages and display the block in my pagelist via its getBlockByID.

The only quirk with this is that the blockID attribute gets set on the page that holds the composer block anytime the block is displayed on that page, so when I wanted to do this with a content block, it wouldn't work because its the last content block on the page that gets its ID saved to the attribute. So I had to copy concrete/blocks/content to application/custom_content and only use it in once in my composer block pages. That way the custom blockID attribute gets set to the right block, and then I can pull it into another block by grabbing the blockID attribute off the page and then displaying it in my page list block.
Gondwana replied on at Permalink Reply
Gondwana
Beware that block IDs can change when they're edited (although this may not apply to Content blocks) and when a copy is pasted and changed. Your controller might need to handle the appropriate events to manage this.

Also beware that block IDs aren't necessarily unique on a page.
ob7dev replied on at Permalink Reply
ob7dev
But my override sets a custom text attribute for the page its on whenever its view.php is active on that page. And it sets the attribute to its blockID. So if you do make changes, and it gets a new block ID, it sets the new ID to the attribute... so the correct block should still get pulled from the page list block....
JohntheFish replied on at Permalink Best Answer Reply
JohntheFish
Setting page attributes to track block ID is likely the wrong way to do anything.

You should be able to do this the other way round,
- from a page list, list the pages,
- from a page, list the blocks in an area,
- filter that list to your block type,
- load the block data.
ob7dev replied on at Permalink Reply
ob7dev
JohntheGenius!
Gondwana replied on at Permalink Reply
Gondwana
That might cover the dynamic bID issue (although there could be weirdness while editing, since I don't know if view() is called whenever bID changes).

You'll still need to satisfy yourself that it won't matter if two or more blocks have the same bID on the page. Maybe this won't happen or matter in your use case, but I'd think it through first.
ob7dev replied on at Permalink Reply
ob7dev
You mean two blocks can have the same bID? Wouldn't that cause getBlockByID to have issues? I thought bID's where unique...?
Gondwana replied on at Permalink Reply
Gondwana
bID is not guaranteed unique, although I've only seen duplicates when copying blocks via the clipboard. Here's a way to demonstrate:
https://www.concrete5.org/community/forums/customizing_c5/unique-blo...
Can you just create your own unique identifiers, not relying on bID?
JohntheFish replied on at Permalink Reply
JohntheFish
Only one block has a bID. But that block can be rendered more than once, so bID may not be unique on a page or across many pages. eg, a copy of a block, a block in a stack, a block in a global area, an area rendered more than once (some responsive templates make that 'mistake').

bID only changes when a block's edit dialog is saved. Each save = new bID. There is a table in the database that chains bIDs, so it is possible to track block versions by interrogating it, but rarely the best solution as you usually want block versions relevant to a specific page version

The change in bID is how page versions keep track of block versions. That is how you can have an editor working on an unapproved version of a page while the approved version is still visible to the public. The practice of recording bIDs into an attribute would have broken that.

It may have been neater if there was a separate record of block versions (like there is for page versions or file versions), but that was a decision made long ago and we have to live with it.
ob7dev replied on at Permalink Reply
ob7dev
Side question, how would I go through the composer fields?