szabesz Posted March 25, 2016 Share Posted March 25, 2016 (edited) I am still trying to figure out if there is a way to access the wire object directly "from anywhere", but we can pass its reference to the function to make it work: function addClass($element, $class, $api_vars) { $classes = $api_vars->wire('classes'); $classes[$element][] = $class; $api_vars->wire('classes', $classes); } so in a template: addClass('tm-main', 'tm-blog', $this->wire); Just a sidenote: I do not think $api_vars->wire('classes', $classes); is needed since $classes contains a reference to the object and by doing $classes[$element][] = $class; we actually change the object so no need to store $classes once more. Edit: I have just tested it, and we do need the above, sorry! Edited March 25, 2016 by szabesz 1 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 @bernhard: Seems to work. Can you please test it? function addClass($element, $class) { $classes = wire('wire')->classes; $classes[$element][] = $class; wire('wire')->wire('classes', $classes); } 1 Link to comment Share on other sites More sharing options...
bernhard Posted March 25, 2016 Share Posted March 25, 2016 got it! as simple as that: function addClass($element, $class) { $pw = wire(); // current pw instance $classes = wire('classes'); $classes[$element][] = $class; $pw->wire('classes', $classes); } in the other files: // _init.php // set classes for parent container addClass('tm-main', 'tm-section'); // blog.php addClass('tm-main', 'tm-blog'); // _main.php <section id="tm-main" class="<?= getClasses('tm-main') ?>"> <?= $content ?> </section> see apigen docs: http://kongondo.github.io/ProcessWireAPIGen/devns/source-class-ProcessWire.Wire.html#1027-1037 thank you szabez! also thank you horst for jumping in 2 Link to comment Share on other sites More sharing options...
tpr Posted March 25, 2016 Share Posted March 25, 2016 As an alternate solution, you can create a Settings page just for the purpose to store global vars. Especially useful if you deal with multiple languages. I usually add a multilang text area and apply multivalue textformatter (see my sig). Set its access to admin only to avoid others modifying it. In most cases addig it to the Home page is enough. 4 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 As an alternate solution, you can create a Settings page just for the purpose to store global vars. Especially useful if you deal with multiple languages. I usually add a multilang text area and apply multivalue textformatter (see my sig). Set its access to admin only to avoid others modifying it. In most cases addig it to the Home page is enough. When the administrator should be able to change settings, your solution works fine, however, adding our own standard classes to HTML elements is a different problem I think. bernhard wants to create a collection of HTML classes which can be easily applied to an element, and normally we do not want the administrator to change these values. Building these collections the beginning of the template file is good idea. 2 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 function addClass($element, $class) { $pw = wire(); // current pw instance $classes = wire('classes'); $classes[$element][] = $class; $pw->wire('classes', $classes); } To simplify it a biny bit: function addClass($element, $class) { $classes = wire('classes'); $classes[$element][] = $class; wire()->wire('classes', $classes); } Anyway, thanks a lot bernhard! When reading LostKobrakai's comment, I was also wondering how we can we use it any context, but I did not spend the time to figure it out on my own Link to comment Share on other sites More sharing options...
tpr Posted March 25, 2016 Share Posted March 25, 2016 Thanks szabesz, I think I should have more understanding of bernhard's usecase. Fortunately PW is flexible enough to handle such scenarios. 2 Link to comment Share on other sites More sharing options...
Soma Posted March 29, 2016 Share Posted March 29, 2016 Something using WireArray and WireData. You could use it like this, and all WireArray method would be usable like find(selector) , filter(), remove(), sort() etc. Somewhere in an autoload module or in /site/init.php <?php class MySiteConfig extends WireArray{ public function addItem($key, $value){ $item = new WireData(); $item->name = $key; $item->value = $value; $this->add($item); return $this; } public function render($key){ $str = ""; foreach($this->find("name=$key") as $d) $str .= " " . $d->value; $str = trim($str); return $str; } } // create a new "global" $siteConfig template variable $myConfig = new MySiteConfig(); $this->wire("siteConfig", $myConfig); $siteConfig would then be available everywhere. The addItem() would allow to add items to the WireArray with name -> value. In basic-page.php Template file: $siteConfig->addItem("classes", "main")->addItem("classes", "myClassX"); $siteConfig->addItem("classes", "myClassY"); $content .= wireRenderFile("blog"); then in the blog.php partial $siteConfig->addItem("classes", "blog"); ?><div class='blog <?php echo $siteConfig->render("classes"); ?>'> <h1>Blog Test</h1> <?php // example of using WireArray's implode() echo $siteConfig->implode(" ", "value"); // example of filtering items $vars = $siteConfig->find("name=classes, value^=my"); if($vars->count) { foreach($vars as $v) echo " $v->value"; } ?> </div> This would be easy to extend with further helper methods etc. Also in your template site/init.php or templates/_init.php you could create various template variables That is just a fictive example, not sure how practical this is for handling a use case mentioned in this thread. 7 Link to comment Share on other sites More sharing options...
szabesz Posted March 29, 2016 Share Posted March 29, 2016 @Soma: Thank you for the detailed tip! I think it is more versatile than what we have came up with so far. As far as I can tell, your render method example covers the particular use case we dealt with in this thread and surely with even more helper methods added to the class all sorts of utilities can be implemented. 1 Link to comment Share on other sites More sharing options...
Macrura Posted June 11, 2016 Author Share Posted June 11, 2016 I read through most of the replies here, and tried to analyze what the best way to improve upon the original post/request. So far this is the version working with devns branch; it is similar to the original method posted, but uses suggestions from Soma, tpr and LostKobrakai... $this->wire("config")->site = new WireData(); $st = $pages->get('/settings/')->settings_table; foreach($st as $row) { if(!$row->value) continue; if($row->disable == 1) continue; $thisKey = $row->setting; $this->wire("config")->site->$thisKey = $row->value; } This allows the site settings from the database to be accessible everywhere needed, and not have to init the array in config.php. The syntax is slightly cleaner/easier than using the array style. $this->wire('config')->site->pub_search_pattern; or in a template: $config->site->pub_search_pattern; 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted June 11, 2016 Share Posted June 11, 2016 @Macrura May I suggest using WireData instead of StdClass. This makes code more resilient to missing properties and prevents lot's of isset() nonsense. $a = new \stdClass(); if($a->test) echo $a->test; // Will generate a PHP Notice "Undefined Property: …" $a = new WireData(); if($a->test) echo $a->test; // Does nothing; $a->test === null 6 Link to comment Share on other sites More sharing options...
Macrura Posted June 11, 2016 Author Share Posted June 11, 2016 ok great, yeah i just changed to that and all appears to work fine... Will update the code above with the 'final' answer... 2 Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted May 2, 2023 Share Posted May 2, 2023 I'm putting this here in case anyone finds this useful (or I google this myself in a few years)... Let's say you have the following in config.php: // config.php $config->myArray = [ 'foo' => [ 'k1' => 'v1', 'k2' => 'v2' ], 'bar' => 'some string', 'baz' => ['some', 'other', 'array'] ]; Now you want to want to add an item to the 'foo' array somewhere else in your codebase (template file, a module's init method, etc.). This won't work (overloaded notice will occur): $config->myArray['foo']['k3'] = 'v3'; Correct way to do it: $config->myArray = array_merge( $config->myArray, [ 'foo' => // existing $config->myArray['foo'] + // new [ 'k3' => 'v3' ] ] ); 2 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