ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Snippet Errors

September 12, 2011 1:42pm

Subscribe [2]
  • #1 / Sep 12, 2011 1:42pm

    neuralynx

    62 posts

    Okay, to make it really simple to see the inconsistent behavior, I have created a simple template and snippet that you can play with.  Here is the template (called bull):

    BULL<br>
    
    Seg 1 = {segment_1}   
    Seg 2 = {segment_2}   
    Seg 3 = {segment_3}   
    Seg 4 = {segment_4}<br><br>
    
    {if segment_3 != "" AND segment_4 == ""}
      {exp:query sql="SELECT cat_id FROM exp_categories WHERE cat_url_title = '{segment_3}'"}
          {exp:channel:entries channel="products" category="{cat_id}"}
            {bull_snip}
          {/exp:channel:entries}
      {/exp:query}
    {if:elseif segment_3 != "" AND segment_4 != ""}
      {exp:query sql="SELECT cat_id FROM exp_categories WHERE cat_url_title = '{segment_3}'"}
          {exp:channel:entries channel="products" category="{cat_id}" url_title="{segment_4}"}
            {bull_snip}
          {/exp:channel:entries}
      {/exp:query}
    {if:else}
      {exp:channel:entries channel="products"}
        {bull_snip}
      {/exp:channel:entries}
    {/if}

    And here is the bull_snip snippet:

    -------------------------------------------------------------<br>
        {product_photo_1}
          {exp:query sql="SELECT file_id FROM exp_files WHERE file_name = '{filename}.{extension}' LIMIT 1"}
            {exp:file:entries file_id="{file_id}"}
              Filename: {filename}.{extension}
    
              File ID: {file_id}
    
              Image File URL = {file_url}<br>
              Image Thumbnail URL = {Product_Thumb_file_url}<br>
              {Product_Thumb_file_url}<br>
          <!-- {file_url} -->
            {/exp:file:entries}
          {/exp:query}
        {/product_photo_1}
    
        entry_id = {entry_id}<br>
        entry_id_path = {entry_id_path}<br><br>
    -------------------------------------------------------------<br>

    If you render it with the basic URL:
    http://dev.neuralynx.com/products/bull/
    you get 4 different products, each with the proper file_id, and image URLs.

    If you render a single product with the URL:
    http://dev.neuralynx.com/products/bull/digital_data_acquisition_systems/digital_lynx_16sx
    You get a single product with the proper file_id and URLs

    The problem arises if you just specify a category, as in the URL:
    http://dev.neuralynx.com/products/bull/digital_data_acquisition_systems/
    In this case, you get a single file_id repeated for both products in the category!  But also, you notice that the {entry_id} and {entry_id_path} is correct for each product, so the template is getting that right.  It just seems that the snippet is not parsing or handling the SQL query in the case when a category is specified, but no url_title.

    Been banging my head for three days on this problem and am really getting frustrated.

  • #2 / Sep 12, 2011 3:58pm

    neuralynx

    62 posts

    It seems clear to me that this is most certainly an error in the query module.  I have modified the bull_snippet to be as explicit as possible:

    -------------------------------------------------------------<br>
        {product_photo_1}
          Filename: {filename}.{extension}
    
          Query = SELECT file_id FROM exp_files WHERE file_name = '{filename}.{extension}'<br>
          {exp:query sql="SELECT file_id FROM exp_files WHERE file_name = '{filename}.{extension}'"}
            Query File ID: {file_id}<br>
            {exp:file:entries file_id="{file_id}"}
              Filename: {filename}.{extension}
    
              File ID: {file_id}
    
              Image File URL = {file_url}<br>
              Image Thumbnail URL = {Product_Thumb_file_url}<br>
              {Product_Thumb_file_url}<br>
          <!-- {file_url} -->
            {/exp:file:entries}
          {/exp:query}
        {/product_photo_1}
    
        entry_id = {entry_id}<br>
        entry_id_path = {entry_id_path}<br><br>
    -------------------------------------------------------------<br>

    It prints the filename, the query it is about to run, and then the file ID from the query return.  There is some strange side-effect that causes the query to return an incorrect result when it is run within the channel tags that specify a category.

    The incorrect results can plainly be seen at:
    http://dev.neuralynx.com/products/bull/digital_data_acquisition_systems/
    http://dev.neuralynx.com/products/bull/nanoz_and_accessories

    If this is a error, I would like some sort of reply from EE “Support”, and maybe I can find another way to accomplish the task.  I cannot continue to wait an unknown period of time for some unknown support person to post an answer or suggestion—or maybe not ever.  If someone is looking into this, then please at least let me know that this problem is not being ignored.

  • #3 / Sep 12, 2011 10:03pm

    Kevin Smith

    4784 posts

    Hi neuralynx,

    I’m sorry you felt like you had to wait an undue amount of time for help. We want to be as helpful as possible, but we also want to set the right expectation for response times. Our goal is to respond to every post within one business day. We haven’t been ignoring you!

    One basic thing to understand about snippets is that the EE parser simply expands snippets into the template being parsed very early in the parse order. (See Low’s excellent parse order PDF here.) Since your initial thought was that something might be wrong with the snippets, I thought I’d mention that first. If you think something’s wrong with the snippets, you can take them out of the equation entirely (for troubleshooting purposes) by just pasting the snippet contents where your snippet tag is in the master template.

    Now, you’ve got a lot going on here. If the Query module isn’t returning the file ID that you expect, there’s likely an issue with the query itself. While we can’t offer help in writing your queries, we do want to make sure the Query module isn’t malfunctioning here. Printing out the query like this:

    Query = SELECT file_id FROM exp_files WHERE file_name = '{filename}.{extension}'<br>
          {exp:query sql="SELECT file_id FROM exp_files WHERE file_name = '{filename}.{extension}'"}

    … isn’t a reliable way to debug since that may not be the actual query being put through the Query module thanks to the parse order. Instead, let me get you to enable displaying SQL Queries and Template Debugging in your Output and Debugging Preferences. Now check the queries that are actually being run against your database. Does it look like you expect? Could you post here the queries that are output by loading the URLs that are giving you fits?

  • #4 / Sep 13, 2011 11:41am

    neuralynx

    62 posts

    There are plenty of free CMS suites that work very well, with all their known strengths and weaknesses.  On its own, EE is good software that is competitive on its own merits.  However, there are many cracks in the veneer, such as out-of-date documentation, weak documentation, and simple features one would expect such a simple variable assignment.  I’m new, so there’s probably a bunch more.

    All software has issues like this, but for something in the cost range of your software, the expectations are rightfully higher.  I spent all day Friday trying to jump through hoops of needlessly complex {if} statements, and the justification for snippets, when the ability to simply assign a value to a variable would have worked.  Finally, on Monday morning, after exhausting all other avenues I could think of or find, I posted a support request.

    So yes, given the fact that there seems to be an error in the expensive software I purchased, and some really basic functionality is not supported, and I could not get an answer for an entire day, I think I am justified in being a bit upset about the situation.

    But okay, I’m willing to go forward here, learn from the experience, leave my gripes in the past, and focus on the issue at hand.

    ——————————————————————-

    I enabled the debugging as specified, and am sifting through the queries.  Some of them I do not know why they would even be executed.  If the channel parameter selection was working correctly, then I don’t believe queries for files in non-specified categories should even appear.

    Nonetheless, the relevant queries are just as I would expect:

    0.0001          SELECT file_id FROM exp_files WHERE file_name = 'DigitalLynx16SX_1200.png' 
    0.0001          SELECT file_id FROM exp_files WHERE file_name = 'DigitalLynx4SX_1200.png'

    But then it goes on to run this query a few times:

    0.0004          SELECT `exp_files`.`file_id`
                    FROM (`exp_files`)
                    WHERE `exp_files`.`site_id` IN ('1') 
                    AND `exp_files`.`file_id` =  '7'
                    ORDER BY `upload_date` desc
                    LIMIT 100

    Why would anything run a query that selects ‘file_id’ where one of the query parameters is file_id?  And why would it run this more than once?

    It is difficult to follow the program flow via queries, so I tried to attach a file of the debug output, but I just get the error “Error Message:  The file you are attempting to upload has invalid content for its MIME type.

    It is a simple TEXT file.  I tried even putting ‘Content-Type: text/plain’ at the top, but it still didn’t like it.

    You are welcome to run visit the test URL yourself and see the debug output:
    http://dev.neuralynx.com/products/bull/digital_data_acquisition_systems/
    There should be no access restrictions.

  • #5 / Sep 13, 2011 12:19pm

    neuralynx

    62 posts

    What config setting do I need to change to allow you see the log file?

  • #6 / Sep 13, 2011 1:15pm

    neuralynx

    62 posts

    Okay, I had to turn my debug output into a PDF in order to attach it, but here it is…

  • #7 / Sep 13, 2011 4:57pm

    Kevin Smith

    4784 posts

    Hi neuralynx,

    I’d like to look this over with a few of my developers, so be on the lookout for an email from me.

  • #8 / Sep 14, 2011 2:39pm

    neuralynx

    62 posts

    Seems to be working as expected when I change the snippets into embedded templates.

    Still can’t explain why the snippet works in certain conditions, but not others.

  • #9 / Sep 14, 2011 7:41pm

    Kevin Smith

    4784 posts

    Glad to see you found a solution! I’d say in this particular instance, you were probably caught by some parse order issues. The good thing about embedded templates, as Low’s Parse Order PDF shows, is they’re parsed very late in the parse order, letting you make sure almost everything in your parent template is parsed first. With complex templates like the one you have set up, it’s important to make sure your tags are structured with template parse order considerations in mind.

    Is there anything else I can help you with?

  • #10 / Sep 15, 2011 11:56am

    neuralynx

    62 posts

    Well, I wouldn’t so much call it a solution as a workaround.

    Parse order doesn’t explain why the snippet works in most conditions, but not in one of them.

    Non-deterministic behavior is not a desirable quality.

    From what I can gather reading other threads, snippets are faster, but seem to be quirky, and not robust.  I guess what I take away from all this is that if I really need to know something will work, I shouldn’t use snippets.

  • #11 / Sep 15, 2011 4:51pm

    Kevin Smith

    4784 posts

    Snippets are faster and less robust than embeds, this is true. From the docs:

    Snippets can be considered to actually be part of the template that they are used on, with their expanded contents parsed simultaneous to other tags and variables on the template. Embedded templates are separate templates, with their own preferences (caching, PHP parsing, access, etc.), and are parsed individually. Put another way, embedded templates are not included in the parent template, but rather added to them after the fact, using a separate query and full page parsing resources for each template.

    The reason snippets are faster is because they’re expanded into the template, with no other processing, at the first stage of the template parsing process. This allows you to take the same block of template code that might be in two places in one template (or one place in lots of templates) and use a snippet instead, which lets you stay DRY while avoiding any additional processing overhead that come with using an embedded template. Because of the way snippets are expanded into templates before any processing occurs, if your code doesn’t work using snippets, it won’t work without snippets either. If you take the code you’re using in your snippets here and just copy and paste it back into the parent template, you’ll see what I mean. It’s always one of the first things I recommend when troubleshooting problems involving snippets, and that’s why. The problem isn’t with snippets; it’s with your code.

    Note the comment that Chad Crowell makes at the bottom of the Snippets page in the docs:

    Note that you can’t put a channel:entries tag into a snippet as a replacement for putting it inside an embed. For instance, if you have a channel:entries tag pair and need another one inside of it, you can’t do that in a snippet, it will need to be in an embedded template.  The reason is that when the snippet is parsed and the rendered code placed into the template, you’ll essentially have a c:e tag pair inside of another c:e tag pair, which won’t work. More info: http://ellislab.com/forums/viewthread/187760/

    Using embedded templates, on the other hand, provides a solution to the usual inability to nest Channel Entries tags inside other Channel Entries tags due to the way they’re processed by the template parser. An embedded template is essentially fully processed as a template on its own before its output is pulled into that parent template, a full series of steps that doesn’t take place until very late in the parent template’s parse order.

    Does this help clear things up for you? Snippets are very different from embedded templates, and they’re meant to be used for different things. Sometimes their use cases overlap, but there are many times (like the one you’ve discovered) when the desired behavior can only be achieved with one and not the other.

  • #12 / Sep 15, 2011 5:32pm

    neuralynx

    62 posts

    Okay, snippets insert their code into the template, while embeds are parsed/run first, and then insert their results into the templates. 

    That makes sense, although it still doesn’t explain the inconsistent behavior I encountered.  But I’m willing to go with the intended uses of each, and not try to get one to do what the other is intended for.

    However, it seems that many people are using snippets and embedded templates as a way to avoid duplicating code over and over in a single template because there does not exist a way to assign values to variables.  A lot of complication could be eliminated if I were simply allowed to set the return of a query to a variable, and then use that variable several times later in the template.

    I tried a couple plugins, but they didn’t really do what I wanted.  I think I will submit a feature request, even though I see such requests have been made in the past.

    Alright, this issue has taken almost a week of my working life, although I do admit to be just learning EE.  I’m sure after a while this will all seem obvious to me.  This thread can be closed.

    Thanks,
    Scott

  • #13 / Sep 15, 2011 5:44pm

    Kevin Smith

    4784 posts

    Sure, I’d be glad to close this thread out. I wanted to mention a few more things before I do so to answer your questions about assigning variables. There are at least two good options for this that I use regularly, and they’re great for different situations. One is Preload Text Replacement, something native to EE, parsed after simple conditionals and before module and plugin tags. The other is eMarketSouth’s String plugin. Those two tools help me a great deal, and I’d highly recommend becoming familiar with them.

    Good luck with your site!

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases