We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 51399
    • 7 Posts
    I feel like I can't be the first person to have this slight issue, but unfortunately I can't seem to find anything on the subject, perhaps my google-fu isn't quite up to the job.

    So I'm currently developing an extra for a client using Bob Ray's MyComponent (great extra by the way, Bob) and my concern is that I am referencing resources by their IDs a lot; in links (e.g [[~1180]]) and snippets etc.

    But it occured to me, when I put this extra live on their site none of the resource IDs will match up because they have been adding more resources themselves while I've been developing this, so I wrote a quick snippet to get a resource's ID from its pagetitle and am using that instead... but that doesn't seem right to me either because then if I want to change a resources pagetitle I have to then change it in every place it is referenced.

    This is one of those weird issues where nothing is exactly wrong... it just doesn't seem right.
    Does anyone have any ideas?

    Thanks.
      • 42562
      • 1,145 Posts
      I did the same thing, wrote a snippet to get id via pagetitle - or other pattern (pagetitle suffix, template or TV- this allows for unknown resources)

      Truth is, unless Bob Ray has some info that eludes us, you will have to redesign your extra in such a way that this dependency is not necessary for the core functionality of the Extra
        TinymceWrapper: Complete back/frontend content solution.
        Harden your MODX site by passwording your three main folders: core, manager, connectors and renaming your assets (thank me later!)
        5 ways to sniff / hack your own sites; even with renamed/hidden folders, burst them all up, to see how secure you are not.
        • 30585
        • 833 Posts
        If you have a relatively small number of resources, you can use system Settings or ClientConfig to store your resource ids. You'd then reference those settings instead of resource ids.

        Consider the following setup:

        Container (1)
        -- Page One (2)
        -- Another Page (3)

        You could then create the following system settings to store those ids:

        myExtra.container_id => value = 1
        myExtra.page_one_id => value = 2
        myExtra.another_page_id => value = 3

        Linking to Page 1 would be as easy as:
         [[~[[++myExtra.page_one_id]]]]


        In a snippet:

        <?php
        $pageOne = $modx->getOption('myExtra.page_one_id');
        # do stuff with $pageOne
        
          A MODx Fanatic
          • 3749
          • 24,544 Posts
          Thanks for the kind words.

          I can think of a couple of ways to handle this. One is to write a resolver that runs at the end of the install that gets the actual IDs and does a search-and-replace operation on the links. You could make that simpler by using tags with the alias instead of an ID (assuming that you set the resource aliases when creating them):

          [[~some-alias]]


          If you put the aliases and IDs in two arrays, you can use those arrays as arguments to str_replace(). Or you can use a single array of aliases and IDs and do this:

          [Update] I realized that there's some danger if one alias is part of another alias, so I've modified the code to include the tags to avoid that.[/Update]


          $docs = array (
              '[[~alias1]]',
              '[[~alias2']],
          );
          
          $array_from_to = array();
          foreach($docs as $doc) {
              $res = $modx->getObject('modResource', array('alias' => $doc));
              $array_from_to['[[~' . $doc . ']]'] = $res->get('id');
          } 
          
          /* Now you have an array like this:
             array(
                '[[~alias1]]' => 22,
                '[[~alias2]]' => 34,
             );
          */
          
          /* Do the search and replace */
          foreach ($array_from_to as $key => $value) {
              $obj = $modx->getObject('modResource', (int) $value);
              $text = $obj->getContent();
              $text = str_replace(array_keys($array_from_to), $array_from_to, $text);
              $obj->setContent($text);
              $obj->save();
          }
          


          Another thing I've done is to use a resolver to create and set some System Settings for the page IDs (where the 'key' is the alias and the 'value' is the Resource ID). Then you can use links like this:
          [[~[[++alias]] ]]


          The down side of this second method is that it breaks if someone changes the alias unless you also change the System Setting. The first method is less confusing to people reading the source and easier to make changes to. [ed. note: BobRay last edited this post 10 years, 8 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
            • 3749
            • 24,544 Posts
            Note that I updated the code above to include the tags. I also added a cast to (int) for the getObject() call.
              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