We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 20364
    • 89 Posts
    We have a site with multiple Contexts. Each context has a Container called "Modules", which is where we hold some common pieces of content that other pages can include. We are using Resource List TV to allow the user to choose which document inside "Modules" they want to use.

    The way this is working is a Snippet which does a getObject sort of like this:

    $result = $modx->getObject('modDocument',array('pagetitle'=> 'Modules', 'context_key' => $modx->context->key));
    return $result->get('id');
    

    Problem is, $modx->context->key isn’t set from the backend perspective when editing a document. Since this snippet is running outside of the Context (via @EVAL), it doesn’t know which Context you’re in, so it returns 0.

    Is there a way for us to tweak this, or a whole different way for the TV to know which ’Modules’ folder to grab depending on which Context the document you’re editing belongs to?

    Thanks in advance!!!!
      • 3749
      • 24,544 Posts
      You’re always in the ’mgr’ context in the Manager. You can get the context of the current resource with $modx->resource->get(’context_key’) in the front end.

      I’m not clear at all on what you’re doing because there’s no way to run a snippet while editing a resource in the back end.

      Is it a plugin, instead?

        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
        • 20364
        • 89 Posts
        Hey Bob. Like your book cover? wink

        Anyway, sorry, I may not have explained it well..

        I have a TV using "Resource List" as the Input Type.

        Option values is
        @EVAL return $modx->runSnippet('findBy', array('param' => 'alias', 'value' => 'Modules', 'return' => 'id'));

        findby is returning the ID of the resource named "Modules" in this case.

        My problem is, there is a Resource container called "Modules" for each Context. So, when you use this TV, the Resource List grabs the first Modules ID it finds in the database, not necessarily the one that pertains to the Context of the Resource you’re edting.

        Maybe this will help:

        Let’s say this is my tree:

        Context: chicago
        -- Resource: Chicago Home (14)
        -- Container: Modules (15)
        ---- Resource: Photo Rotator (16)
        Context: newyork
        -- Contaienr: New York Home (19)
        -- Container: Modules (20)
        ---- Resource: Specials (21)

        When I edit "Chicago Home", it uses the TV called "module" which has the EVAL statement I posted above. It queries the db, finds "Modules" and returns 16 just like it should, so the Resource List shows (in this case) "Photo Rotator"

        However, when I edit "New York Home" which also uses "module, it queries, but since it’s searching global and not context-specific, it also returns 16, since that is the first mention of "Modules" in the database.

        I need a way for it to return 20.. so that when using the "module" TV in "New York Home", it returns the Resource List for the Module container in that Context.

        Hope that makes more sense smiley
          • 3749
          • 24,544 Posts
          The only thing I can think of is to just use the ID of the parent instead of the @EVAL.

          I think you can use @INHERIT for the input option values field of all children (but not the parents) so they’ll show the correct choices.
            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
            • 20364
            • 89 Posts
            That won’t work because we don’t know the parent ID, because it’s obviously different between each context. That’s the whole issue :/
              • 3749
              • 24,544 Posts
              I’m afraid I’m not following you. If the resources you want to show are children of the modules container, in your example the parent ID would be 15 for one context and 20 for the other. You’d have to set it manually for the top-level resources, but all their children should inherit it. You could also write a plugin to set the TV’s Input Options Value based on the name of its context. Or, you could make the parent ID a context setting and look it up with getOption() in the plugin.
                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
                • 20364
                • 89 Posts
                I think the part we are missing each other on is that this is for the Resource List in a TV. It can’t be set manually for each Context, as it can only be set once for the TV that is then being used across multiple Resources.

                Your second suggestion about creating a Snippet that grabs a value based on the Context is exactly what I did. The problem is, when you go to edit Document 15 (in the example), the TV gets processed, the Snippet gets executed, but it doesn’t know which value to grab, because you aren’t actually in a Context. You’re still in ’mgr’. So it always returns 0.
                  • 3749
                  • 24,544 Posts
                  Good point. It’s tricky, but I think it may be possible. The current resource will be available as $resource in a plugin tied to OnDocFormPrerender. The ID of the context of the resource will be available with $resource->get(’context’); Once you know the context, you can select the Parent ID and save it as a session variable ($_SESSION[’parentId’]). Your findBy snippet can then return the value of the $_SESSION variable. I think you could skip the snippet and use:

                  @EVAL return $_SESSION['parentId'];


                  In fact, you might be able to put the whole thing in the @EVAL statement, but I’m not sure what you would use to get the resource. I don’t know what information about the current resource is available at that point. It might be possible to use $scriptProperties[’id’] and get the resource with:

                  $resource = $modx->getObject('modResource',$scriptProperties['id'])


                  Another way to go, though a bit unorthodox, might be to get the TV object itself in the plugin, where you definitely have the $resource object, and set the ’parent’ input_options member on each call. That would look something like this:

                  <?php
                  $tvId = 12; /* or whatever */
                  
                  $tv = $modx->getObject('modTemplateVar', $tvId);
                  
                  $inputOptions = $tv->get('input_options');
                  
                  /* figure out $parentId from the resource's context ID here */
                  
                  $inputOptions['parents'] = (string) $parentId;
                  $tv->set('input_options',$inputOptions);
                  $tv->save();
                  


                  It’s fairly inefficient since you’d be rewriting the whole TV on every resource edit, but I think it would work.

                  A third option would be to use a separate TV for the parentId and set it in a plugin tied to OnBeforeDocFormSave. Then check that TV in your snippet. It would only work when updating existing docs, not when they are being created, though.
                    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
                    • 20364
                    • 89 Posts
                    Awesome. A Plugin is definitely going to be the way to go.

                    I tested, and setting a SESSION variable tied to OnDocFormPrerender should work. The only challenge now is figuring out which Context you are creating the Resource in.
                    $resource->get('context')

                    returns
                    Fatal error: Call to a member function get() on a non-object

                    However, in the source I see this:
                    <script type="text/javascript"> 
                    // <![CDATA[
                    MODx.config.publish_document = "1";
                    MODx.onDocFormRender = "";
                    MODx.ctx = "chicago";
                    Ext.onReady(function() {
                        MODx.load({
                            xtype: "modx-page-resource-create"
                            ,record: {"template":3,"content_type":1,"class_key":"modDocument","context_key":"chicago","parent":"9","richtext":"1","hidemenu":"0","published":"","searchable":"1","cacheable":"1","parent_pagetitle":"Extras"}
                            ,access_permissions: "1"
                            ,publish_document: "1"
                            ,canSave: "1"
                        });
                    });
                    // ]]>
                    </script> 

                    So, clearly the context key is available somehow, which is really all I need.

                    Any idea how to grab that?
                      • 3749
                      • 24,544 Posts
                      My bad. $resource is only available when updating existing documents. For new docs (and existing ones), $id is available so you can do $modx->getObject(’modResource’, $id). We might be back to square one, however, because the context field may not be set at that point.

                      You may be able to use Ultimate parent or $modx->getParentIds($id) to figure it out.

                      As a last resort, OnDocFormRender fires after the form has been loaded in memory but before it is displayed so you might be able to do some ExtJS voodoo at that point.

                      As far as grabbing context_key, I’m afraid I don’t know.
                        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