Sinmok Posted March 4, 2014 Share Posted March 4, 2014 Hello all, Little stuck on how to override what a field outputs when being called within a template file. Take the following sample code inside a template: <h1> <?=$page->title?> </h1> <div> <?=$page->another_field?> </div> What I'm trying to do is analyse and potentially modifying the output of this field from within a template, using a module WITHOUT saving the page. This is currently the code that I'm trying to run public function init() { // add a hook after each page is rendered and modify the output $this->addHookBefore('Page::render', $this, 'exec'); } public function exec($event) { //Get the rendered page $page = &$event->object; if($page->template == 'admin') { return; } //As a test, try and modify the title field, but in the future I'll need to be able to modify any fields $page->set("title","A test title!"); } Unfortunately, this doesn't work. - The page still renders the original title within the template! Ideally - my long term goal is to know: What the field type of the called/rendered field is The current value of this field Any guidance is appreciated! 1 Link to comment Share on other sites More sharing options...
Soma Posted March 4, 2014 Share Posted March 4, 2014 Works fine $this->addHookBefore('Page::render', $this, 'renderHook'); public function renderHook($event) { $page = $event->object; if($page->template == 'admin') return; $page->title = "ohhhhhhh"; } Now the rendered page has always title ohhhhhhh. But this does not change the title for page in navigation or other places. 1 Link to comment Share on other sites More sharing options...
Sinmok Posted March 4, 2014 Author Share Posted March 4, 2014 I should have been more specific. I don't know what the field is going to be. I need to iterate over the pages fields and then make a decision based on that. For example: $page = $event->object; if($page->template == 'admin') { return; } $fields = $page->fields; foreach($fields as $field){ $this->setup($page,$field); } However, within setup I try protected function setup($page, $field){ if($conditional_logic){ $page->{$field->name} = "Some other value"; } } But I get the error Exception: Page '/test/' is not currently viewable. (in /var/www/modules/wire/modules/PageRender.module line 251) Even though I can echo out the contents of $page->{$field->name}; Link to comment Share on other sites More sharing options...
Soma Posted March 4, 2014 Share Posted March 4, 2014 Hello all, Ideally - my long term goal is to know: What the field type of the called/rendered field is The current value of this field Any guidance is appreciated! If on page render, there's no field render. Just a page and it's fields. To get fields on a page there's several methods. Maybe the most natural and just general would be foreach($page->fields as $f) { echo "Type:$f->type Name: $f->name Label: $f->label<br>"; } $page->template->fields, $page->get("fields") etc A more deep hook into fields would be to hook formatValue(page, field, value) of Fieldtype. It will replace every title fields rendered on page also from other pages. $this->addHookAfter('Fieldtype::formatValue', $this, 'hookFields'); public function hookFields($event) { $page = $event->arguments("page"); $field = $event->arguments("field"); $value = $event->arguments("value"); // not sure this is needed here, and won't prevent from exec in admin. You better set module config to "autoload" => "template!=admin" if($page->template == "admin") return; if($field->name == "title"){ $event->return = "ohhhhhhh"; } } You could also just hook into specified field type like page title field $this->addHookAfter('FieldtypePageTitle::formatValue', $this, 'hookTitle'); You can also create your own property as per HelloWorld.module. But not overwrite already existing fields. $this->addHookProperty('Page::hello_world', $this, 'example4'); I'm not sure what you're trying to archive and if there isn't another approach, just mention ways... I should have been more specific. I don't know what the field is going to be. I need to iterate over the pages fields and then make a decision based on that. For example: You asked how to modify the page title. I showed you how and it's working. Fieldtype::formatValue will get called only when output formatting is on. And it's called when using TextFormatter modules on a field. 1 Link to comment Share on other sites More sharing options...
Hari KT Posted December 24, 2014 Share Posted December 24, 2014 Hi @Soma, if I am adding a hook on a field and returning some html the values are escaped. Is there a way to turn off the escape functionality ? Link to comment Share on other sites More sharing options...
SiNNuT Posted December 24, 2014 Share Posted December 24, 2014 There is a htmlentities Textformatter active on the field you're working with? Eiter disable the formatter or turn off output formatting in your code? Link to comment Share on other sites More sharing options...
Hari KT Posted December 24, 2014 Share Posted December 24, 2014 It was one of my dump mistake @SniNNuT . I missed to write `<script>` tags . Thank you for reaching to help me. Link to comment Share on other sites More sharing options...
Hari KT Posted February 6, 2015 Share Posted February 6, 2015 Hi, I was trying to show the system template on Selectorfield as asked over : https://processwire.com/talk/topic/9026-show-system-templates-on-selectorfield/ Is there a way to make a hook like this work? public function init() { $this->addHookBefore('InputfieldSelector::render', $this, 'selectorField'); } public function selectorField($event) { $inputSelector = $event->object; if ($event->object->name == 'field1') { $inputSelector->allowSystemTemplates = true; $event->return = $inputSelector; return $event->return; } } Though I did this, it seems not working properly . Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 6, 2015 Share Posted February 6, 2015 There shouldn't be a need to change $event->return, as you're hooking before the function not after it. Also you don't want to replace the returned markup of InputfieldSelector::render. The option is correctly set, but it's not working for me, too. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now