We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22656
    • 121 Posts
    How do I create a second context which is exactly the same as the original context (ie not duplicating all the pages from original context)

    I have a requirement to create a cloned version of an existing modx site. The site itself will only be slightly different, in particular some menu items, slightly modified template and some functionality removed. All the other pages will be exactly the same as the main website, meaning I do not want to copy them and create duplicate versions under this secondary context.

    So, I was thinking - create the second context, create my specific template for this context, and somehow pull in all the pages from the original context. How can I do this?

    Basically what I am trying to achieve is using contexts for subdomains, to end up with something like this (very similar to babel):
    mysite.com (context1)
    context2.mysite.com
    context3.mysite.com

    as I said I want the same resource tree from context1 shown accross the other contexts, however I would like to be able to make minute changes within each context, disable some elements, enable others, exclude certain resources, etc.

    Also, due to the fact these contexts will share exactly the SAME content, I will have to ensure duplicate content flag isnt raised by google. Could I just use noindex on all pages in secondary contexts, or exclude the subdomain in robots, or use the canonical tag pointing to the original website's version of the page?

    [ed. note: papachumba last edited this post 14 years, 3 months ago.]
      • 22656
      • 121 Posts
      Well, looks like its as simple as creating a new context and pointing symlinks to original context's pages. Templates can still be changed page by page which fullfils my requirements (i think)
        • 22656
        • 121 Posts
        Ok, been mulling over this one for some time...
        Basically i created a secondary context with symlinks pointing to original context. This all works fine.

        My issue is maintenance. Anytime an editor adds a resource to the primary context, the cloned context should also have the same resource's alias.

        Lets simplify:

        context1.site.com/about-us.html
        context2.site.com/about-us.html

        second "about us" is just a symlink pointing to the original about us page. They both have the same alias "about-us", they use different templates, all well and good. It's reasonably easy for me to set this up for all the existing pages, however what about new pages editors create?

        How can I ensure that if an editor creates a new resource called "about-us-more-info.html" in main context, without my involvement secondary context will produce the error message if someone tries going to this link, as there is no page with the symlink in secondary context - all these new pages will fail unless I create them in the secondary context too (manually)?

        I've been looking at babel, and I could possibly use this to ensure pages in the secondary contexts get created, however babel will only copy the content itself and won't create a symlink.

        Its almost like I need a plugin which, on every page's creation -

        • copy page alias, create resource of same alias under all subsequent contexts (use template specific to that context whilst doing so)

        • Anytime you delete the page, the clone version will be deleted from all contexts.


        After done some research on contexts, I can see their use specifically for multilanguage purposes, or for purposes where you need totally separate websites (in which case most people will probably go with separate modx installations, just in case something breaks it is localised to only one site)


          • 3749
          • 24,544 Posts
          Its almost like I need a plugin which, on every page's creation -
          copy page alias, create resource of same alias under all subsequent contexts (use template specific to that context whilst doing so)
          Anytime you delete the page, the clone version will be deleted from all contexts.

          I think that's definitely what you want -- a plugin connected to OnResourceDelete and OnDocFormSave. This is off the top of my head, but it should get you started:

          <?php
          /*CreateSymlinks Plugin */
          $docId = $resource->get('id');
          $docAlias = $resource->get('alias');
          
          /* The numbers on the right here are the respective template IDs
           * The left members should be the names of your contexts 
           */
          
          $contexts = array(
              'context1' => 3,
              'context2' => 7,
              'context3' => 9,
          );
          
          $fields = array(
             'docAlias' => $docAlias,
             'pageTitle' => $resource->get('pagetitle'), /* not sure if this is necessary */
              );
          
          switch ($modx->event->name) {
              case OnResourceDelete:
          
                  $docs = $modx->getCollection('modResource', array('alias' => $docAlias));
          
                  foreach ($docs as $doc) {
                      $doc->delete();
                  }
                  break;
          
          
              case OnDocFormSave:
                  if ($mode === modSystemEvent::MODE_NEW) {
                      foreach($contexts as $contextName => $templateId) {
                          $fields['context_key'] = $contextName;
                          $fields['template'] = $templateId;
                          $symlink = $modx->newObject('modSymlink', $fields);
                          $symlink->setContent($docId); /* not positive about this line */
                          $symlink->save();
                      }
                         
                  }
                  break;
          }



          delete() will leave the resources in the tree until you empty the trash. You can use remove() to completely trash them, but delete() is a lot safer, especially while you're developing.


          ------------------------------------------------------------------------------------------
          PLEASE, PLEASE specify the version of MODX you are using.
          MODX info for everyone: http://bobsguides.com/modx.html [ed. note: BobRay last edited this post 14 years, 4 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
            • 9102 ☆ A M B ☆
            • 318 Posts
            It's not really relevant to the discussion of how to do it, but I feel I should point out that this is probably a bad idea from an SEO perspective. Having clones of your content on different domains could lead to bad search rankings for some or all of the sites, and even possible penalties.

            Maybe that doesn't matter for this project, but I think it needs to be said.
              • 22656
              • 121 Posts
              bobray, your a star! exactly what I needed.

              freejung - many websites syndicate content for various purposes. my idea is to use modx framework for rolling out infinite versions of whitelabels of a given site. Clones as such wouldnt be available to search engines and will be used towards targeted customers, not relying on search engine results. It would serve no purpose giving google all these clones to gobble up, so:

              .htaccess

              RewriteCond %{HTTP_HOST} ^clone1\.mywebsite\.com [NC]
              RewriteCond %{HTTP_HOST} ^clone2\.mywebsite\.com [NC]
              RewriteCond %{HTTP_USER_AGENT} google|bing|slurp [NC] 
              RewriteRule .? - [G] 


              in cloned page head:

              <link href="http://www.mywebsite.com/original-version-of-page.html" rel="canonical" />
              <meta name="robots" content="noindex, nofollow" />
              

              according to some online advice, it would be beneficial to actually let google crawl these duplicate urls and just use the canonical tag to point to original page. in which case take htacess rule off i guess.
                • 9102 ☆ A M B ☆
                • 318 Posts
                Yes, canonicalization can work across domains.

                If you're not planning on ranking with the duplicate sites, that's fine.
                  • 22656
                  • 121 Posts
                  tx again bobray, i've tweaked the code for my needs and it works great, however I am getting a weird bug - when saving an existing resource, the page refreshes and presents me with "create a new resource" action ie a blank new document each time.

                  code im using for the plugin:

                  <?php
                  /*CreateSymlinks Plugin */
                  //$docId = $resource->get('id');
                  //$docAlias = $resource->get('alias');
                   
                  /* The numbers on the right here are the respective template IDs
                   * The left members should be the names of your contexts 
                   */
                   
                  $contexts = array(
                      'context1' => 13,
                      'context2' => 13,
                  );
                   
                  $fields = array(
                     'docAlias' => $docAlias,
                     'pageTitle' => $resource->get('pagetitle'),
                      );
                   
                  switch ($modx->event->name) {
                      case OnResourceDelete:
                   
                          $docs = $modx->getCollection('modResource', array('alias' => $docAlias));
                   
                          foreach ($docs as $doc) {
                              $doc->delete();
                          }
                          break;
                   
                   
                      case OnDocFormSave:
                          $e = $modx->Event;
                          $docId = $e->params['id'];
                          $docAlias = $e->params['alias'];
                          $pageTitle =  $resource->get('pagetitle');
                          $pageAlias =  $resource->get('alias');
                  
                          if ($mode === modSystemEvent::MODE_NEW) {
                              foreach($contexts as $contextName => $templateId) {
                                  $fields['context_key'] = $contextName;
                                  $fields['template'] = $templateId;
                                  $symlink = $modx->newObject('modSymlink', $fields);
                                  $symlink->setContent($docId); 
                                  $symlink->set('pagetitle', $pageTitle);
                                  $symlink->set('alias', $pageAlias);
                                  $symlink->set('published',true);
                                  $symlink->save();
                              }
                                  
                          }
                          break;
                  }

                  ?>
                    • 10208 ☆ A M B ☆
                    • 1,780 Posts
                    Maybe the icon that makes it do this after each save at the top of the resource page got clicked.

                    Just to the right of the help button, at the upper right of a resource editing page, there are three icons.

                    Hover over each for tooltip. They are "add another", "continue editing", and "close". Click "continue editing". That should fix it.

                    (Bob saved me one day with this one)
                      Frogabog- MODX Websites in Portland Oregon
                      "Do yourself a favor and get a copy of "MODX - The Official Guide" by Bob Ray. Read it.
                      Having server issues? These guys have MODX Hosting perfected - SkyToaster
                      • 22656
                      • 121 Posts
                      ah! indeed you are right, Sir. Stupidly overlooked this little detail lol.