Macrura Posted February 12, 2016 Share Posted February 12, 2016 in my config.php, i setup an empty array for siteSettings like this: $config->siteSettings = array(); then in my ready.php file i'm array merging some values from a settings table (profields table), in the admin like this: $st = $pages->get('/settings/')->settings_table; $settings = array(); foreach($st as $row) { if(!$row->value) continue; if($row->disable == 1) continue; $settings[$row->setting] = $row->value; } $config->siteSettings = array_merge($config->siteSettings, $settings); i'm curious if anyone sees any possible issues with this; it works now and i can access my siteSettings everywhere doing this; 7 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted February 12, 2016 Share Posted February 12, 2016 I Don't see any issue here. It's IMO a good way of doing things, doing it 'all the time'. 1 Link to comment Share on other sites More sharing options...
teppo Posted February 12, 2016 Share Posted February 12, 2016 I Don't see any issue here. It's IMO a good way of doing things, doing it 'all the time'. Same thing here. As long as Ryan doesn't add a native setting called "siteSettings" – which seems quite unlikely – all is good Link to comment Share on other sites More sharing options...
Macrura Posted February 12, 2016 Author Share Posted February 12, 2016 ok thanks - that's good to hear ! on some previous projects i was getting those values in the _init and just setting variables i could use in templates, but were not available in functions, modules or the admin (such as in runtime markup field). For this, I had initially tried to add items to the array directly but was running into an "indirect modification of overloaded property" error. After researching that, i solved it by using the array merge; though i am curious if there is a way to add items directly on the fly from a template file, maybe i need to use the _set ? __set( $key, $value ) Provides direct reference access to set values in the $data array 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 12, 2016 Share Posted February 12, 2016 You could also add a custom api variable like that. $this->wire('variableName', $obj); In your case it's both config, but if you're adding something different this might even be more appropriate. 6 Link to comment Share on other sites More sharing options...
Macrura Posted February 13, 2016 Author Share Posted February 13, 2016 You could also add a custom api variable like that. $this->wire('variableName', $obj); In your case it's both config, but if you're adding something different this might even be more appropriate. so if i wanted to make an api variable called settings, how would i populate it with the object, say from the ready.php, or would i need to create a module? so would it then be possible to have a wire('settings')->siteTitle sort of thing?, instead of $config->siteSettings['siteTitle'] Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 13, 2016 Share Posted February 13, 2016 Exactly. You would even get $settings in template context. 2 Link to comment Share on other sites More sharing options...
tpr Posted February 13, 2016 Share Posted February 13, 2016 This is a great tip. I just used it in a module and simplifies things a lot. In init() I create a new global variable and process its values on ready(). 1 Link to comment Share on other sites More sharing options...
bernhard Posted March 24, 2016 Share Posted March 24, 2016 hmmm, came across the "indirect modification of overloaded property" error today and found this thread... thank you lostkobrakai for that snippet $this->wire('variableName', $obj); it works, but only as long as i do not try to modify that variable in a template file. my setup: (delayed output) _init.php $test = array('one', 'two', 'three'); $this->wire('testarray', $test); template XY included via wireRenderFile() $testarray = wire('testarray'); // $testarray = [one, two, three] $testarray[] = "four"; // $testarray = [one, two, three, four] _main.php // wire('testarray') = [one, two, three] // why is four not stored in the array? what i was trying to do is to make some classnames configurable during runtime. i have a repeater matrix for some content blocks. they get rendered into the same parent div and i want to add classes dynamically depending on the items that are contained in the repeater. my workaround is setting the parent div's classname via switch($page->template) { case 'blog': $class = "demo class blog"; break; ... default: $class = "demo class"; break; } // html <div class="<?= $class ?>"> // foreach repeaterfield echo item->render() </div> thats not ideal. i would like to set the parent class directly in the file with the code for the field-render like this: <?php $democlasses = wire('democlasses'); $democlasses[] = "my-sample-blog-parent-class"; ?> <div> // my blog markup </div> any hints how i can get a configurable array in my templates? until now i just needed some global variables and storing them just like this worked fine: // _init.php $config->demovar = "demo"; // template $config->demovar = "newdemo"; // _main.php echo $config->demovar; // newdemo hope i made myself clear edit: i tried with wirearray at first (to have something like parentclass->add('blog') ) but i had the "noinstanceof wire" problem. there was a tread about this some days ago but i was not able to find it any more... any help very welcome Link to comment Share on other sites More sharing options...
Soma Posted March 24, 2016 Share Posted March 24, 2016 Maybe of use for someone. I somewhere use a in a Helper module's init(); // site specific configs $this->wire("config")->site = new StdClass(); // so now you can do $this->wire("config")->site->someKey = "somevalue"; and use this $config->site->someKey everywhere. Link to comment Share on other sites More sharing options...
bernhard Posted March 24, 2016 Share Posted March 24, 2016 hi soma, i was doing exactly this, but i did not get it working with arrays. is your post related to mine? edit: i think it works as long as i stay inside _init.php but i want to modify the array in template files... Link to comment Share on other sites More sharing options...
szabesz Posted March 24, 2016 Share Posted March 24, 2016 I could not make use of $this->wire('variableName', $obj); in my template files either, because as bernhard has pointed out, it is not possible to modify the variable. So I ended up using this: use ArrayObject; $sbs_globalData = array( 'block_counter' => 1, ); $sbs_globalArrayObject = new ArrayObject($sbs_globalData, ArrayObject::ARRAY_AS_PROPS); $config->sbs_globals = $sbs_globalArrayObject; However, I am also interested in utilizing WireArray instead. 1 Link to comment Share on other sites More sharing options...
tpr Posted March 24, 2016 Share Posted March 24, 2016 //_init.php $testVar = new \stdClass(); wire('testVar', $testVar); // home.php (or elsewhere) $testVar->myArray = array( 'hello' => 'world' ); echo '<pre>'; var_dump($testVar); echo '</pre>'; This works fine here. Or am I missing something? Using stdClass can be an issue because you can't add methods to it. If you plan to do so, better using a real class. 1 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 (edited) EDIT: anyone reading this, please note that the variable was undefined because instead of _init/php I used ready.php accidentally, see: https://processwire.com/talk/topic/12198-modifying-config-property-eg-sitesettings-from-readyphp/?p=116746 Thanks tpr, What we are after is this (at least I am ) : //_init.php $testVar = new \stdClass(); $testVar->myArray = array( 'hello' => 'world' ); wire('testVar', $testVar); // home.php (or elsewhere) echo '<pre>'; var_dump($testVar); echo '</pre>'; This results in "PHP Notice: Undefined variable: testVar in..." in home.php Edited March 25, 2016 by szabesz Link to comment Share on other sites More sharing options...
tpr Posted March 25, 2016 Share Posted March 25, 2016 You could do a foreach on the object and create the variables. 1 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 Sorry, I forgot to specify that it is in the template where $testVar is undefined. (I'm gonna edit the post...) Link to comment Share on other sites More sharing options...
tpr Posted March 25, 2016 Share Posted March 25, 2016 That should not be undefined. Are you sure _init.php is prepended? 1 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 Oh, my, I mixed up /site/templates/_init.php and /site/ready.php just because the latter was open in my IDE and I used that.... Sorry for this! Sure, in _init.php the variable is available thanks! Now I have a few posts to edit Link to comment Share on other sites More sharing options...
tpr Posted March 25, 2016 Share Posted March 25, 2016 (edited) Go get a coffee This works too: // _init.php (mind the underscore) wire('testArr', array()); $testArr['initValue'] = 'helloworld'; // home.php (no underscores at all) $testArr['myArr'] = array( 'first' => 'veryfirst', 'two' => 'veryfirst' ); // create variables from $testArr array extract($testArr); echo '<pre>'; var_dump($initValue); echo '</pre>'; echo '<pre>'; var_dump($myArr); echo '</pre>'; Edited March 25, 2016 by tpr 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted March 25, 2016 Share Posted March 25, 2016 @szabesz, those kinda things happen 'all the time'. 2 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 @Martijn Geerts: Yeah, although these naming conventions are logical, it is easy to get confused sometimes.@tpr: Actually, I was drinking my coffee why fiddling with the above code, but doing these two activities at the same time made things worse, I suppose 1 Link to comment Share on other sites More sharing options...
bernhard Posted March 25, 2016 Share Posted March 25, 2016 ok, finally i got (almost) what i wanted: // _init.php // set classes for parent container $classes = array(); $classes['tm-main'][] = 'tm-section'; $this->wire('classes', $classes); // blog.php $classes = $this->wire('classes'); $classes['tm-main'][] = 'tm-blog'; $this->wire('classes', $classes); // _main.php <section id="tm-main" class="<?= getClasses('tm-main') ?>"> <?= $content ?> </section> // _func.php /** * render class string for given div * * @param string key of element * @return string class string * */ function getClasses($element) { $classes = wire('classes'); return implode(" ", $classes[$element]); } using PW 3.0.12 it did not work with the example of tpr above using wire(x, y) without $this... i'm still not 100% happy with that solution. i always need to get, set and save the new class in the template files. that seems not the best solution. i tried to create a function addClass($element, $class) with this content: /** * add class to given element * * @param string key of element * @param string class * */ function addClass($element, $class) { $classes = wire('classes'); $classes[$element][] = $class; wire('classes', $classes); } but that does not have any effect. if anybody could give me some hints what is going on and why, that would be great Link to comment Share on other sites More sharing options...
horst Posted March 25, 2016 Share Posted March 25, 2016 (edited) @bernhard: I use SPEX module that has support for this sort of things (and more). If the above really does not work for you, you may have a look into SPEX, how it is done there. It uses two hooks: https://github.com/jdart/Spex/blob/master/Spex.module#L150 & https://github.com/jdart/Spex/blob/master/Spex.module#L170 The relevant parts in the first hook for you are in line 155 157 and 164-165 (the rest is related to a profiler / logging, it is not relevant for you in the initial regard) If you want to try it out or build something own that need to rely on the method getTemplateVars(), please refer to its support thread (or better to the solution here) for a necessary code change when using it with PW 3.0+ Edited March 25, 2016 by horst 1 Link to comment Share on other sites More sharing options...
szabesz Posted March 25, 2016 Share Posted March 25, 2016 Hi boys, // _init.php (mind the underscore) wire('testArr', array()); $testArr['initValue'] = 'helloworld'; // home.php (no underscores at all) $testArr['myArr'] = array( 'first' => 'veryfirst', 'two' => 'veryfirst' ); // create variables from $testArr array extract($testArr); echo '<pre>'; var_dump($initValue); echo '</pre>'; echo '<pre>'; var_dump($myArr); echo '</pre>'; First of all, it is not early morning, so I got back to this one bernhard wrote: "using PW 3.0.12 it did not work with the example of tpr above using wire(x, y) without $this..." Actually, this has nothing to do with PW version, since $testArr is just a local variable, in the scope of the template and not related to the wire object. This way $testArr is not stored as an API variable. To append it to the wire object, we do need to access it via $this. See public function wire($name = '', $value = null, $lock = false) in /wire/core/Wire.php.The function wire($name = 'wire') in /wire/core/Functions.php can only retrieve variables but it cannot set them. So wire('testArr', array()); has no effect. The code only works, because we are dealing with variables in the same scope. Correct me if I'm mistaken, but I cannot come up with another explanation. 1 Link to comment Share on other sites More sharing options...
bernhard Posted March 25, 2016 Share Posted March 25, 2016 thank you szabesz, that makes sense to me. so would it be possible to set a property (right?) of the wire object inside a function in _func.php? function setPropertyOfWire($key, $val) { $this->wire($key, $val); } would not work, because $this is the wrong scope. OOP is still quite new to me 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