Save page attribute in custom block

Permalink
Hello,

To make it more easy for my client to edit a specific page attribute that is shown on every page, I created a new block type that outputs the value of that page attribute, editable via the edit mode of that block. The block is added in a global area that exists on every page, so the same instance of the block is active on every page, but always showing the custom attribute value of the current page.

I'm experiencing a strange issue though with editing the block. When I go into edit mode of a page and first edit and then save the block, changes are not applied. When I edit the block for the second time changes are applied correctly.

The save function in the block controller is like this:

function save($data) {
    global $c;
    $c->setAttribute('my_attribute', $data['my_attribute']);
}


Anyone any idea why only every second (and next) time the block is edited the new attribute value is actually saved?

Many thanks!

Guido
View Replies:
obaudains replied on at Permalink Reply
Hello,

Did you manage to find a solution for this..?
Guido replied on at Permalink Reply
Guido
Unfortunately I didn't. Had to tell my client to edit the attribute via Page Properties.

Do you have the exact same issue?

Not sure if I already tried this, but you could check the id of the collection object, or try to get the collection by using Page::getCurrentPage() instead of using the global $c.
jordanlev replied on at Permalink Reply
jordanlev
Page properties don't get refreshed until the page is reloaded (and editing a block does not reload the page). I've run into this problem before and created some code you can use to make the page automatically reload after a property is changed, but it only works with the "edit properties" dialog (not a block like you have):
https://github.com/jordanlev/c5_reload_on_attribute_change...
obaudains replied on at Permalink Reply
Thanks for the response,

Im having trouble actually saving the page attribute through the block though.

On my edit.php I pull through the attribute into the form field:

$car = Page::getCurrentPage();
$value = $car->getAttribute('car_colour'); ?>
<?php echo $form->label('content', 'Car Colour');?>
<?php echo $form->text('content', $value, array('style' => 'width: 320px'));?>


This pulls it through fine. But when I change the value when editing and click save, my save function in the controller isnt saving it back to the attribute in th db.

function save($data) {
      global $c;
      $c->setAttribute('car_colour', $data['car_colour']);
   }


Any guidance would be appreciated.

(In short im trying to allow the user to edit the existing page attributes through a page block.)

Thanks
jordanlev replied on at Permalink Reply
jordanlev
I don't know -- I would think calling $c->setAttribute() would work... can't say I know why it isn't. Sorry :(
jegra replied on at Permalink Reply
I know this is an old thread, but stumbled on it looking for something related. I've had success just passing NULL for the value -- the attribute value supplied in the form will get automagically picked up and stored. So:
function save($data) {
      global $c;
      $c->setAttribute('car_colour', NULL);
   }


NOTE: This approach requires setting up the form fields in the block edit view using a CollectionAttributeKey (it preps the fields such that they can be properly read back via the 'NULL' value passing mentioned above). A function I used for this in the edit page:
function renderAttribute($handle, $label, $fh) {
   global $c;
   $ak = CollectionAttributeKey::getByHandle($handle);
   $caValue = $c->getAttributeValueObject($ak);
   echo $fh->label($handle, $label . ': ');
   echo $ak->render('form', $caValue);
}

...where $handle is the attribute handle, $label is the label you'd like to display in the form for the attribute, and $fh is a form helper, via:
$fh = Loader::helper('form');


This works well for everything other than 'select' type attributes, which require a little more work.

In regards to always getting the attribute to update, the trick seems to be to call the getVersionToModify() method on the collection when entering edit mode. So, in the controller, you'd need an edit method similar to:
public function edit() {   
   global $c;
   $c = $c->getVersionToModify();   
}
chameleondesign replied on at Permalink Reply
chameleondesign
I have this problem too - I don't think it is to do with refreshing the page. It is just not setting the attribute the first time you edit the block form.
A3020 replied on at Permalink Reply
A3020
A while ago I built the 'Attribute Block' addon to edit page attributes easily via custom blocks, it's worth checking it out: concrete5.org/marketplace/addons/attribute-block/