Welcome to the MetaMod and Chameleon Support Forums.

Before posting, please check out the FAQs.

helpme

 

Need extra help with your Joomla site? Consider paid Joomla support by the developer of Chameleon and MetaMod.

 

Global (without using global) variables for metamod mods.

Global (without using global) variables for metamod mods.

Hi Stephen,

It's been a long time smile. I was around back when metamod and metaTemplate were in it's infancy. I tried logging in after all these years and it still works... my memory that is. tongue
So, now I'm back again, with a different project under similar conditions, and some questions.

I've got a very specific task which I need help wrapping my head around. I'm a bit rusty. Back in the day, metamod appears to have shared variables across mods. In other words, defining php functions and variables in one metamod, was available from another. It appears this isn't the case anymore. I'm not sure if this is a J! change, or a metamod change.
The reason I ask is becuase I'm trying to limit queries. I'm expecting heavy loads. It would be ideal to call a script once, or create one in one of the mods, run a query, and have the arrayed results available from any metamod. Do you have thoughts on this? A safe, clean, manageable way?

FYI, currently I'm using sourcerer for php in mods... but appears I will have to call a php script over and over from each mod, same as I am now finding with metamod (which I'm prob rolling over to regardless due to security concerns). I believe both mods (yours and sourcerer), by calling the script every time (from each mod), creates multiples of the same query in the script. True?

