We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32046
    • 75 Posts
    Hi
    I have in my .htaccess the following:
    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    RewriteRule ^(.*)$ /mysite/index.php?q=$1 [L,QSA]
    

    This RewriteRule works fine for ’mysite’ on my localhost development machine. Standard modX .htaccess.

    Now, I have hundreds of products in a database, and would like to serve any one of them up from the one page mysite/product (resource with alias "product") but with unique urls for SEO (ie. not mysite/product?pid=77. So when a user enters mysite/productId/77 (which is a non-existent page) they would be redirected to mysite/product with a GET var of pid=77. ie. Google would see this as mysite/productId/77. I would then use a snippet to retrieve the info relating to product 77 from the database and display it on the page.

    So I added a new rule to the .htaccess which now reads:
    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # Additional rewrite to handle listings redirect
    RewriteRule ^(.*)/productId/([0-9]+)$ /mysite/index.php?q=product&pid=$2 [L,QSA]
    
    # Original modx rewrite rule
    RewriteRule ^(.*)$ /mysite/index.php?q=$1 [L,QSA]
    


    Argh!, it breaks!
    There must be a conflict or something here - Both rules work fine, but ONLY if one is commented out, ie, the first rewrite rule works fine and redirects mysite/productId/77 to mysite/product (with a GET var of pid=77) if the second rule is commented out. If I don’t comment the second rule out I get a Internal Server Error 500.
    The same applies for the url mysite/contactUs, it’s fine ONLY IF I comment out the first rule. This is driving me nuts!

    I need both rules! Can any of you mod_rewrite gurus see what I’m doing wrong here?
    Thanks

      • 4310
      • 2,310 Posts
      Usually I’d use :
      RewriteEngine On
      RewriteBase /mysite/
      
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      
      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
        • 9102 ☆ A M B ☆
        • 318 Posts
        The trouble is you’re trying to rewrite both to the "real" URL. The first rule should point to the "friendly" URL created by the second rule, like this:

        # Additional rewrite to handle listings redirect
        RewriteRule ^(.*)/productId/([0-9]+)$ /product?pid=$2 [L,QSA]
        
        # Original modx rewrite rule
        RewriteRule ^(.*)$ /mysite/index.php?q=$1 [L,QSA]
        


        (assuming your suffix for HTML resources is blank, otherwise the last part of the first rule could be product.html?pid=$2 or whatever your suffix is)

        This is essentially the same problem as SEO-friendly pagination with getPage, which I talked about here: http://modxcms.com/forums/index.php/topic,56621.0.html
          • 9102 ☆ A M B ☆
          • 318 Posts
          Also, I’m not sure I understand what you’re trying to do with directory structure. Your second rewrite does not create friendly URLs of the form /mysite/friendly-url but rather of the form /friendly-url which points to index.php in the /mysite/ subdirectory. Not sure why you would do this, things would be more straightforward if you just put index.php in root and then use:
          # Additional rewrite to handle listings redirect
          RewriteRule ^productId/([0-9]+)$ /product?pid=$1 [L,QSA]
          
          # Original modx rewrite rule
          RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
          

          Then link to individual products with a URL like /productId/77 and avoid using the /mysite/ directory altogether -- but you should be able to get it to work either way.
            • 32046
            • 75 Posts
            Thanks guys, I’ll give that a try.
            The reason I use
            RewriteRule ^(.*)$ /mysite/index.php?q=$1 [L,QSA]
            is that I have dozens of websites on my development box (linux) under /home/murray/public_html/site1/ and .../site2/ etc. My localhost is set to /home/murray/public_html/ so when I test a site I enter http://localhost/site1 to bring up the homepage of site1.
            I know I can set this up using virtual alias’s somehow but never got around to working that out - this way just seems easy wink. When I deploy I take the mysite/ out of the above .htaccess. Does that make sense?
              • 9102 ☆ A M B ☆
              • 318 Posts
              Sure, makes total sense. However, if there’s still a problem with these rules, it might be worth setting up a virtual alias or whatever it takes to mirror the production environment. You should be able to get this to work using the subdirectory, but you’ll have to be very careful about what the incoming request string is supposed to look like.
                • 32046
                • 75 Posts
                Thanks esnyder,
                I set it up exactly as in post #3 and still have the internal server error. So while your suggestions have not exactly solved my issue I have certainly learned a good deal about rewrites from what you’ve written. Stuff I should have understood a long time ago, so thank you for that.
                I think I will try setting up apache virtual hosts to better mirror the production enviro, and then I’ll try tackling this again.
                  • 32046
                  • 75 Posts
                  OK, I have virtual hosts set up so have done away with the /mysite necessity and am back to the standard modX rewriteRule. The site is now accessed by browsing to http://dev.mysite. The entire site works 100% well with this new setup.
                  I’ve also added the suggested additional rewriteRule (thanks esnyder)
                  RewriteRule ^productId/([0-9]+)$ /product?pid=$1 [L,QSA]
                  RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
                  

                  When I browse to dev.mysite/productId/77 the result is Internal Server Error. The same result for any page I browse to, so the new RewriteRule is breaking the site. Esnyder, I think I understand the logic of rewriting the first rule to point to the URL created by the second rule, but obviously something else is wrong, the two rules appear to conflict?
                    • 32046
                    • 75 Posts
                    Entire .htaccess file is:
                    Options +FollowSymlinks
                    RewriteEngine On
                    RewriteBase /
                    
                    # Fix Apache internal dummy connections from breaking [(site_url)] cache
                    RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC]
                    RewriteRule .* - [F,L]
                    
                    # Exclude /assets and /manager directories and images from rewrite rules
                    RewriteRule ^(manager|assets)/*$ - [L]
                    RewriteRule \.(jpg|jpeg|png|gif|ico)$ - [L]
                    
                    # For Friendly URLs
                    RewriteCond %{REQUEST_FILENAME} !-f
                    RewriteCond %{REQUEST_FILENAME} !-d
                    
                    RewriteRule ^productId/([0-9]+)$ /product?pid=$1 [L,QSA]
                    RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
                    
                    
                      • 36764 ☆ A M B ☆
                      • 45 Posts
                      Evengard aka Eiventeleiron Reply #10, 15 years, 4 months ago
                      I would recommend you not to use the custom rewrite rules, but instead use my approach:
                      http://modxcms.com/forums/index.php/topic,64718.msg368719.html#msg368719
                      This plugin will help to recognize URLs such as
                      http://yourdomain.com/products.html/productId-256