We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 52884
    • 25 Posts
    Hi all,

    I am trying to save a dynamic value (country code of the user), which I need to retrieve in several cached and uncached chunks used in a resource.

    My approach was to use a placeholder for this, set via a plugin on OnLoadWebDocument Event.
    This works (I can get the value in all chunks). However, the rendered resource seems to be stored in the cache with the placeholder value of the first visitor. If I swith the location, the resource is retrieved from the cache and not updated with the new placeholder value. I tried to set the placeholder via a snippet (runsnippet) to ensure the snippet gets called uncached, but the result was the same.

    I found an interesting article which might could lead to a solution ( http://www.modx360.com/blog/2010/02/12/prevent-parsing-modx-tags/ )
    But I was wondering if there is an easier way then parsing and manipulating the whole resource. I also found a link to an Evo Plugin called ParallelPageCache, but the link is dead now.

    Does anybody have an idea how to achieve this?
      • 3749
      • 24,544 Posts
      Have you tried making the placeholder uncached?

      [[!+placeholderName]]
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 52884
        • 25 Posts
        That worked - partly. The correct output of the placeholder is displayed (in chunks I am using as a contentblocks template).

        However, when I try to use output modifiers on an uncached placeholder in these chunks, I run into problems. Other content in the chunk is not displayed at all, when I use something like [[!+usergeolocation1:isnot=`hk`:then=`1`:else=`2`]] That seems to be the case with every placeholder, no matter how they are generated. So this might be more of a general caching issue.

        (I am using getResources in my parent resource chunk, which gets the child resources which are using contentblocks with chunks as contentblock templates)
          • 3749
          • 24,544 Posts
          The exclamation point delays the processing of the tag, so it hasn't been replaced with the value at the time the output modifier executes.

          If you have a snippet that calculates the usergeolocation, maybe you can modify that snippet to set the placeholder value to 1 or 0. It will be a lot faster than the output modifier.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 52884
            • 25 Posts
            Hi Bob,

            thanks for the explanation! Unfortunately, 0 and 1 was only an example to keep it simple, the code I want to put out is more complex and would require bigger modifications.

            So I guess the only way would be using a snippet that does the calculation and then uses "getChunk" to put out the correct content, right?
            No way to tell the modifier to delay its exexution as well? Maybe a custom modifier/filter?
              • 3749
              • 24,544 Posts
              I think a snippet is the best bet. A custom modifier is just a snippet with a bunch of wasted time and resources used to parse the modifier.

              TBH, in situations like this, I would normally skip getResources and put all the processing in a single custom snippet, using a query to get the resources and then looping through them, calling getChunk() just once to get each Tpl chunk, and replacing the placeholders with str_replace(). Doing it that way is not only faster, it also eliminates all possible issues with the cache, which (as you're finding) can be time-consuming and really irritating.

              BTW, after re-reading your OP, it might work better to save the data in a $_SESSION variable when the user logs in (say, in a plugin attached to one of the Login events), then retrieve it directly in your snippet, or create a separate snippet that just returns the $_SESSION variable. [ed. note: BobRay last edited this post 9 years, 11 months ago.]
                Did I help you? Buy me a beer
                Get my Book: MODX:The Official Guide
                MODX info for everyone: http://bobsguides.com/modx.html
                My MODX Extras
                Bob's Guides is now hosted at A2 MODX Hosting
                • 52884
                • 25 Posts
                Ok, I am making progress with this.

                In my snippet I was able to loop through the resources and put the content with the help of calling getChunk() to a variable.
                I now would like to remove some content blocks layouts before returning this variable, if they should not be displayed to the visitor. The CB Layout Template chunk contains HTML comments with the country codes it is intended for:
                <!--GEO-START--DE-US- -->
                content...
                <!--GEO-END--DE-US- -->
                


                So my idea was to use preg_match_all to get all commment matches and replace these parts via preg_replace. But it seems that there are no matches found at all. Do I need to convert the variable first to get the regex working?

                
                $output= output of all chunks..
                $usergeolocation = "US";
                
                preg_match_all('/<!--GEO-START-(.*?)\-->/ims', $output, $matches);
                $usergeolocation = "US";
                
                $mycountryfound = array();
                
                foreach ($matches as $key => $value) {
                  if (strpos($value, '-'.$usergeolocation.'-') !== false) {
                    $mycountryfound[] = $key;
                  }
                }
                
                foreach ($mycountryfound as $found) {
                $startPoint = $matches[$found];
                $endPoint = str_replace("START","END",$matches[$found]);
                $output = preg_replace('#('.preg_quote($startPoint).')(.*)('.preg_quote($endPoint).')#si', '', $output);
                
                }
                
                return $output;
                
                
                  • 3749
                  • 24,544 Posts
                  Have you tested your regex against a real example to see if it gets a match? You may have to escape all the dashes and the exclamation point (or just leave the HTML comments out of the expression altogether -- I don't think you need them).


                    Did I help you? Buy me a beer
                    Get my Book: MODX:The Official Guide
                    MODX info for everyone: http://bobsguides.com/modx.html
                    My MODX Extras
                    Bob's Guides is now hosted at A2 MODX Hosting