We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    With SEO friendly URLs enabled, MODx gets a request like www.mydomain.com/path/doc and then "path/doc" gets resolved so that the MODx page with the alias "doc" within the "path" folder would be displayed. Fine. If I try to navigate to a URL like www.mydomain.com/path/doc/does_not_exist (where there isn’t a page with that alias), then I end up being redirected to the 404 page.

    What if I want the path/doc page to grab the "does_not_exist" part of the URL and use it in a custom database query?

    I’m trying to simplify my question so it’s clear, but here’s some more info to clarify what I’m trying to do:
    I have some custom tables in my database that I’d like MODx to read from. I can use a @SELECT binding or a Snippet to read information from these tables and display it to the user, but right now I’m limited to hard-coding a static query each time I want to display information. I’m hoping I can use the URL segments to dynamically generate those queries so I can display the information I want, i.e. path/doc/something would ultimately end up as a SQL query like
    SELECT * FROM my_custom_table WHERE id='something';

    If there are no search results, then it could roll over to the 404 page as per usual.

    A lot of frameworks have something like path/doc/123 where "123" is the unique database id.... that’s really what I’m hoping for, and again the only reason I want that kind of access is so that I can *easily* get to the data in those custom tables.

    Can anyone point me in the right direction?

      • 22303 MODX Staff
      • 10,725 Posts
      You could write a custom plugin and attach to OnPageNotFound event that will take the $_GET[’q’] value and resolve to the actual page you want to break the path into variables to use in a script there. IOW, just convert the path parts to query string variables to send to your custom controller page. However, this will not help you generate those URLs.

      The other option is to author custom rewrite rules that can break the request down the same way the plugin would, though this still would not give you the ability to generate the URLs the way your controller expects them. You would need a custom snippet to generate those URLs in either case.
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Thanks! Yeah, I’m not sure about a clean way of generating the URLs... if they are tied directly back to a key in my custom database table, I can figure out ways to read them, but I’ll have to create modified versions of WayFinder or Ditto to list which "pages" are available in that custom table... but since this is a niche use, I think this is a perfectly viable solution.

        Does the $_GET[’q’] method grab the url, e.g. /some/stuff/here? Typically, it’s grabbing arguments after the "?", like this: mydomain.com?var=val&var2=val2 -- I guess I’m just confirming that actual url is available to the $_GET method. Is this because of the .htaccess file and how it reconstructs the url? Is that what determines what is considered an argument?
          • 22303 MODX Staff
          • 10,725 Posts
          Correct, your rewrite rules would be responsible for breaking the segments down and sending them along as query string parameters which you can read from the $_GET.
            • 7231
            • 4,205 Posts
            There was tutorial posted a while back on how to use ajaxsearch on the error page to generate a list of pages based on the friendly path information. And Ditto with some filters can output a list of documents with either title or alias containing the path.
              [font=Verdana]Shane Sponagle | [wiki] Snippet Call Anatomy | MODx Developer Blog | [nettuts] Working With a Content Management Framework: MODx

              Something is happening here, but you don't know what it is.
              Do you, Mr. Jones? - [bob dylan]
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              Ok, cool. I kinda thought that the .htaccess file had a hand in determining what constitutes a "url" and what constitutes a "query"... I know in Perl Catalyst, there are different methods for grabbing the url vs. grabbing what comes after the "?".

              Tapping into this functionality might be just the thing I need to bridge between MODx and Code Igniter, for example... or for any other framework / custom database queries.

              Thanks for all the help. If you find the links to those tutorials, I’d love to see them. I might browse through Ditto’s source code, too.

                • 9207 ☆ A M B ☆
                • 2,475 Posts
                Ok, I’m starting to work on this, so I thought I’d share my progress. I’ve got a basic Plugin that runs on the event "OnPageNotFound", and right now, I’m just echoing the query string:

                echo $_GET['q'];


                But what happens is that the query string is printed up at the top of the page (good!), but then the regular 404 page follows underneath it (bad).

                The solution: use the "exit" statement:
                echo $_GET['q'];
                exit;


                Then my query string prints all by itself. Is this the right way to do this? Is there a better way? Ultimately I’ll have an if statement that can determine whether the query string is relevant as an id to my custom database table, and if it is, I’ll have some good page generation code before the exit statement, but if not, I’ll forgo the exit statement altogether.
                  • 22303 MODX Staff
                  • 10,725 Posts
                  All that you are trying to do can be accomplished by using snippets on pages and customizing rewrite rules for your specific logic. All of this other stuff is IMO totally unnecessary and will make it harder to migrate forward with MODx as it improves/changes.
                    • 9207 ☆ A M B ☆
                    • 2,475 Posts
                    Thanks OG... I don’t want to paint myself in a corner here. I’m not the smartest branch on the tree here, so for posterity, can you outline the exact steps that I could take to make this work? I don’t think I’m following what you had in mind... my Plugin is grabbing the query string (which I can use to lookup records in my custom database table)... something like this in my Plugin (this is for my "books" example, assuming mydomain.com/books/some_title is NOT a page in MODx):

                    # This is not actual code... but hopefully you get the idea... sorry, I'm switching between Perl and PHP this a.m. o_O
                    $uri_args = $_GET['q'];
                    if ($uri_args match /^books\/(.*)/) {
                       $results = "SELECT * FROM custom_db_table WHERE id='$1'";
                       print and format $results;
                       exit; // so that I don't display the 404 page.
                    } 


                    So I have a couple questions: if the page I’m looking for doesn’t exist, I can grab the URL and do something with it from the Plugin, but how would I pass the variables to a Snippet? Or is it unnecessary (see below)?

                    Do I need to modify my .htaccess file to assist with this? If I make the correct modification to the .htaccess file (e.g. a RewriteRule that pipes mydomain.com/books/* to the mydomain.com/books/ page?). And if I make that rewrite rule, do I even need the Plugin to grab the query string before the 404? Or can I just access the $_GET[’q’] from a Snippet contained on the "books" page?

                    I’m whipping this horse pretty hard, but there’s gold at the end of the rainbow... I can feel it. Thanks!
                      • 9207 ☆ A M B ☆
                      • 2,475 Posts
                      I’m posting my progress here for posterity. On a static site, I successfully tested the following redirect in my .htaccess file:

                      RewriteRule ^books/(.*)$ books/index.php


                      Where "index.php" is an actual file in the books directory... then all urls in the books directory resolve to the index page. Simple...

                      And on my MODx site, I can do a similar rewrite using the following syntax:
                      RewriteRule ^books/(.*)$ index.php?id=56


                      On my ’books’ page (id 56), I have the following uncached snippet:
                      <?php
                      echo "Server Request URI: ";
                      echo $_SERVER['REQUEST_URI'];
                      ?>


                      For the record, the $_GET[’q’] command and the $_SERVER[’HTTP_REFERER’] values came up empty-handed, but the REQUEST_URI came through with the full text of what was in the browser’s address bar.

                      E.g. With that .htaccess RewriteRule in place, I type in www.mydomain.com/books/some_title, then my "books" page (id 56), prints out "books/some_title" as the REQUEST_URI. It’s a bit redundant, but it’s relatively easy to strip off the "some_title" and use it to search for an entry in my custom database table. Whoo-hoo!

                      I couldn’t seem to make this work using friendly URLs... but I think that’s ok. Does anyone see anything inherently wrong with how I’m doing this? Am I an inch away from disaster or some nasty security vulnerability? Thanks for any feedback... I’m hoping to put this into a tutorial about making a custom module.