Cheers. Good to see you're still in the game with these two amazing products. I'll gladly purchase metamod if you think it's the right tool for my objective, and don't mind giving me a small hand on implementation here (or honestly I'd rather pay you up front for a few hours of work, on top of purchasing it ,to create an example of what I need of which I can then expand upon, should you have an idea of how to implement this properly.

Best,
Forrest

NOTE: In case you read this before I edited it, my other issue is resolved. I created a custom plugin to search/replace the output.

Edited By: techgump
23-Feb-16 06:14:57

techgump
Local SEO Guru
Beginner Modder
ranks
useravatar
Offline
16 Posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

Hi Forrest,

great to hear from you again.

You'll be pleased to know that Chameleon offers some great support for what you are doing with find and replace. It has global find and replace, and allows the replacement string to contain tokens for PHP global variables. This means that you can replace {mytoken} with {global:$foo}. In the PHP box in Chameleon you can have previously defined global $foo to whatever you want. This gives you the ability to calculate something once, based on conditions, then use it later.

You mentioned about calculating something in MetaMod and making it available to other modules. This should still work, but is obviously be affected by module caching and the order of module rendering. If that wasn't working for you then I would suggest looking closely at those 2 issues. However, I think Chameleon may be a better way to go as it won't be affected by caching and gives you more control depending on what you are trying to do - i.e. it doesn't directly deal with modules in the same way as MetaMod but can deal with find-and-replace etc.

Hope that helps,
Stephen

Stephen Brandon
MetaMod / Chameleon developer
If you use MetaMod or Chameleon, please post a rating and a review at the Joomla! Extensions Directory: Chameleon | MetaMod

metamodguy
useravatar
Offline
3328 Posts
User info in posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

Thanks for the speedy reply, Stephen. If you don't mind, I'm going to tap you just a bit further, or anyone else here who wants to chime in, for a bit more indepth J! guidance and knowledge in regards to implementation with metamod/chameleon, if you could and would.

First, I'm currently working from the perspective that server caching is off. I'll address this down the road, but since it's a multisite under one install, I'm going to have to address unique caching folders on a per domain basis (for clearing cache otherwise will clear all client sites caches) as well as dealing with the prospect of unsavvy users who will expect to see updated content merely by editing article forms.
However, ideally at some point, I do indeed need to plan on implementing caching on mods and eventually pages. So if I understand you correctly, Chameleon rules only work before cached pages are fetched? Or can rules be ignored if pages are already cached? Other than the unsavvy client issues, I don't foresee an issue where cached pages will present an issue regarding variables. I'd hate to be unnecessarily generating queries inside Chameleon to propagate values that are already cached just fine into pages.... which brings me to my second scenario.

As of yet, all my variables to be stored and passed (or searched and replaced) are merely domain dependant (and nothing else), hence they can be considered static (which is why caching isn't a concern in this regard). A single php query and script upon site entrance could suffice to propagate variables for site-wide use, substantially reducing queries when viewing any other pages. Most vars aren't secretive either, meaning session storage is an option. Your {globals:$foo} seems a candidate to provide variable passage, but how is this architecturally implemented in Chameleon? Does it rely on J! member functions? Sessions? Or is it actually setting php $globals? Maybe it uses a combination of things with fallbacks? If you could elaborate, it would help. If rules are run regardless of cache, then it may be best for me to propagate my queries into a single cacheable metamod pro which is loaded prior to other meatmods? And on that topic, while I am unable to simply set a var or function in one mod and pass it to another like I used to (without declaring it global), this J! 3 function seems fine in doing the job to pass variables within a given page.

Code:

$app = JFactory::getApplication();

$app->set('some_variable', 'some_value');

...

Code:

echo $app->get('some_variable');

Is there another method (other than sessions, $globals, POST) that you know of which I should consider in passing vars from a main php script metamod and subsequent mods? A method that passes vars between pages? Would it be ideal for me to use sessions, or a combination of the two, to reduce server loads?  I could foreseeably, in the first (what I'll call "primary") metamod for variable prep:
- Check $session for existing vars
- else fallback to $app for vars, and set missing $session var the same
- else neither exists so only then run query and create/set both $app and $session vars same.
In this scenario, given caching is off for now, I can reduce queries on subsequent pages from the primary script metamod by at least utilizing session var checks first in the primary script metamod before processing the subsequent script to generate vars. Are sessions my only good option for this scenario in J passing vars between pages, or does J! have some other tools in it's box that you're aware of? Any advice?

Third, I really have two cases of WHOM will be using variables/tags. Myself and team coders of which {global:$foo} presents no issue (and some foreseeable benefits), and the other is my clients, whereby I really need simplified tags for thier use: like {BUSINESS}, {NAME}, {CITY}, etc.. Right now I've implemented the client tags by creating a custom system plugin in first position which grabs the body onAfterRender, searches for the strings, and replaces them with set variables. Seems to work great, is a single script, and will cache when I implement such. I'm not seeing a downfall yet, or a reason to move this part. It also appears to work on feeds fine too. Knowing what I've described now, do you have any further insight as to why I might consider changing this specific part in favor of Chameleon?

I'm just trying to wrap my head around the issue a bit more. I'd rather do things right out of the box, and appreciate any knowledge/time you're willing and able to put forth in pointing me in the right direction.

EDIT: Oh, and one more thing. Can I jump in and out of PHP from within metamod?
And what about an option to process plugins like in the custom HTML mod?

Again, thank you, and thanks for continuing to support and develop out your products. smile
I'm off to buy metamod for now.

techgump
Local SEO Guru
Beginner Modder
ranks
useravatar
Offline
16 Posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

I'll try to address these one at a time:

"So if I understand you correctly, Chameleon rules only work before cached pages are fetched? Or can rules be ignored if pages are already cached?"

- Chameleon rules trigger before the pages are rendered, therefore before any caching takes place or decisions about whether or not to cache are made. I've never considered what it would take to be able to detect if the current request would result in a cache hit (extra for experts!). It might not be that difficult at least for the system page cache. Other types of caches would need to be tested differently. I imagine the logic also starts to get quite complex in that case e.g. testing to see if a particular module is cached is also going to interact with the page cache, as well as the fact that the module in question may appear on a variety of different pages.

Note also that the search-and-replace system is (I think) generally going to work on the final output (post cache hit). I can't remember off the top of my head if you can change that by reordering the system cache plugin to before/after the Chameleon Rules system plugin.

"Your {globals:$foo} seems a candidate to provide variable passage, but how is this architecturally implemented in Chameleon? Does it rely on J! member functions? Sessions? Or is it actually setting php $globals? "

- actually it's {global:$foo} not {globals:$foo} sorry for the type.
available:
{global:$foo}
{session:foo}
{env:foo}
These correspond to the $GLOBALS, $_SESSION and $_ENV superglobals. e.g. if you have set $_SESSION['foo']='bar' then that corresponds to {session:foo}. You can nest them as well: $GLOBALS['foo']['bar'] = 'wombat' corresponds to {globals:$foo[bar]}

There's nothing particularly Joomla specific about this - it's just plain ol' PHP.

"I am unable to simply set a var or function in one mod and pass it to another like I used to (without declaring it global)"

- hmm that must have been a long time ago! I haven't made any changes to that for years. If declaring it global "fixes" it then it's a matter of variable and function scope. Performance wise there shouldn't be much difference.

I quite like your $app->set() method which I didn't know about. Do you know how this is implemented in Joomla? Sessions or only for the current request? However if you are looking for performance then stick with globals as they will be a lot faster since they don't involve any function/method calls.

"Are sessions my only good option for this scenario in J passing vars between pages, or does J! have some other tools in it's box that you're aware of? Any advice?"

Unless you want to pass large amounts of data, then sessions are by definition the best and correct way to keep data around for a given user for their session.

You mentioned however that the data is domain dependent. Does this mean it's not actually user dependent? If it's not user dependent then the session is not as appropriate.

Options:
- if you just want to make decisions on the fly per page (e.g. "domain is mydomain.com so replace the logo with the mydomain logo" ) then use globals to pass it on to any modules etc that might need it.
- if you need to remember something that a user did for the rest of the session, then you need to use sessions
- if you need to remember certain actions/events that occur and use these to trigger future actions for ALL users irrespective of user or page, then you need to store things in the database or file system.

I like your approach of putting all the decision-making into 1 MetaMod (uncached) then subsequent MetaMods can draw on the saved data if/when necessary.

Regarding your custom plugin doing find and replace: if this works well for you then it will definitely be less overhead than using Chameleon. The main benefit of Chameleon for you would be that other admins might find it easier to add in new search-and-replace strings in future. But performance-wise I think you're doing it a very efficient way.

Jumping in and out of PHP blocks: yes you can do this in MetaMod using the standard PHP tags. Note that MetaMod already assumes you are writing PHP so you don't need the opening PHP construct. But you can close that again and write standard HTML - just remember to re-open the PHP again after the HTML block even if you are not writing any more PHP.

A "gotcha" with that is that you can't pull in extra modules between other output. The only way to trigger a module to appear is to return the module id or position with a return statement, which by definition ceases execution of the code block, so anything after it will be ignored.

Lastly, processing plugins on MetaMod output: sorry this isn't supported. The main thing MetaMod does is to choose when to display other modules, and these other modules may or may not have the ability to run content plugins. Direct output from the MetaMod was a bit of an afterthought  (though extremely useful!) so I never bothered to add the option of running plugins over it. Do you really need this?

Cheers,
Stephen

Stephen Brandon
MetaMod / Chameleon developer
If you use MetaMod or Chameleon, please post a rating and a review at the Joomla! Extensions Directory: Chameleon | MetaMod

metamodguy
useravatar
Offline
3328 Posts
User info in posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

Awesome. Thanks for your insights. A clear direction for me is being better formulated.

I quite like your $app->set()... Do you know how this is implemented in Joomla? Sessions or only for the current request?

Based on my findings, this is for the current request only.

Code:

$app = JFactory::getApplication(); 

$app->set('some_variable', 'some_value');
...
echo $app->get('some_variable');

However, there is one for sessions as well.

Code:

$sess = JFactory::getSession();

$sess->set('some_variable', "some_value");
...
echo $sess->get('some_variable');
You mentioned however that the data is domain dependent. Does this mean it's not actually user dependent? If it's not user dependent then the session is not as appropriate.

Yes, my variables are not user dependant; just domain dependant. I'm curious why you state sessions as not being as appropriate. I can see with page caching on how using session vars in this manner is mostly irrelevant in use, but isn't there some benefit, when no cache is used, to setting session settings for variable access on additional page views? Otherwise, on each additional page loaded my script in metamod requires I query the database and process my php rules to generate the static values... the same values from the previous page, and page before that, etc. Using sessions I can eliminate query and script redundancies on any additional page by passing session vars, and first checking if they exist before processing the script. Is this not advisable? I'll be honest, I'm actually a novice php coder who's almost always in way too deep for my limited knowledge.  yikes


So, great news on jumping in and out of php. I figured such, but thought I'd ask. The return function ending the script isn't a big deal. It doesn't effect my current situation in any way. However, seeing that metamod doesn't process plugins, I may have to rethink that.
The reason I asked is that I'm using a Google map plugin, which like many plugins of this nature, can be called from articles and custom html mods (pending "process plugins" works) using a specific tag; like

Code:

{googlemaps: height:300|width:400|addr:1234+Playa+Blvd+...}

So, in my case, I'm using php to derive dynamic address vars for the tag based on incoming domain, and am hence needing to call it, or a portion of it's vars, out using php.
So do I really need it? No. I'm sure I can find another way around. But would it be nice in a future release.. something to consider I suppose smile

techgump
Local SEO Guru
Beginner Modder
ranks
useravatar
Offline
16 Posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

BTW, you might also find of interest on the matter of setting/retrieving vars/globals using Joomla:

https://docs.joomla.org/Retrieving_requ … ing_JInput

Specifically the section: Getting Values from a Specific Super Global

techgump
Local SEO Guru
Beginner Modder
ranks
useravatar
Offline
16 Posts
Administrator has disabled public posting

Re: Global (without using global) variables for metamod mods.

Regarding domain dependant code vs session:

You are right that calculating the info once per session then storing it in the session means less server load.

However if you have 2 users on the same domain, and for page X the output of the page is the same for both users (i.e. not user dependent), then surely it's better to calculate it once overall and not twice (once per user)?

This suggests to me that you use the Joomla caching support in PHP rather than session support to hold domain-specific data. This stores the cache on disk and each request will read this cache if available.

Make sense?

So you might want to make a tiny plugin (or use Chameleon) that checks for which domain you are on and (at simplest) sets a global variable with some content which can be picked up in different modules, OR if the content is more dynamic or resource intensive to create, then stores it in the cache folder. The code would then pick it up from the cache if the cache is fresh and avoid having to create it.

At the end of the day don't succumb to "premature optimisation". That is, simply making a conditional based on domain is very lightweight. Setting some text into a variable is also very lightweight. Don't bother trying to cache those things, honestly. Only try to cache things that:

- involved significant looping
- use more than 1 database call, or any query that uses a lot of joins and is inherently slow
- uses a lot of function/method calls, particular involving looping (e.g. parsing of XML files).

Hope that helps,
Stephen

Stephen Brandon
MetaMod / Chameleon developer
If you use MetaMod or Chameleon, please post a rating and a review at the Joomla! Extensions Directory: Chameleon | MetaMod

metamodguy
useravatar
Offline
3328 Posts
User info in posts
Administrator has disabled public posting

Board Info

Board Stats:
 
Total Topics:
1679
Total Polls:
6
Total Posts:
5933
Total Posts Today:
2
User Info:
 
Total Users:
4371
Newest User:
kajha63871
Members Online:
0
Guests Online:
252

Online: 
There are no members online

Forum Legend:

 Topic
 New
 Locked
 Sticky
 Active
 New/Active
 New/Locked
 New Sticky
 Locked/Active
 Active/Sticky
 Sticky/Locked
 Sticky/Active/Locked