We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 34022 ☆ A M B ☆
    • 91 Posts
    Hi,

    I am currently developing two components: the Networkit (social networking) component, and a Loop ("foreach") and Case snippet combo that I am trying to turn into an easier FormIt form generator. Both of these projects have encountered a partial caching problem with placeholders. This may actually not be a problem at all and part of the design, but in both cases I think it would make sense for the partial caching to work.

    The Loop/ Case Issue:

    Here is my FormIt call code, which works perfectly when the Loop snippet and [[$field]] chunks are called uncached:
    [[!FormIt? &hooks=`recaptcha,spam,email,redirect` &emailTpl=`ContactFormReport` &emailTo=`[[++emailsender]]` &emailSubject=`New message from [[++site_name]] [[*pagetitle]] page.` &redirectTo=`7` &submitVar=`submitForm` &validate=`[[Loop? &separator=`:required,` &idx=`0` &loop=`first==last==company==address==city==state==zip==phone==primary_color==floor_area==
    grout_joint_filling_of_cut_control_joints==repair_of_holes_and_cracks==
    edge_tint_border==start-up_maintenance_program==email:email==message`]]:required, blank:blank`]]
    <div>[[+fi.error.error_message]] [[!+fi.validation_error_message]] [[+fi.error.recaptcha]]</div>
    <form id="submitForm" action="[[~[[*id]]]]" method="post"><fieldset><div class="wrap">
    <input name="blank" type="hidden" />
    [[!Loop? &tpl=`field` &ph=`name,req,label` &static=`type==text` &loop=`
      first==last==company==address==address2==city==state==zip==email==phone==fax==floor_area
      ||1==1==1==1====1==1==1==1==1====1
      ||======================Floor Area (sq.ft.)
    ` ]]
    [[!$field? &name=`existing_floor_covering` &type=`checkbox` &label=`Yes` &message=`Existing floor covering` &numeric=`0`]]
    [[!$field? &name=`type_of_covering` &type=`text`]]
    [[!$field? &name=`primary_color` &type=`select` &req=`1` &options=`Natural==Color`]]
    [[!Loop? &ph=`name,message` &static=`req==1||type==radio` &tpl=`field` &loop=`grout_joint_filling_of_cut_control_joints==repair_of_holes_and_cracks==edge_tint_border==start-up_maintenance_program||Grout/ joint filling of cut & control joints?==Patching of blemishes/ cracks/ tenches?==Edge tine border?==Start-up maintenance program?`]]
    [[!$field? &name=`message` &req=`1` &type=`textarea`]]
    <div class="captcha">
         [[+fi.error.recaptcha]]
      [[!+formit.recaptcha_html]]
    </div>
    [[!$field? &type=`submit` &name=`submitForm` &value=`Send This Message` &message=` `]]
    </div></fieldset></form>​


    And here is the [[$field]] chunk:
    <div>
     
      <label for="[[+name]]">[[+req:notempty=`* `]][[+message:default=`[[+label:default=`[[+name:replace=`_== `:ucwords]]`]]`]]</label>
      
    [[Case? &subject=`[[+type:default=`text`]]`
    &case1=`text` &then1=`
      <input id="[[+name]]" class="[[+type]] [[+class]][[!+fi.error.[[+name]]:notempty=` error`]]" name="[[+name]]" type="[[+type]]" value="[[!+fi.[[+name]]]]" />
    `
    &case2=`textarea` &then2=`
      <textarea id="[[+name]]" class="[[+type]] [[+class]][[!+fi.error.[[+name]]:notempty=` error`]]" name="[[+name]]">[[+fi.[[+name]]]]</textarea>
    `
    &case3=`checkbox` &then3=`
    <input name="[[+name]]" type="hidden" value="[[+default]]" />
    [[$fieldBool? &type=`checkbox` &name=`[[+name]]` &label=`[[+label]]` &message=`[[+label]]`]]
    `
    &case4=`radio` &then4=`
    [[!+fi.error.[[+name]]:notempty=`<span class="left error">`]]
    <input type="hidden" name="[[+name]]" />
    [[$fieldBool? &name=`[[+name]]` &label=`Yes` &message=`Yes`]]
    [[$fieldBool? &name=`[[+name]]` &label=`No` &message=`No`]]
    [[!+fi.error.[[+name]]:notempty=`</span>`]]
    `
    &case5=`submit` &then5=`
    <input id="[[+name]]" class="button" name="[[+name]]" type="[[+type]]" value="[[+label:default=`Submit`]]" />
    `
    &case6=`select` &then6=`
    <select name="[[+name]]" id="[[+name]]" class="[[!+fi.error.[[+name]]:notempty=`error`]]">
      <option name="[[+name]]" value="[[+default]]">[[+label]]</option>
    [[Loop? &tpl=`fieldOption` &static=`name==[[+name]]` &ph=`label` &loop=`[[+options]]` ]]
    </select>
    `
    
    ]]
    [[!+fi.error.[[+name]]]]
    </div>
    ​


    The Loop snippet code is available here: http://modxcms.com/forums/index.php/topic,60559.0.html
    And the Case snippet code is available here: http://modxcms.com/forums/index.php/topic,61045.0.html

    What doesn’t work when [[Loop]] and [[$field]] are called cached: Everything works EXCEPT [[!+fi.error.[[+name]]:notempty=`error`]]. Even the "[[!+fi.error.[[+name]]]]" placeholders are generated properly as "This field is required".

    When it actually works: If the [[$field]] template does NOT use a [[Case]] snippet, everything works as expected, including the [[!+fi.error.[[+name]]:notempty=`error`]].

    Why the Loop and [[$field]] snippets should be cached: Because only static input goes in! Partial caching means that the uncached placeholder [[!+fi.error.[[+name]]:notempty=`error`]] should be generated every time from scratch, but everything else can be cached. There is no need to re-generate a text input field! It will always remain a text input field!


    The NetworkIt Issue:

    This snippet is pretty complicated, but basically the idea is that a resource with a GET parameter for userid similar to "wall_userid" will output a bunch of information about that user, including FormIt calls that will send messages to the user, a list of messages to/ from the user, etc....

    To avoid having to call [[!getUrlParam? &name=`wall_userid`]] or a similar snippet over and over on the page, I use [[!Profile? &user=`[[!getUrlParam? &name=`wall_userid`]]` &prefix=`public.`]] at the top of the template so that I can just use [[+public.fullname]] instead of [[!getUrlParam:userinfo=`fullname`? &name=`wall_userid`]]. And yes, I know I can just make a short snippet like [[!getUser:userinfo=`fullname`]] or [[!getUser? &info=`fullname`]], but I would need to call that as often as 20 times a page or more, so it makes sense to use placeholders instead to avoid database queries, especially if the site will have a huge user database.

    Here’s the problem: I want to use caching for the page for every single user. Normally, [[Profile? &user=`1`]] would be cached, [[Profile? &user=`2`]] would be cached, etc.... But, I am forced to call Profile (and thus all placeholders) uncached.

    Calling Profile uncached is a tolerable situation, but I can’t use caching on other snippets either. For example: [[Gravatar? &email=`[[!+public.email]]`]] SHOULD be cached for every email, because (assuming the email doesn’t change), there is no need to re-generate the gravatar URL every time. However, snippets with placeholder inputs only work if called uncached. By comparison, [[Gravatar? &email=`[[!getUrlParam? &name=`wall_userid`]]`]] works perfectly well cached.

    Here is the cached portion of the resource for Gravatar (modified slightly for anonymity):

    '[[Gravatar? &email=`2` &size=`40`]]' => 'http://www.gravatar.com/avatar.php?gravatar_id=XXXXX&size=40&rating=G&default=wavatar',
    '[[Gravatar? &email=`13` &size=`40`]]' => 'http://www.gravatar.com/avatar.php?gravatar_id=YYYYY&size=40&rating=G&default=wavatar',
    '[[Gravatar? &email=`28` &size=`40`]]' => 'http://www.gravatar.com/avatar.php?gravatar_id=ZZZZZ&size=40&rating=G&default=wavatar',
    


    Of course, I would probably need to set up a custom caching system that is user-based and not document-based, but it would still need to use placeholders for the easiest implementation.

    The main goal of this snippet is to allow a site with hundreds or thousands of users to output hundreds or thousands of messages. If I can’t call the [[getMessages? &user=`[[!+public.id]]`]] cached, the website would slow down to a crawl. So, is using a [[!getUser:userinfo=`XXX`]] snippet (which also has an overhead) all over the page my only alternative to enable caching? Shouldn’t there be some sort of method in MODx to force SOME placeholders to be evaluated FIRST, thus enabling cached snippets?

    Any recommendations?
      WebsiteZen.com - MODX and E-Commerce web development in the San Francisco Bay Area
      • 3749
      • 24,544 Posts
      I’m not sure I understand your issue, but did you try this:

      [[+fi.error.[[!+name]]]]
        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
        • 34022 ☆ A M B ☆
        • 91 Posts
        Just tried it and it didn’t work.

        Bottom line, the issue is that when the [[$field]] chunk (which contains a Case snippet call) is called cached: [tt][[$field? &name=`first` &type=`text` &label=`First Name`]][/tt], [tt][[!+fi.error.[[+name]]:notempty=`error`]][/tt], which is inside of the Case snippet’s &then parameters, fails to update, even though [tt][[!+fi.error.[[+name]]]][/tt] updates properly. When placed outside of the Case call but still inside the field chunk, both versions update properly.

        The :notempty=`error` output filter is used to add an "error" class to the input, which allows me to color the field pink. I would really like this functionality to stay.

        BTW, Thanks for all the help!

          WebsiteZen.com - MODX and E-Commerce web development in the San Francisco Bay Area
          • 34022 ☆ A M B ☆
          • 91 Posts
          Should I file this as a bug report? I also noticed similar problems when using the "If" snippet.
            WebsiteZen.com - MODX and E-Commerce web development in the San Francisco Bay Area
            • 3749
            • 24,544 Posts
            TBH, I don’t understand the issue well enough to say whether it’s a bug or not, but it can’t hurt to file it.
              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
              • 34022 ☆ A M B ☆
              • 91 Posts
                WebsiteZen.com - MODX and E-Commerce web development in the San Francisco Bay Area