We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 18654
    • 191 Posts
    Whats the best way to setup a url path so that I can use certain segments of the url as parameters (similar to $_GET but nicer looking).

    For example: mysite.org/chapters/uncc or mysite.org/blog/some-article

    Where "chapters" and "blog" are actual resources and "uncc" and "some-article" are parameters.

    So, for example when someone goes to mysite.org/blog/some-article - it would go to the /blog resource and then I would use "some-article" as a parameter which I would use to query an Expression Engine database for content.

    Ideally, for chapters, I would like to remove "chapters" from the url and use mysite.org/uncc, mysite.org/appstate, etc.

    The reason I am using a second CMS for blogs / chapters is because we will have a large number of blogs / chapters and I don’t want the resource tree getting bogged down and making the whole manager run slow.

    Any thoughts?
      God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
      • 33968
      • 863 Posts
      Disclaimer: anything I say below is completely untested and I’m no expert on htaccess or regular expressions grin

      This is what came to mind for me - there might be (and probably is) a better way!
      I think you’ll need to dig into your .htaccess file and use some regex to split up your url correctly.

      Try out the following amendment to your existing .htaccess file:
      # The Friendly URLs part
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^blog/(\w+)/?$ blog?param=$1 [QSA]
      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
      

      The 3rd line is what I’ve inserted.

      Basically, mysite.org/blog/some-article becomes:
      mysite.org/blog?param=some-article

      On your ’blog’ page, you’ll have a snippet with $_SERVER[’REQUEST_URI’] to grab the url as the user sees it, then just split off the article name from the end. Actually I don’t think ’?param=$1’ is necessary so you might be able to omit that. But you get the general idea?

      If that didn’t work, here’s a great article on .htaccess I found recently!
        • 18654
        • 191 Posts
        Quote from: lucas at May 21, 2011, 12:50 PM

        Try out the following amendment to your existing .htaccess file:
        # The Friendly URLs part
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^blog/(\w+)/?$ blog?param=$1 [QSA]
        RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
        


        Great idea! I’m getting a server error right now when I add that line, but I’m working on tweaking it to make it work.
          God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
          • 18654
          • 191 Posts
          Ok, this works:

          # Send all blog pages requests to /blog
          RewriteRule ^blog/(.*)$ index.php?q=blog&param=$1 [L,QSA]
          
          # The Friendly URLs part
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
          


          and this works:

          # Send all blog pages requests to /blog
          RewriteRule ^blog/(.*)$ /blogs&param=$1 [L,QSA]
          
          # The Friendly URLs part
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
          


          but this doesn’t work:
          # Send all blog pages requests to /blog
          RewriteRule ^blog/(.*)$ /blog&param=$1 [L,QSA]
          
          # The Friendly URLs part
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
          


          It seems like rewriting blog to blog?whatever doesn’t work but blog to somethingbesidesblog?whatever does work.


            God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
            • 33968
            • 863 Posts
            I tried this out this morning:
            # Send all blog pages requests to /blog
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^blog/(.*)/?$ index.php?q=blog [L,QSA]
            
            # The Friendly URLs part
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
            


            I had to repeat ’RewriteCond’ as it was affecting my css paths too. Would be very happy if anyone could shed some light on the best way to handle this. However, the above seems to be working fine smiley

            Note also there is no need for ’&param=$1’ as the page url remains unchanged; we can easily grab the last url segment / article name using a snippet on the ’/blog’ page:
            <?php
            $output = '';
            
            $url = $_SERVER['REQUEST_URI'];  
            $segments = explode('/', $url);
            $output = $segments[count($segments)-1];
            
            return $output;
            

            There you have your article title to build your db query for EE. Be sure to sanitise thoroughly and trim off anything you don’t need for your query.
            Result: no messy url params and completely SEO friendly. Nice!

            ***
            ps. Seeing as /blog/anything-and-everything will now be rewritten to ’/blog’, you’ll need to look into a way to return a 404 if someone arrives on a bad link
              • 18654
              • 191 Posts
              I’m currently working on a slightly different approach that allows me a bit more flexibility (still a work in progress). Additionally, my production server and local server required different .htaccess code to run correctly using the previous approach (sure I could have worked this out eventually but ...). Here’s my current approach.

              1. Hook into onHandleRequest event (the entire $_REQUEST array is sanitized just before this event fires).
              2. Some variation of the code below - eventually I will have an array of rewrite paths for any item that could potentially have alot of records (events, news, etc). Plugin code:

              <?php
              $rAlias = $modx->getOption('request_param_alias', null, 'q');
              $urlPath = $_REQUEST[$rAlias];
              $urlSegments = explode('/', $urlPath);
              
              if ($urlSegments[0] == 'blog' && $urlSegments[1] = 'post') {
              	$_REQUEST[$rAlias] = 'blog/post';
              	$_REQUEST['qstring'] = str_replace('blog/post', '', $urlPath);
              }
              


              As you mentioned above, I could remove the ’qstring’ variable and parse the string once it gets to the resource, but for now I’m leaning towards keeping everything in one place.
                God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
                • 18654
                • 191 Posts
                Here is the current iteration of my plugin - seems to be working and is easily configurable.

                <?php
                $rAlias = $modx->getOption('request_param_alias', null, 'q');
                $urlSegments = explode('/', $_REQUEST[$rAlias]);
                $urlPath = trim($urlSegments[0] . '/' . $urlSegments[1], '/');
                $rewritePaths = array(
                	'blog/post',
                	'blog/archives',
                	'blog/category',
                	'blog/tag',
                	'news-events/media-coverage',
                	'news-events/media-coverage/archive',
                	'news-events/newsletters',
                	'news-events/newsletters/archive',
                	'partners'
                );
                
                if(in_array($urlPath, $rewritePaths)) {
                	$_REQUEST[$rAlias] = $urlPath;
                	$_REQUEST['qstring'] = str_replace($urlPath, '', $_REQUEST[$rAlias]);
                }
                


                EDIT: Found some bugs with the above code. The following seems to fix these issues and is a bit more robust:

                <?php
                $rAlias = $modx->getOption('request_param_alias', null, 'q');
                $urlSegments = explode('/', $_REQUEST[$rAlias]);
                $urlPath = trim($urlSegments[0] . '/' . $urlSegments[1] . '/' . $urlSegments[2], '/');
                $rewritePatterns = array(
                	'/^blog\/post/' => 'blog/post',
                	'/^blog\/archives/' => 'blog/archives',
                	'/^blog\/category/' => 'blog/category',
                	'/^blog\/tag/' => 'blog/tag',
                	'/^news-events\/media-coverage/' => 'news-events/media-coverage',
                	'/^news-events\/media-coverage\/archive/' => 'news-events/media-coverage/archive',
                	'/^news-events\/newsletters/' => 'news-events/newsletters',
                	'/^news-events\/newsletters/archive/' => 'news-events/newsletters/archive',
                	'/^partners\//' => 'partners/'
                );
                
                foreach ($rewritePatterns as $pattern => $replacement) {
                	if (preg_match($pattern, $urlPath)){
                		$_REQUEST[$rAlias] = $replacement;
                		$_REQUEST['qstring'] = str_replace($replacement, '', $_REQUEST[$rAlias]);
                	}
                }
                

                  God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
                  • 33968
                  • 863 Posts
                  Nice work! It hadn’t occurred to me to go with a plugin. It certainly seems a lot more flexible. From the looks of it you don’t even need to touch .htaccess for that to work, is that right?
                    • 18654
                    • 191 Posts
                    Quote from: lucas at May 23, 2011, 02:05 AM

                    From the looks of it you don’t even need to touch .htaccess for that to work, is that right?

                    Correct - no need to touch .htaccess.
                      God does not save those who are only imaginary sinners. Be a sinner, and let your sins be strong, but let your trust in Christ be stronger, and rejoice in Christ who is the victor over sin, death, and the world.
                      • 22303 MODX Staff
                      • 10,725 Posts
                      FWIW, I would use this OnPageNotFound to handle your custom routing. That way the MODX routing still works and your custom handling occurs after it fails. Otherwise, you might interfere with the default MODX routing unintentionally.