Sinmok Posted March 4, 2014 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
Soma Posted March 4, 2014 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
Sinmok Posted March 4, 2014 Author 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};
Soma Posted March 4, 2014 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
Hari KT Posted December 24, 2014 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 ?
SiNNuT Posted December 24, 2014 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?
Hari KT Posted December 24, 2014 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.
Hari KT Posted February 6, 2015 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 .
LostKobrakai Posted February 6, 2015 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
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