We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 12410
    • 353 Posts
    Hi,
    Can modx do anything like this: http://expressionengine.com/user_guide/templates/globals/url_segments.html

    ie url www.hello.com/animals/dogs

    if segment 1=animals
    show this code
    else
    show this other code
    close if



    Any help appreciated

    Thanks
      • 33968
      • 863 Posts
      You could write a fairly simple snippet to do this, but there might be an easier way using Output Modifiers and the UltimateParent snippet...

      Assuming you use Revolution:
      [[UltimateParent:is=`X`:then=`[[$chunk1]]`:else=`[[$chunk2]]`? &topLevel=`2`]]
      

      Where ’X’ is the id of your ’animals’ resource.
        • 12410
        • 353 Posts
        Thanks for the direction - I will look into it. Is there any syntax that represents url segments in modx revo

        eg
        http://www.mysite.com/animals/dogs/labrador

        [[++site_url]][[++segment_1]]/[[++segment_2]]/[[++segment_3]] ?

        From Googling I saw this code
        <?php
        
        
        $uri = $_SERVER['REQUEST_URI'];
        $segment = explode("/", $uri);
        $uri_3 = $segment[3];
        echo '$segment[3]'; //is this syntax correct?
        ?>


        ...but my PHP isnt great sad

        if anyone could write a snippet called [[segment_1]] to isolate the 1st url segment then I could do the same for segment_2 to segment_5 it would be fantastic. Any help appreciated on how to modify the above. I think a lot of people may find this useful.

        Thanks

          • 33968
          • 863 Posts
          Yuh, do ExpressionEngine urls really look like that? What’s with the index.php as a folder:
          http://example.com/index.php/products/shirts/
          


          As my Saturday morning present to you, I’ve coded up ’urlSegment’ smiley

          Call it like this:

          [[!urlSegment? &segment=`X`]]
          Where ’X’ is the position of the segment you want to grab. Defaults to the first segment.

          eg: http://www.example.com/animals/dogs/alsatian

          To grab ’dogs’: [[!getSegment? &segment=`2`]]
          To grab ’alsatian: [[!getSegment? &segment=`3`]]

          Simple stuff.

          Snippet code:
          <?php
            $output = '';
            $segment = $modx->getOption('segment',$scriptProperties,'1');
          
            $url  = $_SERVER['REQUEST_URI'];
            $path = parse_url($url);
            
            $segments = explode('/', $path['path']);
            
            if ($segments[$segment]) {
              $output = $segments[$segment];
            } else {
              $output = 'Segment ' . $segment . ' does not exist!';
            } 
            
            return $output;
          


          This is just an example but if it’s the code could easily be extended to output each segment to a placeholder, something like [[+segment1]], [[+segment2]], [[+segmentLast]] etc.
            • 12410
            • 353 Posts
            You’re a star! Thanks! You’ve made my Saturday! YAY
              • 33968
              • 863 Posts
              Glad to help! And here’s an improvement:

              Call [[!getUrlSegments]] in your document, then you will have the following placeholders available to do as you wish:

              [[+segment1]] = animals
              [[+segment2]] = dogs
              [[+segment3]] = alsatian

              and...

              [[+segmentLast]] = alsatian

              <?php
              $output = '';
              
                $url  = $_SERVER['REQUEST_URI'];
                $path = parse_url($url);
                
                $segments = explode('/', $path['path']);
               
                foreach ($segments as $s => $segment) {
                  if ($s > 0) {
                    $output .= $modx->setPlaceholder('segment'.$s, $segment);
                  }
                  if ($s == count($segments) - 1) {
                    $output .= $modx->setPlaceholder('segmentLast', $segment);
                  }
                }          
                   
              return $output;
              
                • 18373 ☆ A M B ☆
                • 3,141 Posts
                Don’t forget to also uncache the placeholders there - the parser first replaces the cached items with their (cached!!!!!) values, and only then executes the uncached snippets et al.

                So:
                [[!+segment1]] = animals
                [[!+segment2]] = dogs
                [[!+segment3]] = alsatian
                [[!+segmentLast]] = alsatian
                  Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                  Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
                  • 33968
                  • 863 Posts
                  @Mark H.: I’m not sure about that... seeing as the only time caching would be an issue is if a parent alias (or ’segment’ in this case) was changed. In this case, the url of the current document changes so wouldn’t the page be rendered again from scratch rather than from the cache? Seems to work that way when I tested it.

                  However I put this snippet together quickly and now something has me confused.

                  Calling the snippet uncached [[!...]] with placeholders cached [[+...]] works fine.
                  But I’d always rather have everything cached if possible. Calling the snippet cached [[...]] works first time, but subsequent loads from the cache render the placeholders empty. I don’t know a lot about caching in Revo but I can’t get my head around that. huh
                    • 18373 ☆ A M B ☆
                    • 3,141 Posts
                    The way the parser works is that it sort of indexes the tags (elements and placeholders) it finds, and goes through them from the deepest nested one, and back up in the chain. Per "level" first the cached ones, and only then the uncached.

                    You are right that it wouldn’t be changing here unless the link changes, but the parse order is important, and complex at times. tongue

                    If you’re calling them both cached you’d have to make sure the snippet is called before the placeholders...
                      Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                      Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
                      • 33968
                      • 863 Posts
                      Thanks Mark - I’ve since dug a bit deeper into how Revo handles caching and found the same issue posted in bug reports. Calling both the snippet and placeholders cached on the same page just does not work beyond the first load. But Jason has provided a great explanation as to why this happens... it is in fact by design. Duh!

                      Call me obsessed, but I’m always wondering if there’s a way to save that 0.004 seconds or so when a snippet doesn’t need to be cached wink