Problem injecting code into template

New Member
3 0 0

Hi all

 

I have an app in review which was passed back with the request that the app automatically adds itself to the merchant's theme template. I'm a little uncomfortable about this on the basis that:

1) When they uninstall they'll be left with a snippet which won't work

2) I'll have no clue what template they have or where they might want to add the snippet, and

3) Parsing mixed html/liquid is a git.

 

I can easily add my snippet, and I can remove the reference to it from a template with a simple string replace, but adding it is proving to be problematic.

 

I'm using PHP server side, and adding the reference to the snippet as a liquid include, which then pulls in the javascript and div placeholder. Statically (having the merchant paste two lines of code) it works a charm, but trying to do this dynamically is a *nightmare*. I've been very close twice, using different DOM parsers in PHP, but each has difficulties with liquid. I've even tried the liquid library with no joy, so I'm hitting a head end.

 

Has anyone got a working example of pulling a theme asset, parsing it for a 'known' element, appending a new element to it, and successfully PUTting that back to a template?

 

Cheers,

Gary.

 

0 Likes
Shopify Staff
Shopify Staff
391 53 62

Hey @gary-thompson,

 

I can appreciate the trepidation. Inserting theme code is dangerous.

 

There are a few different approaches depending on what your app is doing. If you can get away with using ScriptTag, do so. ScriptTags are simple to add and automatically removed when the app is uninstalled.

 

I suspect you need access to specific information (for example 'customer id') so you're looking to add code to the theme? Some apps guide merchants through an install process (e.g. 1. Duplicate your live theme 2. Open theme editor, 3. Find theme.liquid, etc), this can be a little safer and also implies how to remove the code.

 

If you do go down the path of programatically inserting code, here are some things to keep in mind:

  • All themes will have a theme.liquid, this would be the best place to insert the code.
  • Optionally, create a snippet and then render the snippet in theme.liquid.
  • If it's JavaScript, look for </body>, and insert the code on the line above.
  • Consider wrapping the code in an identifier, this will make removing the code easier. For example:

 

<!-- Begin App X code -->{% render 'app-x' %}<!-- End App X code --> 

 

  • Don't forget error handling. </body> might not always exist, and your identifier might get modified.
  • You can listen to the app/uninstall webhook to detect app uninstalls, but by the time you get notified you won't have API access. Some apps email users with clean up instructions.

Finally, plan for worst case scenario. Assume you code doesn't get removed, it should fail gracefully. Maybe a subtle log to console "It looks like you've uninstalled App X, please remove ... from ...".

 

Are you able to describe what your app's doing / the reason for the code?

 

0 Likes
New Member
3 0 0

Hi there

 

All the problems you've outlaid are those that I had concern with. In the end I've elected to stick with the more straightforward 'give the merchant clear instructions' as I feel this is actually the best experience - it's clear what they're adding and where, and they know what to remove when they're done.

 

I had worked along the lines that you'd suggested already - create snippet (trivial), and referencing the snippet in liquid - the biggest (and in my view inescapable) hurdle is finding where to inject the reference. I'm commenting here more in the hope it helps someone else who follows and is finding the same issues; these are:

 

  • You don't know which template a theme may be using; in my case I was looking for sections/cart-template.liquid but given that can be called anything you actually have to go back a level to templates/cart.liquid and try to extract from there which section is used to populate the cart. And even then, it's possible that the answer is 'none', and all the cart liquid resides in the template
  • Once you've identified the template (and you can always abandon installation at step 1 if you can't find an obvious candidate) then you have to find a reference element to pop your own include reference next to; provided every .liquid file had one, and only one <h1> element then that would be fine, but what if the theme designer wrote that as an <h2> tag...
  • Assuming you can find that element then you can add your reference. And then write the section code back but:
    • what if another app has written to it in the meantime - you're now in a race condition
    • you need to store a backup of the original, just in case you need to back out but (see point above) - another potential race condition
  • And then there's the uninstall issue - which  you have no control over, and even if you did you meet all the same issues as in the bullet point above.

I also personally found liquid an absolute git to parse.  The idea of automatically installing an app for the merchant is lovely, but the practice feels fraught with difficulty which is easily overcome by letting the human make the decision.

 

My app is now published in the store, so I guess time will tell if users find installation easy or hard...

 

Cheers,

Gary.

 

0 Likes
Shopify Staff
Shopify Staff
391 53 62

Hey Gary.

 

Congrats on publishing.

 

It sounds like a lot of your headaches were caused by needing the code inserted in a specific location - i'm curious, are you able to elaborate why/what the app's doing?

0 Likes
Highlighted
New Member
3 0 0

Sorry - quick delay whilst stuck in DIY hell. The app is the In Cart Incentivizer (https://apps.shopify.com/in-cart-incentivizer?surface_detail=sales-and-conversion-optimization-upsel...) - it's adding a progress bar to the marchant's cart, so any number of places they could choose to place it rather than once specific place. Though if there was certainty that the one specific place would always exist it wouldn't half make life easier!

 

Cheers,

Gary.

 

 

0 Likes