Jump to content

modifying $config property (e.g. siteSettings) from ready.php


Macrura
 Share

Recommended Posts

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 by szabesz
  • Like 1
Link to comment
Share on other sites

@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);
}
  • Like 1
Link to comment
Share on other sites

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 :)

  • Like 2
Link to comment
Share on other sites

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.

  • Like 4
Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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

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.

  • Like 7
Link to comment
Share on other sites

@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.

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

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;
  • Like 1
Link to comment
Share on other sites

@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
  • Like 6
Link to comment
Share on other sites

  • 6 years later...

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'
      ]
  ]
);

 

  • Like 2
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...