We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • Here's what I want to do: set the template for a new resource based on the parent resource. Not necessarily the template that is *used* by the parent resource (not a simple 'inherit template' concept), but a template that may optionally be specified by the parent template. For example, I want all children of the resource "Meetings" to use the Meetings template (even though the Meetings resource itself does not).

    I know that Form Customization sets allow me to do this with constraints. I can explicitly create an FC set that sets the template to "Meetings" when the parent resource is "Meetings".

    The problem is, I don't want to have to explicitly set up a new FC set each time this situation arises. Way too much administrative overhead, man.

    What I'd like to do is have a TV called "childTemplate" attached to my templates, so that a user can specify that all children of the current resource should use template X.

    So my thought was to write a Plugin that would do the following:

    • fire either on 'OnDocFormPreRender' or 'OnDocFormRender' (I'm not sure which is appropriate)
    • (for "new" resources only) determine the parent resource, and check to see whether a childTemplate was specified there
    • if a childTemplate was specified in the parent, set that as the template for the new resource.

    The first problem I ran into is that $resource is null for new resources when the 'OnDocFormPrerender' and 'OnDocFormRender' events fire.

    (Shaun says this is not the case as of Revo 2.2, which would change things considerably).

    I was able to figure out the parent by using $_GET['parent'] instead of $resource->get('parent').
    However, I am not able to use $resource->set('template', $tpl), because, again, the resource is null.

    So that's where I'm at with my original question, which is "how would I write a plugin to set the template for a new resource?"

    However, after thinking all of this through a bit more, I'm wondering if a different approach would be better. Perhaps instead of writing the plugin described above, I should instead write one that

    • fires on 'OnDocFormSave',
    • sees if "childTemplate" was modified (so we're talking about a user editing the parent resource here)
    • dynamically creates an FC set if necessary

    In other words, specifying a template in "childTemplate" would dynamically create an FC set with the appropriate parent constraint.

    Is that an insane and convoluted thought? Is it even doable?
      • 3749
      • 24,544 Posts
      I think you're on the right track. OnBeforeDocFormSave seems like the place to do it (though OnDocFormSave would work too if you re-save the resource). I don't see the need for any FC rules.

      Something like this should do it:

      <?php
      /* Connect to OnBeforeDocFormSave */
      
      /* Leave this test out of you want to autoupdate when the TV changes in the parent */
      if ($mode === modSystemEvent::MODE_NEW) {  
          $parentObj = $resource->getOne('Parent');
        
           if ($parentObj) {
                 $childTemplate = $parentObj->getTVValue('childTemplate');
      
                  if ($childTemplate) {
                          $resource->set('template', $childTemplate);
                  }
           }
      }

        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
      • Quote from: BobRay at Sep 08, 2011, 06:13 PM
        I think you're on the right track. OnBeforeDocFormSave seems like the place to do it (though OnDocFormSave would work too if you re-save the resource). I don't see the need for any FC rules.

        That would work if what I wanted to do was just control how the template was set when the user saved the resource. But I want to force the use of said template when the user initially edits the new resource.

        So I either need to A) find a way to force the template onto the new resource during OnDocFormPrerender or OnDocFormRender, or B) rely on FC rules (which I may or may not be able to create dynamically with an entirely different plugin).

        Does that make sense?
          • 3749
          • 24,544 Posts
          It does, but the code I suggested will simply ignore the user's input and use the correct template. Wouldn't that be good enough? You could hide the template field with Form Customization.
            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
          • I just figured out a solution to this that meets my requirements (shows the template I want upon creating a new resource):

            if ($mode == 'new') {

            $_REQUEST['template'] = 13;

            }

            Adding a 'template' specification into the REQUEST array upon DocFormPrerender or DocFormRender gets it to render the resource form with the correct template.

              • 36932
              • 39 Posts
              Maybe a little late, but:
              I looked for this for a long time and thanks to your helpful discussion here, I was able to make a working plugin for this purpose:

              https://gist.github.com/1474540

              Pretty short, but already enough to set the default template when creating a ressource to a TV of the parent node.

              I'm planning to extend this a little when there's some more time, e.g. recursive searching for parents that define the TV and support for options.
              Any suggestions on this are appreciated.
                • 12066
                • 48 Posts
                Hi,

                found this thread, so I thought it would be the best place for my question as well.
                I want to set the parent property on 'OnDocFormRender' but I can't figure out how to do that.

                My approach is based on @boundaryfunctions:
                $props = array(
                  'template'  => $modx->getOption('A system setting storing the template ID'),
                  'parent'    => $modx->getOption('A system setting storing the parent ID'),
                );
                $modx->controller->setProperties($props);
                


                That's not working as I expected.

                When looking through the controller classes in manager/controllers/default/resource/ I came up with another approach:

                $placeholders['parent'] = (int) INT;
                $placeholders['parentname'] = (string) STRING;
                

                OR
                $scriptProperties['parent'] = (int) INT;
                $scriptProperties['parentname'] = (string) STRING;
                


                What am I missing? Thanks for any help.
                  • 12066
                  • 48 Posts
                  Hi @BobRay,

                  I received an email that you responded to my comment, but I don't see it here. Did you remove it?
                  I should mention that it was for mgr context, not for web...

                  Thanks
                    • 3749
                    • 24,544 Posts
                    Yes, I removed it because I realized that I misread the event name and my reply didn't make any sense.

                    How about using Form Customization to set the default parent and template IDs?
                      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
                      • 12066
                      • 48 Posts
                      Yeah, FC would work. Though I want to make it work with transport packages and I have absolutely no clue how to get this done via build/resolvers or what's responsible for this...

                      Is 'MyComponent' capable of this task or do you have any knowledge on bringing this to package level?