We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22303 MODX Staff
    • 10,725 Posts
    Quote from: BobRay at Oct 20, 2008, 11:35 PM

    I must be misunderstanding this because what I see seems to contradict this. My chunk is in a cached page and should be cached by default (causing my original problem). But it *does* set the placeholder from the properties sent in the getChunk() call even though I don’t use _cachable=false or the ! token in the placeholder tags.
    Right, that’s what it is supposed to do. It replaces any properties passed to the chunk (or any embedded in the chunk through other tags) that are cacheable first, and then removes the placeholders set from the properties. For the next release, it will also restore any placeholders overwritten in the scope of the chunk. Once the output of that chunk with all cacheable content is produced and cached, it will in the future skip the placeholder setting and simply return the output produced the time it was cached.

    Quote from: BobRay at Oct 20, 2008, 11:35 PM

    I like that, but now I have this question: Why would I ever want to use the properties array in getChunk() if I can get any combination of cacheing I want using just setPlaceholder() and [[!$placeholder]], especially since using the properties array might conflict with a placeholder marked with the ! tag (perhaps set by a user of the snippet modifying the tpl).?
    Because they are local to the scope of the chunk and should be replaced immediately. Delaying any placeholders set from these local properties with the ! token will prevent the local placeholders from being processed and you will instead get values outside of the chunk scope replaced (or they will be removed if unprocessed when processing is finished). The restoration feature that is coming in very soon will address the conflict issue with placeholders set outside the chunk scope.

    Quote from: BobRay at Oct 20, 2008, 11:35 PM

    BTW, I wanted to ask about the philosophy of using the properties array to *set* incoming properties in getChunk(). My understanding of the general use of arrays like that in the getObject family is that we use an array like that as a set of search criteria for finding the object (and the argument is called $criteria in getObject()). I understand that getChunk() is not just a wrapper for getObject(), but based on what I knew of MODx objects, I would have guessed that that array in getChunk() would just add extra search criteria. I would never have guessed that its function was to set properties of the returned object and it would be really tough to understand what the scope of those changes would be (even after having it explained). And it’s not that common, IMO, to *set* specific object properties in a *get* method.

    I don’t have much in the way of an alternative to suggest, but thought I’d at least raise the issue. The only other way I could think of is to do away with that argument altogether (or just not tell people about it) and just use setPlaceolder() and the ! token in the placeholder tags, even if it’s a little less efficient. It might prevent having to have a discussion like this one with a boatload of confused developers. wink
    xPDO::getObject(), getCollection(), getObjectGraph() and getCollectionGraph() are the core xPDO functions that work with xPDOObjects generically. getChunk is a legacy modX API function that I extended with a new parameter to work just as parseChunk did. getChunk has nothing to do with xPDOObjects and is specific to the modX class functionality which extends xPDO and interacts with one particular xPDOObject, modChunk (which extends modElement). There is absolutely no relationship between these functions; one is for loading instances of xPDOObjects, while one is a shortcut method for getting the processed output of a chunk.

    Teaching folks how the scope of these placeholders will work is the key; generally, chunks serve as templates for specific scripts, so most of the time a simple combination of cacheable local placeholders and either cached or uncached global placeholders will work (depending on if you are caching the script and/or resource as well).
      • 3749
      • 24,544 Posts
      Once the output of that chunk with all cacheable content is produced and cached, it will in the future skip the placeholder setting and simply return the output produced the time it was cached.
      Just to see if I’m finally getting this --

      For a chachable chunk, once you’ve made the changes you mention:

      The chunk in the cache will always have [[!+placeholder]] tags in it but all other cachable tags will have been replaced with content.

      Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content unless there are properties set in getChunk().

      In that case those properties will appear instead of the ones from setPlaceholder() but what’s in the cache will be unchanged and if that chunk appears elsewhere, even on the same page, it will get the setPlaceholder() values for the placeholders tagged as uncached.

      Am I getting close?

      I still can’t think of a situation where you’d need to set placeholder properties in the getChunk() call rather than just putting setPlaceHolder() one line above the getChunk() call. Maybe I’m misunderstanding the scope of setPlaceholder(). Doesn’t the most recent setPlaceholder() always determine what goes in the output? I’m still wondering if setting the properties in getChunk() is worth the potential confusion it could cause.

        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
        • 22303 MODX Staff
        • 10,725 Posts
        Quote from: BobRay at Oct 21, 2008, 05:13 PM

        Am I getting close?

        I still can’t think of a situation where you’d need to set placeholder properties in the getChunk() call rather than just putting setPlaceHolder() one line above the getChunk() call. Maybe I’m misunderstanding the scope of setPlaceholder(). Doesn’t the most recent setPlaceholder() always determine what goes in the output? I’m still wondering if setting the properties in getChunk() is worth the potential confusion it could cause.
        Hmm, not really; I see it the opposite; any data that needs to be replaced in the local scope of processing the chunk should be passed as properties. No setPlaceholder() calls are necessary, and anything processed within the scope of the chunk is replaced with those local properties without affecting the global placeholders with the same name; just like parseChunk() always has. So once you call getChunk(’Chunk’, $properties) and the output comes back, you have whatever placeholders were set before you called it available again. Caching is irrelevant to this, since if the chunk is cached, everything it output when cached is not going to be processed again, just returned.

        The only situation I see using [[!+placeholder]] in a chunk as necessary is if you have a global placeholder ’a’ and a local property ’a’ you are passing to getChunk(), but you want to use both in the chunk. I see that as rare, and in most cases you’ll have global placeholder ’a’ and local property ’b’, so [[!+a]] would not be necessary, as [[+a]] would still be in the cached content if not replaced in the scope of the chunk (or by setPlaceholder(’a’,...) calls in any other cacheable snippets on the page).
          • 3749
          • 24,544 Posts
          Ok, I think I see where you’re coming from, but first, for future reference, I really need to know if these are accurate statements (and, if not, what would be more accurate):

          For a chachable chunk, once you’ve made the changes you mention:

          The chunk in the cache will always have [[!+placeholder]] tags in it but all other cachable tags will have been replaced with content.

          Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content unless there are properties set in getChunk().

          In that case those properties will appear instead of the ones from setPlaceholder() but what’s in the cache will be unchanged and if that chunk appears elsewhere, even on the same page, it will get the setPlaceholder() values for the placeholders tagged as uncached.

          On the use of setPlaceholder() versus setting properties in getChunk(): From a coding philosophy standpoint, the more local a change is, the better, so I now agree with you on the point, but I still have a somewhat contrary view when looking at it from a developer education and usability perspective.

          It’s a whole lot easier, IMHO, for both developers and developer educators if we just say: Use setPlaceholder() to set placeholders and mark any placeholders that shouldn’t be cached with a ! token. We’re done explaining it, and they get it instantly because it fits perfectly with what they already know about caching in MODx. I could be wrong, but I’m thinking that at least 99.9% of the time, that’s going to have exactly the same effect as setting properties in the getChunk() call. In the tiny fraction of other cases, you can still set the properties in getChunk(). On the plus side, and I think it’s a big plus, we don’t have to explain complex details about the scope of placeholder manipulation to the many people who won’t find the information in the docs.

          The only counterexample I can think of would be nested snippets using the same placeholder names, but if placeholders always have a local name prefix, I don’t forsee many collisions ever happening and even if the names are the same, it would seldom cause a problem since placeholders are almost always set pretty close to where they’re used and set every time they’re used.

          Probably there’s something I’m not thinking of.
            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
            • 22303 MODX Staff
            • 10,725 Posts
            Quote from: BobRay at Oct 22, 2008, 01:20 AM

            For a chachable chunk, once you’ve made the changes you mention:

            The chunk in the cache will always have [[!+placeholder]] tags in it but all other cachable tags will have been replaced with content.
            The chunk in the cache will have any tags that could not be processed, including all tags with non-cacheable tokens ( ! ) and any cacheable tags that were not replaced (i.e. no content could be retrieved for those tags).

            Quote from: BobRay at Oct 22, 2008, 01:20 AM

            Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content unless there are properties set in getChunk().

            In that case those properties will appear instead of the ones from setPlaceholder() but what’s in the cache will be unchanged and if that chunk appears elsewhere, even on the same page, it will get the setPlaceholder() values for the placeholders tagged as uncached.
            Most recent is a difficult concept here, since it completely depends on source-order parsing of tags in a tree-like structure. The important point I think you are missing is that [[!+placeholder]] tags will never be replaced by local properties passed to an Element because by the time they are processed, that scope is gone and the placeholders that were set from those local properties are unset.

            Quote from: BobRay at Oct 22, 2008, 01:20 AM

            It’s a whole lot easier, IMHO, for both developers and developer educators if we just say: Use setPlaceholder() to set placeholders and mark any placeholders that shouldn’t be cached with a ! token. We’re done explaining it, and they get it instantly because it fits perfectly with what they already know about caching in MODx. I could be wrong, but I’m thinking that at least 99.9% of the time, that’s going to have exactly the same effect as setting properties in the getChunk() call. In the tiny fraction of other cases, you can still set the properties in getChunk(). On the plus side, and I think it’s a big plus, we don’t have to explain complex details about the scope of placeholder manipulation to the many people who won’t find the information in the docs.

            The only counterexample I can think of would be nested snippets using the same placeholder names, but if placeholders always have a local name prefix, I don’t forsee many collisions ever happening and even if the names are the same, it would seldom cause a problem since placeholders are almost always set pretty close to where they’re used and set every time they’re used.
            Using the ! technique will not work with local properties, for a reason, as I have explained; otherwise, I would agree with this.

            But element scope is going to be very important moving forward in this framework; besides setPlaceholder() is now complemented by a whole set of related functions, including modX::toPlaceholder(), modX::toPlaceholders(), modX::unsetPlaceholders(), modElement::toPlaceholders(), and more. Simply calling setPlaceholder() IMO, works, but is not necessarily the best way to work with data, especially in complex situations. As you alluded to, it goes back to being able to find the information in the documentation, which still needs to be created for this stuff.
              • 22303 MODX Staff
              • 10,725 Posts
              FYI, those changes I keep discussing are now merged into the main revolution branch as of revision 4358.
                • 3749
                • 24,544 Posts
                The important point I think you are missing is that [[!+placeholder]] tags will never be replaced by local properties passed to an Element because by the time they are processed, that scope is gone and the placeholders that were set from those local properties are unset.

                In my mind, that makes setting the properties in the getChunk() call not only more difficult, but more risky, since any user of the snippet can later make them fail to apply just by adding the ! token to a placeholder in the tpl chunk. A ! placeholder that is *only* set with properties would have no value at all in that case.

                Let me make a (hopefully) final try at describing the way things work now for placeholders in a cached chunk, based on your corrections:

                The chunk in the cache will always have [[!+placeholder]] tags in it and also other tags for which no replacement value could be found at the time it was cached.

                Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content. "Most recent" can be hard to predict, but a setPlaceholder() call made just before a call to getChunk() can be counted on to apply for placeholders marked with a ! tag.

                For [[+placeholder] tags (cached), sending local properties in a getChunk() call will override the values set in any setPlaceholder() call, but without changing any placeholder values set with setPlaceholder() and without altering the cached chunk.


                  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
                  • 22303 MODX Staff
                  • 10,725 Posts
                  Quote from: BobRay at Oct 22, 2008, 04:45 PM

                  The important point I think you are missing is that [[!+placeholder]] tags will never be replaced by local properties passed to an Element because by the time they are processed, that scope is gone and the placeholders that were set from those local properties are unset.
                  In my mind, that makes setting the properties in the getChunk() call not only more difficult, but more risky, since any user of the snippet can later make them fail to apply just by adding the ! token to a placeholder in the tpl chunk. A ! placeholder that is *only* set with properties would have no value at all in that case.
                  Which is why using ! in placeholders should be reserved for special situations where placeholders set in the templates are conflicting with those in chunks from an installed add-on.

                  Quote from: BobRay at Oct 22, 2008, 04:45 PM

                  Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content. "Most recent" can be hard to predict, but a setPlaceholder() call made just before a call to getChunk() can be counted on to apply for placeholders marked with a ! tag.
                  What if I decide to cache the snippet? Then those placeholders would never get set and since you prevented caching of the values set by those API calls into the cacheable content, they would now be empty. Another reason why ! in placeholders should be reserved for special situations where you know there will always be a placeholder being set (e.g. using [[!++site_url]] if you serve multiple domains from a single site), regardless of cacheability.

                  Quote from: BobRay at Oct 22, 2008, 04:45 PM

                  For [[+placeholder] tags (cached), sending local properties in a getChunk() call will override the values set in any setPlaceholder() call, but without changing any placeholder values set with setPlaceholder() and without altering the cached chunk.
                  It changes them, but just in the scope of processing that chunk. Once the parsing process leaves the scope of that chunk (which includes everything processed within the chunk), the placeholders set via properties are unset, and any values overwritten from the previous scope restored.
                    • 3749
                    • 24,544 Posts
                    Quote from: OpenGeek at Oct 22, 2008, 05:31 PM

                    Quote from: BobRay at Oct 22, 2008, 04:45 PM

                    Before rendering, those [[!+placeholder]] tags will be replaced with the most recent setPlaceholder() call’s content. "Most recent" can be hard to predict, but a setPlaceholder() call made just before a call to getChunk() can be counted on to apply for placeholders marked with a ! tag.
                    What if I decide to cache the snippet? Then those placeholders would never get set and since you prevented caching of the values set by those API calls into the cacheable content, they would now be empty. Another reason why ! in placeholders should be reserved for special situations where you know there will always be a placeholder being set (e.g. using [[!++site_url]] if you serve multiple domains from a single site), regardless of cacheability.

                    Ok, you have me there. That’s definitely a more serious problem. I would have guessed that a setPlaceholder() value set for a particular request would be used for any uncached placeholder during that request. Is that not possible? If it were, you could advise people to use setPlaceholder() as the default and to use properties only in rare instances and get the results you want in a more intuitive scheme, IMHO.


                    Quote from: BobRay at Oct 22, 2008, 04:45 PM

                    For [[+placeholder] tags (cached), sending local properties in a getChunk() call will override the values set in any setPlaceholder() call, but without changing any placeholder values set with setPlaceholder() and without altering the cached chunk.
                    Quote from: OpenGeek

                    It changes them, but just in the scope of processing that chunk. Once the parsing process leaves the scope of that chunk (which includes everything processed within the chunk), the placeholders set via properties are unset, and any values overwritten from the previous scope restored.

                    Ok, make that "without *permanently* changing any placeholder values . . .." wink
                      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