We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 37143
    • 74 Posts
    Hi, so I have the Store Locator setup and needed to identify different types of stores based on their parent resource. So, my templates for the GoogleMap Window and the StoreOutputList have a lot of GetREsourceField calls in them. An example is below. This worked fine until I imported 1000 stores. With that many stores, the initial load of SToreLocator fails (timeout) after 30 seconds. If I use the default templates instead of my custom ones, things work ok, albeit slow, but they work. Here is my MapTpl, the Output list tpl is very similar:

    [[If?
    &subject=`[[+parent]]`
    &operator=`EQ`
    &operand=`2888`
    &then=`<h3>Staples</h3><h4>[[+pagetitle]]
    [[getResourceField? &id=`[[+id]]` &field=`store-city` &processTV=`1` &default=`Sorry, no address info available`]], [[getResourceField? &id=`[[+id]]` &field=`store-state` &processTV=`1` &default=`Sorry, no address info available`]]</h4>
    [[getResourceField? &id=`[[+id]]` &field=`store-phone` &processTV=`1` &default=`Sorry, no phone info available`]]`

    &else=`<h3>[[getResourceField? &id=`[[+id]]` &field=`store-name` &processTV=`1` &default=`Sorry, no store name available`]]</h3><h4>[[getResourceField? &id=`[[+id]]` &field=`store-contact` &processTV=`1` &default=`Sorry, no contact person info available`]]</h4>[[getResourceField? &id=`[[+id]]` &field=`store-zip` &processTV=`1` &default=`Sorry, no zip code info available`]]
    [[getResourceField? &id=`[[+id]]` &field=`store-phone` &processTV=`1` &default=`Sorry, no phone info available`]], <a href="mailto:[[getResourceField? &id=`[[+id]]` &field=`store-email` &processTV=`1` &default=`Sorry, no e-mail info available`]]">[[getResourceField? &id=`[[+id]]` &field=`store-email` &processTV=`1` &default=`Sorry, no e-mail info available`]]</a>`
    ]]

    Can anyone recommend a better way to attack this? Paid work/consultation is available for this. I am at my limits of what I can understand and accomplish, and need help. Anyone interested please reply or email me at acaffiero at gmail dot com.

    Thanks!

      • 35150 ☆ A M B ☆
      • 191 Posts
      I don't know anything about the Store Locator extra, but a thousand stores is a lot and you'd be better off performance wise putting them in a custom database table and writing a snippet to retrieve and format the data.

      However, that call you've got there could be made considerably more efficient, *maybe* enough to get Store Locator to load within 30 seconds, after which it should be cached and less of a performance concern. The problem is the 9 calls to getResourceField per store location (they get executed in both the 'then' and 'else' branches, even though you end up only using one or the other). That's 9000 calls to do all your locations. I don't think getResourceField is quite the right thing to use. getResources might be a better candidate, though handling it's &parent parameter might be tricky in this case depending on whether or not your store resources have a common ancestor.

      Actually, I've got a simple snippet I've been meaning to submit to the extras repository that would be easy to use here and would cut out a lot of overhead, possibly enough to get you over the hump. It's called setPlaceholders. Using it you could rewrite your code above like this:

      [[setPlaceholders?
      &id=`[[+id]]`
      &fields=`
      tv.store-name !! Sorry, no store name available ||
      tv.store-contact !! Sorry, no contact person info available ||
      tv.store-email !! Sorry, no e-mail info available ||
      tv.store-phone !! Sorry, no phone info available ||
      tv.store-city !! Sorry, no address info available ||
      tv.store-state !! Sorry, no address info available ||
      tv.store-zip !! Sorry, no zip code info available
      `
      ]]

      [[If?
      &subject=`[[+parent]]`
      &operator=`EQ`
      &operand=`2888`
      &then=`<h3>Staples</h3><h4>[[+pagetitle]] [[+ph.tv.store-city]], [[+ph.tv.store-state]]</h4> [[+ph.tv.store-phone]]`

      &else=`<h3>[[+ph.tv.store-name]]</h3><h4>[[+ph.tv.store-contact]]</h4>[[+ph.tv.store-zip]] [[+ph.tv.store-phone]], <a href="mailto:[[+ph.tv.store-email]]">[[+ph.tv.store-email]]</a>`
      ]]


      And that could be optimized even further by creating two chunks:
      chunkA <h3>Staples</h3><h4>[[+pagetitle]] [[+ph.tv.store-city]], [[+ph.tv.store-state]]</h4> [[+ph.tv.store-phone]]
      chunkB <h3>[[+ph.tv.store-name]]</h3><h4>[[+ph.tv.store-contact]]</h4>[[+ph.tv.store-zip]] [[+ph.tv.store-phone]], <a href="mailto:[[+ph.tv.store-email]]">[[+ph.tv.store-email]]</a>

      and replacing the 'If' call with this line:
      [[$[[+parent:eq=`2888`:then=`chunkA`:else=`chunkB`]]]]

      This way only one of the branches gets parsed.

      Anyway, seems worth a try. It'd be simple to test and might solve your problem well enough to get by with. I'll try to submit setPlaceholders this weekend. In fact, I'll email it to you this evening if you'd like to try it out before then.
        Extras :: pThumb • Resizer • imageSlim • setPlaceholders
        • 35150 ☆ A M B ☆
        • 191 Posts
        One further optimization idea. Since some of the TVs are different between chunkA and chunkB, instead of getting them all initially, get rid of that setPlaceholders call and add it separately to each of the chunks, getting only the TVs that particular chunk requires.
          Extras :: pThumb • Resizer • imageSlim • setPlaceholders
          • 37143
          • 74 Posts
          Quote from: jgrant at Dec 21, 2012, 10:44 PM
          I don't know anything about the Store Locator extra, but a thousand stores is a lot and you'd be better off performance wise putting them in a custom database table and writing a snippet to retrieve and format the data.

          However, that call you've got there could be made considerably more efficient, *maybe* enough to get Store Locator to load within 30 seconds, after which it should be cached and less of a performance concern. The problem is the 9 calls to getResourceField per store location (they get executed in both the 'then' and 'else' branches, even though you end up only using one or the other). That's 9000 calls to do all your locations. I don't think getResourceField is quite the right thing to use. getResources might be a better candidate, though handling it's &parent parameter might be tricky in this case depending on whether or not your store resources have a common ancestor.

          Actually, I've got a simple snippet I've been meaning to submit to the extras repository that would be easy to use here and would cut out a lot of overhead, possibly enough to get you over the hump. It's called setPlaceholders. Using it you could rewrite your code above like this:

          [[setPlaceholders?
          &id=`[[+id]]`
          &fields=`
          tv.store-name !! Sorry, no store name available ||
          tv.store-contact !! Sorry, no contact person info available ||
          tv.store-email !! Sorry, no e-mail info available ||
          tv.store-phone !! Sorry, no phone info available ||
          tv.store-city !! Sorry, no address info available ||
          tv.store-state !! Sorry, no address info available ||
          tv.store-zip !! Sorry, no zip code info available
          `
          ]]

          [[If?
          &subject=`[[+parent]]`
          &operator=`EQ`
          &operand=`2888`
          &then=`<h3>Staples</h3><h4>[[+pagetitle]] [[+ph.tv.store-city]], [[+ph.tv.store-state]]</h4> [[+ph.tv.store-phone]]`

          &else=`<h3>[[+ph.tv.store-name]]</h3><h4>[[+ph.tv.store-contact]]</h4>[[+ph.tv.store-zip]] [[+ph.tv.store-phone]], <a href="mailto:[[+ph.tv.store-email]]">[[+ph.tv.store-email]]</a>`
          ]]


          And that could be optimized even further by creating two chunks:
          chunkA <h3>Staples</h3><h4>[[+pagetitle]] [[+ph.tv.store-city]], [[+ph.tv.store-state]]</h4> [[+ph.tv.store-phone]]
          chunkB <h3>[[+ph.tv.store-name]]</h3><h4>[[+ph.tv.store-contact]]</h4>[[+ph.tv.store-zip]] [[+ph.tv.store-phone]], <a href="mailto:[[+ph.tv.store-email]]">[[+ph.tv.store-email]]</a>

          and replacing the 'If' call with this line:
          [[$[[+parent:eq=`2888`:then=`chunkA`:else=`chunkB`]]]]

          This way only one of the branches gets parsed.

          Anyway, seems worth a try. It'd be simple to test and might solve your problem well enough to get by with. I'll try to submit setPlaceholders this weekend. In fact, I'll email it to you this evening if you'd like to try it out before then.

          Sure, I'd def try it, please feel free to email it, and thank you for your replies and assistance.
          I created chunks for my else/then code, but I'm now getting some bad data, so I'm wondering if by moving that code into chunks, it is altering the results.
            • 35150 ☆ A M B ☆
            • 191 Posts
            Check your email; I sent that to you last night, just after 11pm central time. Let me know if you didn't get it and I'll resend.

            I created chunks for my else/then code, but I'm now getting some bad data, so I'm wondering if by moving that code into chunks, it is altering the results.

            It shouldn't be, unless there's something else going on. Here's a good post on the technique and how it works: https://www.markhamstra.com/modx-blog/2011/11/nested-caching-in-modx-revolution/.
              Extras :: pThumb • Resizer • imageSlim • setPlaceholders
              • 37143
              • 74 Posts
              Quote from: jgrant at Dec 22, 2012, 10:05 AM
              Check your email; I sent that to you last night, just after 11pm central time. Let me know if you didn't get it and I'll resend.

              I created chunks for my else/then code, but I'm now getting some bad data, so I'm wondering if by moving that code into chunks, it is altering the results.

              It shouldn't be, unless there's something else going on. Here's a good post on the technique and how it works: https://www.markhamstra.com/modx-blog/2011/11/nested-caching-in-modx-revolution/.

              Please resend that snippet if you could, I don't see it, nor in my spam....Thanks!

              Yeah, this caching is so confusing. Basically, on my two branches, it was returning the first result of data it found, and used that data for each result. Anyhow. Here is what I have now. Still not loading on initial load (time's out), but I think this code is def cleaner:

              [[!StoreLocator?
              &searchZoom=`10`
              &zoom=`4`
              &width=`640`
              &height=`480`
              &centerLongitude=`-95.712891`
              &centerLatitude=`37.09024`
              &formTpl=`store-form`
              &noResultsTpl=`no-store-results`
              &limit=`0`
              &storeRowTpl=`store-row`
              &storeInfoWindowTpl=`store-info-window`
              ]]

              store-info-window is:
              <div class="storelocator-marker" style="width:450px;height:auto;">

              [[+parent:eq=`2888`:then=`[[getResources? &tpl=`window-1` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`:else=`[[getResources? &tpl=`window-2` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`]]

              </div>

              store-row looks like:

              <div class="store-result">

              [[+parent:eq=`2888`:then=`[[getResources? &tpl=`row-1` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`:else=`[[getResources? &tpl=`row-2` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`]]

              </div>

              and then in my getResources templates, I am getting all the TVs values. It all works fine, except for the initial load still with no value in the query. If I set a limit in the Store Locator call, I can "trick" it into loading, then once I have the form up, I can remove the limit and do a search, it runs fast then and I can test my results. But then if I hit "Clear", we time out.

              Anthony
                • 35150 ☆ A M B ☆
                • 191 Posts
                I just resent it.

                [[+parent:eq=`2888`:then=`[[getResources? &tpl=`window-1` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`:else=`[[getResources? &tpl=`window-2` &parents=`-1` &resources=`[[+id]]` &limit=`1` &includeTVs=`1` &processTVs=`1` ]]`]]

                You can make this at least twice as fast by writing it like so:

                [[[[+parent:eq=`2888`:then=`getResources? &tpl=`window-1` &parents=`-1` &resources=`[[+id]]` &includeTVs=`1` `:else=`getResources? &tpl=`window-2` &parents=`-1` &resources=`[[+id]]` &includeTVs=`1` `]]]]

                You could try experimenting with using &includeTVList to include only the TVs you need for that template. That might make it a hair faster.
                  Extras :: pThumb • Resizer • imageSlim • setPlaceholders