We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 21257 MODX Staff
    • 730 Posts
    This is a modification to "Inherit Parent Template" to allow a TV to control what template new children of a document will use.

    I’ve found in the past that it would be useful to have a parent container set to use one template, and all of it’s children use another. A news section is a simple example of this - the news summary page might need a different template than the articles it contains. While this is already easy to do, I think it would be great if it were even easier. When I’m handing over control of the site or a section of a site to non-savvy users, it would be nice if they didn’t have to worry about templates. They just want to create a new document and add the content.

    If anyone’s interested in trying this, you just have to
    a) modify the "Inherit Parent Template" plugin
    b) create a TV to allow selection of the templates
    c) give it a try!

    The modified "Inherit Parent Template" doesn’t rely on this TV existing - it’s legacy behavior will work just fine by default.

    a) Here’s the updated code for "Inherit Parent Template":
    /*
     * Inherit Template from Parent
     * Written By Raymond Irving - 12 Oct 2006
     * modified July 7, 2008 by netProphET
     *
     * Controls what template will be used on a newly created document
     *
     * Default legacy behavior is for a new document to inherit it's template from it's parent.
     * Now, if a special Template Variable (TV) exists in the parent doc, it can control the template
     * that the new child will use.
     * The name of this Template Variable defaults to "ChildTemplate"; you can easily change it.
     *
     * Configuration:
     * - for help setting up the Template Variable to control template selection,
     *   see: http://modxcms.com/forums/index.php/topic,27158.msg164961.html
     * - to specify an alternate name for the Template Variable that controls template selection,
     *   enter it on the Configuration tab of this plugin
     * - check the OnDocFormPrerender event
     *
     * Version 2
     *
     *
     */
    
    global $content;
    $e = &$modx->Event;
    
    $tvname = isset($ChildTemplateTVName) ? $ChildTemplateTVName : 'ChildTemplate';
    
    switch($e->name) {
      case 'OnDocFormPrerender':
        if(($_REQUEST['pid'] > 0) && ($id == 0)) {
          $sql= "SELECT IF(tvc.value!='',tvc.value,tv.default_text) as value ";
          $sql .= "FROM " . $this->getFullTableName('site_tmplvars')." tv ";
          $sql .= "INNER JOIN " . $this->getFullTableName('site_tmplvar_templates')." tvtpl ON tvtpl.tmplvarid = tv.id ";
          $sql .= "LEFT JOIN " . $this->getFullTableName('site_tmplvar_contentvalues')." tvc ON tvc.tmplvarid=tv.id AND tvc.contentid = {$_REQUEST['pid']} ";
          $sql .= "WHERE tv.name='{$tvname}'"; //  AND tvtpl.templateid = " . $docRow['template']
          $rs= $modx->dbQuery($sql);
          $row = $modx->fetchRow($rs);
          $tvChildTemplate = $row['value'];
        }
        if(is_numeric($tvChildTemplate)) {
          $content['template'] = $tvChildTemplate;
        } elseif($parent = $modx->getPageInfo($_REQUEST['pid'],0,'template')) {
          $content['template'] = $parent['template'];
        }
        break;
    
      default:
        return;
        break;
    }
    


    Enter this on the Configuration tab, into the "Plugin configuration" field:
    &ChildTemplateTVName=Name of Template Variable to use;text;ChildTemplate
    


    b) create the Template Variable

    • Create a new Template Variable - named ChildTemplate
    • Input Type should be Dropdown List Menu
    • set Input Option Values to: @SELECT templatename, id FROM [+PREFIX+]site_templates
    • assign the new TV to any template that you want to try this out on
    • save the new TV

    c) now, to finally see this in action

    • choose a parent doc you want to try this out on, edit it
    • set the value of ChildTemplate to some other template (so you know that you’re not seeing the default behavior); Save
    • create a new document under the parent that you just edited - it should come up using the template that you chose above
      Mike Schell
      Lead Developer, MODX Cloud
      Email: [email protected]
      GitHub: https://github.com/netProphET/
      Twitter: @mkschell
      • 25663 MODX Staff
      • 12,272 Posts
      Very cool modification. Why not submit it as a version of the code after some feedback? Well done and quite useful, too. smiley
        Ryan Thrash, MODX Co-Founder
        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
        • 11975
        • 2,542 Posts
          Made with MODx : [url=http://www.copadel.com]copadel, fruits et l
          • 21257 MODX Staff
          • 730 Posts
          LOL,
          Thanks for that, heliotrope! I wondered if this existed, but after a quick scan, did not find it.
          I like that your solution makes use of the core API functions. I decided to shortcut it a bit.
          After doing this, I started wondering if a more generic plugin would be useful.. allowing for inheriting of settings other than Template, either from the parent’s settings directly or from TVs.
          Can anyone see that being useful?
            Mike Schell
            Lead Developer, MODX Cloud
            Email: [email protected]
            GitHub: https://github.com/netProphET/
            Twitter: @mkschell
            • 7231
            • 4,205 Posts
            Can anyone see that being useful?
            Yes. I sometimes alter the inherit template plugin to include document group settings or to set dynamic titles (based on parent name or date) for specific sections.
              [font=Verdana]Shane Sponagle | [wiki] Snippet Call Anatomy | MODx Developer Blog | [nettuts] Working With a Content Management Framework: MODx

              Something is happening here, but you don't know what it is.
              Do you, Mr. Jones? - [bob dylan]
              • 25663 MODX Staff
              • 12,272 Posts
              I think it would make a lot of sense to inherit document groups indeed as well. Maybe a series of checkboxes for properties to inherit would make sense. (published, doc groups, template, cacheable, searchable, etc.)
                Ryan Thrash, MODX Co-Founder
                Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
                • 5340
                • 1,624 Posts
                Who would you use it if you have 2 levels on which you want to set the template.

                Would you create a new plugin and change the default TV name?

                PS: I am not sure how plugins work

                Thx

                More on this:

                I have the following structure

                programs (template: programs-landing, set child template to programs-subject)
                subjects (template: programs-subjects, set child template to programs-inside)
                programName(template: programs-inside)
                program pages like overview, Info etc

                How can I use the plugin in this situation. It only works for the first level. For the second it doesn’t work even if I create a diffrent plugin.
                  • 21257 MODX Staff
                  • 730 Posts
                  Hi xpix,
                  I don’t think my enhancement to Inherit Parent Template is going to be too useful in your situation.
                  The purpose of the enhancement was to allow a MODx developer to set up a container so that when less advanced users create children of that container, the children would be set to the right template automatically. I did not anticipate the need to set specific templates on grandchildren etc.
                  In your scenario, it’s more complex because on second-tier documents you would somehow need to automatically set the value of the TV which controls what the child template is going to be. There are many ways you could do this, but I can’t think of anything too elegant off the top of my head. You’re really need to set up some sort of mapping, and whether you do it at the container level or in the context of templates themselves.. would be up to the developer depending on what would make the most sense for the site.
                  I have a bit of an evil scheme brewing for enhancing this whole concept, but it’s going to take a bit of time to come to fruition. I’ll take this problem into account as I’m considering "requirements".
                    Mike Schell
                    Lead Developer, MODX Cloud
                    Email: [email protected]
                    GitHub: https://github.com/netProphET/
                    Twitter: @mkschell
                    • 5340
                    • 1,624 Posts
                    Here is my non-elegant solution

                    What it does?

                    It helps the developer specify what template should the new child have. Works for how many levels you want but you need to create a diffrent plugin for each level

                    Use this plugin:
                    i harcoded the name of the TV: ChildTemplatePrograms. You can use the config solution if you want.

                    global $content;
                    $e = &$modx->Event;
                    
                    $tvname = 'ChildTemplatePrograms';
                    
                    switch($e->name) {
                      case 'OnDocFormPrerender':
                        if(($_REQUEST['pid'] > 0) && ($id == 0)) {
                          $sql= "SELECT IF(tvc.value!='',tvc.value,tv.default_text) as value ";
                          $sql .= "FROM " . $this->getFullTableName('site_tmplvars')." tv ";
                          $sql .= "INNER JOIN " . $this->getFullTableName('site_tmplvar_templates')." tvtpl ON tvtpl.tmplvarid = tv.id ";
                          $sql .= "LEFT JOIN " . $this->getFullTableName('site_tmplvar_contentvalues')." tvc ON tvc.tmplvarid=tv.id AND tvc.contentid = {$_REQUEST['pid']} ";
                          $sql .= "WHERE tv.name='{$tvname}'"; //  AND tvtpl.templateid = " . $docRow['template']
                          $rs= $modx->dbQuery($sql);
                          $row = $modx->fetchRow($rs);
                          $tvChildTemplate = $row['value'];
                        }
                        if(is_numeric($tvChildTemplate)) {
                          $content['template'] = $tvChildTemplate;
                        } elseif($parent = $modx->getPageInfo($_REQUEST['pid'],0,'template')) {
                          $content['template'] = $parent['template'];
                        }
                        break;
                    
                      default:
                        return;
                        break;
                    }


                    Create a TV called ChildTemplatePrograms:
                    Just use a simple text TV and put the ID of the template you want the child to use. You can hide this tv later from the usual users.
                    Assign the TV to the parent template. In my case programs


                    Repeat these steps for all the levels you want to specify the child template. (do not forget to change the hardcoded TV name).

                    IMPORTANT:
                    - I am looking for a way to pass TV values to plugins. If we can find a way there will be no need to have a plugin for each level.
                    - In case it does not work make sure the plugins are called in the right order(Edit Plugin Execution Order by Event). The plugin for the parent should be called first.


                    Problem:
                    It seems that it works only if you use it on one container. If you try this on 2 multiple levels containers will not work. It’s related to the order of executions for the plugin. I have to differentiate somehow between the 2 folders. I hope to fix this soon

                      • 5340
                      • 1,624 Posts
                      Here is the new version. I found a way to get the info I need in the plugin

                      http://modxcms.com/forums/index.php/topic,28018.msg170278.html#msg170278