We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 44165
    • 20 Posts
    Hi,
    I am building a website for a brewery and brew pub. Each beer has its own document. They have 21 rotating taps in the pub. I would love to have a template variable that lists each beer document in check boxes, with each checked document to display as a link to that beer on the "On tap" page. Frankly, I am quite lost here and don't really know where to begin. One thing I love about MODX is the many different ways one can achieve their goal, but at times like this, it makes it hard to know where to start.

    My document tree is something like this:

    pub
    -on tap
    brewery
    -beers
    --year round
    ---year round beer 1
    ---year round beer 2
    --seasonal
    ---seasonal beer 1
    ---seasonal beer 2
    etc.

    So, lets assume that they have year round beer 1 and seasonal beer 1 currently on tap. How would I create links to those documents to display on the "on tap" page chosen by a TV that lists all of the beers, and displays links to only the checked documents?

    Another (less ideal) option would be to have a TV for each beer document that lets me select weather or not the beer is on tap, and then use wayfinder to display links to the beer documents that have that tv value of on tap. But I am not sure how t do this either.

    If anyone has any thoughts or suggestions on how I might achieve this, they would be greatly appreciated! Please let me know if I can provide any more beneficial information.
    Thanks!

    p.s. I am using revo 2.2.8

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

    • discuss.answer
      • 3749
      • 24,544 Posts
      TVs aren't really designed to store that kind of data. You can do it (possibly with getResources), but it will be slow, inefficient, and difficult to maintain. And it will get worse as the number of entries increases. Using MIGX, might also be an option.

      By far the best way to do this is to create custom tables in the DB and make them xPDO-friendly, though that might be overkill if your list of pubs and beers will always be small.

      1. The beer table would have information about each beer (but no information about pubs): alcohol content, style, brewery location, etc. Optionally, the brewery field could be the ID of a brewery in the 'brewery' table.

      2. The pub table would have information about each pub (but not about its beers): address, phone, url, etc..

      3. The pub_beer table would contain records that each have three fields: 'id' (ID of this pub_beer record), 'beer_id' (the ID of some beer) and 'pub_id' (the ID of some pub).

      4. (optional) A brewery table with information about the brewery (but not about its beers): address, date founded, etc..

      5. (optional) A brewery_beers table with three fields: 'id' (ID of this brewery_beer record), 'beer_id' (the ID of some beer) and 'brewery_id' (the ID of some brewery).

      If you need to separate on tap and bottled beer, you'd probably want two tables like the last one: pub_beer_on_tap, and pub_beer_bottles.

      This will allow *very* fast searching for the beers a pub has or vice versa.

      $beers = $pub->getMany('OnTap');
      $beers = $pub->getMany('Bottles');
      $pubs = $beer->getMany('Pubs');
      $brewery = $beer->getOne('Brewery');
      $beers = $brewery->getMany('Beers');
      

      It will also allow searches like "Find pubs near me with Beer X on tap," which would be a very cumbersonme to do with TVs.

      *************************************************************************************

      That said, you could do it with a checkbox TV called OnTap with Input Options like this: beer1==pageId1||beer2==pageId2||beer3==pageId3 (where pageId is the ID of the beer's Resource.

      The selected beers will be rendered the same way by default, so you could display them with a custom snippet.

      [[!ShowBeers? $beers=`[[!*OnTap]]`]]


      /* Show Beers snippet */
      
      $beers = explode('||', $beers);
      $output = "\n<ul>";
      foreach ($beers as $beerName => $pageId) {
          $url = $modx->makeUrl($pageId, "", "", "full");
          $output .= "\n    <li>" . '<a href="' . $url . '">' . $beerName . '</a></li>'; 
      }
      $output = "\n</ul>";
      
      return $output;


      The down side of this method it that it will be very difficult to create a UI to let you update the information and you'll probably end up doing a lot of tedious manual editing.


      [ed. note: BobRay last edited this post 13 years, 4 months ago.]
        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
        • 44165
        • 20 Posts
        Bob,
        Thank you for your prompt and detailed response. This was my first forum posting, and I can't express how pleased I am to have gotten such a rich response from the man who literally "wrote the book" on modx. My background is html/css and I have a very limited understanding of php, so I'm afraid the proposed 'best option' is a little over my head. I am also relatively new to modx... I have been learning it for about 3 weeks now.
        The website is for a brewery that has a single brew pub attached, so it is a little simpler than your proposed solution. Most of their taps will serve their own beer, which will each have a page detailing the beer profile, label, abv%, etc. These pages are set up so they can easily add, remove or modify a beer. So here is what I have done for the on tap page:

        Each house beer has its own resource page. For the "currently on tap" page, I have made a TV (input: resource list) for each tap (*Tap1, *Tap2, *Tap3 etc.), with the parents property set to the parent document for all of the house beer profile pages. In the on tap template, I have
        <a href="[[~[[*Tap1]]]]">[[getResourceField? &id=`[[*Tap1]]` &field=`pagetitle`]]</a><br>
        

        set up for each tap TV.

        They also feature some guest taps, which will just be url tv's that go to that brewery's website.

        Does this seem like a decent solution for someone who probably can't pull off what you have suggested?

        If so, perhaps you could help me with one small detail. Each beer profile is a child of a beer category, and each beer category is a child of the beers document, which is the grandaddy resource for all the beers. When choosing the resource from my on tap TV's, the beer category's show up in the resource list. For each of these TV properties I have the grandaddy beer document set in the parents field, and include parents is set to no. But the category's still show up in the TV's resource list. For ease of use, I would like the resource list to have every beer page, but not the category's. Seems like include parents;no should hide them. Am I missing something here?

        Again, thank you for your help. I think it might be time for me to buy a copy of your book!

        -Chen
        • discuss.answer
          • 3749
          • 24,544 Posts
          LOL, I should really ask more questions before I start cranking out code and suggestions. wink

          If that works for you, it's a good solution, though I think I would have a Resource for each tap and a Radio Options TV called 'Beer' used to select the beer dispensed from that tap (assuming that I'm understanding the setup). That way, your On Tap page could have one getResources tag if the tap pages are all under the same parent.

          The Beer TV Input Options values look something like this:

          Beer1==(beer one's Resource ID)||Beer2==(beer two's Resource ID) . . . etc.

          In your Tpl chunk for the getResources call, the beer's url would be available as:
          [[~[[+Beer]]]] 


          And the beer page's ID would be available with:
          [[+Beer]]


          Any other fields of the beer page (content, description, introtext, longtitle, pagetitle, etc.) should be available with getResourceField using the ID tag above.


          I don't know of any way to hide the category pages the way you're doing it. You could try having the category pages unpublished or hidden from menus, but I don't think either would work properly. Setting include parent doesn't work because, from the perspective of the snippet, they are children, not parents.


          Another good option would be using MIGX, but it can be challenging for a non-coder, though the author, Bruno17, is great about helping people find solutions with it.

          I should also mention another option, which is to put all the beer pages under the same parent and make their category a TV. That creates problems if you want to show a list somewhere of the beers by category, but I think that would still be doable with getResources.
            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
            • 44165
            • 20 Posts
            I like the idea of setting up a radio button TV, but then I would have to update the input values whenever a new beer is created. I might look into MIGX. For now though, it'll work out as is. Thanks again!