We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 48840
    • 4 Posts
    Hello everyone! I had a quick question I was hoping someone could help me solve.

    I have an existing database with products. I'd like to show said products on my front end and am wondering the best way to do this. After doing some research, here is what I've found thus far:

    1. I could import the products. I'm not sure this is a good idea as there are 1,000s of products.

    2. I could read the external database via xPDO. This was my initial thought, but I'm confused how I get MODX to respond to a specific URL. Say I want the URL to be something along the lines of http://mysite.com/products/1234 or http://mysite.com/products/1234.html where 1234 is the ID of a product in my external database.

    Hopefully that makes sense.

    Thanks for the help!

    This question has been answered by multiple community members. See the first response.

    • discuss.answer
      • 3749
      • 24,544 Posts
      I'd strongly recommend importing your products table into the MODX database and making it xPDO-friendly. If it's a single table (and maybe even if it's not), this method might make things easier: http://bobsguides.com/custom-db-tables.html.

      Once you do that, you can get the product number from the url and use a Tpl chunk to format the data for that row. It will be easier if you don't mind making the URL mysite.com/products/?pid=1234.

      That will look something like this:

      Tpl chunk (ProductTpl):

      (The placeholders should have the same names as the fields in the table.)

      <div class='product'>
          <ul class="product_data">
             <li>Product: [[+product_name]]</li>
             <li>Description: [[+product_description]]</li>
             <li>Price: [[+product_price]]</li>
      
          </ul>
      </div>



      Snippet to display a product (placed on the mysite.com/product page):

      $productId = isset($_GET['pid'])? $_GET['pid'] : 0;
      $product = $modx->getObject('modProduct', $productId);
      if ($product) {
          $fields = $product->toArray();
      } else {
          return 'Product Not Found';
      }
      
      return $modx->getChunk('ProductTpl', $fields);
      
      
        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
        • 28042 ☆ A M B ☆
        • 24,524 Posts
        I'll second that recommendation. It will take a bit of time and effort to get it set up as an xPDO-based service, but once that's done working with your data will be so much easier from then on.
          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 48840
          • 4 Posts
          Thanks guys. Just to make sure I'm understanding you correctly. My products table would be in the same database as MODX (I guess it wouldn't have to be if I configured XPDO to look at a different database). Then, with the setup with XPDO, I can interact with a specific row or rows of said product table via a snippet?

          One follow up question, you said it would be easier to do something like http://mysite.com/products/?pid=1234. Is it not possible to have friendly URLs? How much work would be involved to have a better looking URL or even a slugged version of the product name?

          Could I create a plugin and listen for something like OnHandleRequest or OnWebPageInit to essentially catch the request and route it to my own custom controller/something similar? Just thinking out loud.

          Thanks again for the feedback. Much appreciated!
            • 28042 ☆ A M B ☆
            • 24,524 Posts
            Certainly, you can also use forms and buttons and have a snippet to process the POST. There are several other ways you can process a user choice, but getting the user's choice back to the server to be processed is pretty much limited to GET (in the URL) or POST (form submissions).

            You could us AJAX, in which case the user would never leave the page, and so would not see anything. It would work in exactly the same way, except instead of the user's request resulting in a new page with the processed result, the query data would be sent, processed and the returned result would be inserted into the same page.
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
            • discuss.answer
              • 4172
              • 5,888 Posts
              Could I create a plugin and listen for something like OnHandleRequest or OnWebPageInit to essentially catch the request and route it to my own custom controller/something similar? Just thinking out loud.

              I think OnPageNotFound is the best working system-event for this purpose.

              There is a plugin, which can handle that:
              http://modx.com/extras/package/customrequest
                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!
                • 48840
                • 4 Posts
                Bob, on your website, you say:
                Make sure your custom database table has a primary key called id that is an autoincrement field.

                The products table I am working with is provided by an external source and I do not have control over the database schema. I know that not all of their tables have the primary key named "id". What do I do in that case?
                  • 3749
                  • 24,544 Posts
                  Good question. xPDO will work fine without an 'id' field, but your object has to extend xPDOObject instead of xPDOSimpleObject. It's been a *long* time since I wrote that utility snippet, but IIRC, you can generate the schema alone (without the class and map files), modify the schema to set the inheritance, and then generate the class and map files without generating the schema. You'll have to modify the properties to do that.

                  First pass:

                  &createSchema=`1` &createClasses=`0`


                  Modify schema

                  Second Pass:

                  &createSchema=`0` &createClasses=`1`
                  


                  You may have to specify the primary key in the schema. I'm not sure if it will be detected properly if it's not 'id'.
                    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
                    • 48840
                    • 4 Posts
                    Hello everyone. I just wanted to give a follow-up since I got everything working!

                    I used Bob's initial suggestion of creating an xPDO object to read the data. This worked great and was far easier than I expected.

                    Next to get friendly URLs, I am using CustomRequest suggested by Bruno with the following configuration:
                    <?php
                    
                    // core/components/customrequest/configs/product.config.inc.php
                    $settings['product.show'] = array(
                        'resourceId' => 123,
                        'alias' => 'product/',
                        'urlParams' => array('productId')
                    );
                    

                    Note, I did need to update the customrequest.configsPath setting to {core_path}components/customrequest/configs/.

                    Now, within my snippet, I am able to grab the product's ID number via $_REQUEST['productId']. This way, my end URL is something along the lines of:
                    http://domain.org/product/1234

                    Thank you everyone for your help! Much appreciated!
                      • 3749
                      • 24,544 Posts
                      I'm glad you got it sorted. smiley
                        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