How to update theme files using API

Milind2
Excursionist
25 0 6

Hi Everyone,

Hope all are doing well.

I want to update the theme files(ex. product-template.liquid) when my app is installed in store.

Please help me out to update liquid files using API.

0 Likes
Alex
Shopify Staff
Shopify Staff
1555 81 293

Did you check the documentation? You can do so with the assets endpoint.

0 Likes
Milind2
Excursionist
25 0 6

Hi Alex Richter,

Thanks for your reply.

I used the following assets API to first get the current .liquid contents:

GET /admin/themes/#{theme_id}/assets.json?asset[key]=templates/index.liquid&theme_id=828155753

Then I added my extra code to the fetched contents and I used the following api to update the existing theme file

PUT /admin/themes/#{theme_id}/assets.json
{
  "asset": {
    "key": "templates/index.liquid",
    "value": "<img src='backsoon-postit.png'><p>We are busy updating the store for you and will be back within the hour.</p>"
  }
}

But It returns error regarding invalid data and theme file do not get updated.

Is there any specfic method using which I can convert the contents that are updated, so that API will accept my new updated contents?

Can you please help me out to accomplish this.

Alex
Shopify Staff
Shopify Staff
1555 81 293

You're going to have to provide more details on what's happening from your perspective. Do you have a specific response and/or `X-Request-Id` response header I can look at?

0 Likes
Milind2
Excursionist
25 0 6

Hi Alex Richter,

Below is the response I get when I try to update theme file.

Hope this will help to understand what is the issue.

Response:
ShopifyApiException Object
(
    [method:protected] => PUT
    [path:protected] => /admin/themes/182107796/assets.json
    [params:protected] => Array
        (
            [asset] => Array
                (
                    [key] => sections\/product-template.liquid
                    [value] => 

{% comment %} Get first variant, or deep linked one {% endcomment %} {%- assign current_variant = product.selected_or_first_available_variant -%} {%- assign product_image_zoom_size = '1024x1024' -%} {%- assign product_image_scale = '2' -%} {%- assign enable_zoom = section.settings.enable_zoom -%} {% case section.settings.image_size %} {% when 'small' %} {%- assign product_image_width = 'medium-up--one-third' -%} {%- assign product_description_width = 'medium-up--two-thirds' -%} {%- assign product_thumbnail_width = 'medium-up--one-third' -%} {%- assign height = 345 -%} {% when 'medium' %} {%- assign product_image_width = 'medium-up--one-half' -%} {%- assign product_description_width = 'medium-up--one-half' -%} {%- assign product_thumbnail_width = 'medium-up--one-quarter' -%} {%- assign height = 530 -%} {% when 'large' %} {%- assign product_image_width = 'medium-up--two-thirds' -%} {%- assign product_description_width = 'medium-up--one-third' -%} {%- assign product_thumbnail_width = 'medium-up--one-fifth' -%} {%- assign height = 720 -%} {% when 'full' %} {%- assign product_image_width = '' -%} {%- assign product_description_width = '' -%} {%- assign product_thumbnail_width = 'medium-up--one-eighth' -%} {%- assign height = 1090 -%} {%- assign enable_zoom = false -%} {% endcase %}{%- assign featured_image = product.selected_or_first_available_variant.featured_image | default: product.featured_image -%} {% for image in product.images %} {% capture img_id %}FeaturedImage-{{ section.id }}-{{ image.id }}{% endcapture %} {% capture img_class %}product-featured-img{% endcapture %} {% capture zoom_img_id %}FeaturedImageZoom-{{ section.id }}-{{ image.id }}{% endcapture %} {% capture img_wrapper_id %}{{ zoom_img_id }}-wrapper{% endcapture %} {%- assign img_url = image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%} {% include 'image-style' with small_style: true, width: height, height: height, wrapper_id: img_wrapper_id, img_id: img_id %}

{{ image.alt | escape }}

{% endfor %} {% if product.images.size > 1 %} {% if product.images.size > 3 %} {%- assign enable_thumbnail_slides = true -%} {% endif %}

{% if enable_thumbnail_slides == true %}

          {% endif %}
          
  • {% for image in product.images %}
  • {{ image.alt | escape }}
  • {% endfor %}

{% if enable_thumbnail_slides == true %}


 

{% endif %}

{% endif %}

{{ product.title }}

{% if section.settings.show_vendor %}

{{ product.vendor }}

{% endif %}

{% if current_variant.compare_at_price > current_variant.price %} {{ 'products.product.regular_price' | t }} {{ current_variant.compare_at_price | money }} {{ current_variant.price | money }} {{ 'products.product.on_sale' | t }} {% else %} {{ 'products.product.regular_price' | t }} {{ current_variant.compare_at_price | money }} {{ current_variant.price | money }} {{ 'products.product.on_sale' | t }} {% endif %}

{% unless product.options.size == 1 and product.variants[0].title == 'Default Title' %} {% for option in product.options_with_values %}

{{ option.name }}


 

{% endfor %} {% endunless %}


            {% if section.settings.show_quantity_selector %}
              

{{ 'products.product.quantity' | t }}

{% endif %}


 

{{ product.description }}

{% if section.settings.show_share_buttons %} {% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %} {% endif %}

{% if collection %}

{% include 'icon-arrow-left' %} {{ 'products.product.back_to_collection' | t: title: collection.titl...

{% endif %} {% unless product == empty %} {% endunless %} {% schema %} { "name": "Product pages", "settings": [ { "type": "select", "id": "image_size", "label": "Image size", "options": [ { "value": "small", "label": "Small" }, { "value": "medium", "label": "Medium" }, { "value": "large", "label": "Large" }, { "value": "full", "label": "Full-width" } ], "default": "medium" }, { "type": "checkbox", "id": "show_quantity_selector", "label": "Show quantity selector", "default": false }, { "type": "checkbox", "id": "show_variant_labels", "label": "Show variant labels", "default": true }, { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false }, { "type": "checkbox", "id": "enable_zoom", "label": "Enable image zoom", "default": true }, { "type": "checkbox", "id": "show_share_buttons", "label": "Show social sharing buttons", "default": true } ] } {% endschema %} ) ) [response_headers:protected] => Array ( [http_status_code] => 400 [http_status_message] => Bad Request [server] => nginx [date] => Thu, 12 Apr 2018 06:55:21 GMT [content-type] => application/json [transfer-encoding] => chunked [connection] => keep-alive [x-sorting-hat-podid] => 79 [x-sorting-hat-podid-cached] => 1 [x-sorting-hat-shopid] => 22383817 [x-sorting-hat-section] => pod [x-sorting-hat-shopid-cached] => 1 [x-content-type-options] => nosniff [x-download-options] => noopen [x-permitted-cross-domain-policies] => none [x-xss-protection] => 1; mode=block [x-dc] => chi2,gcp-us-central1 [via] => 1.1 google [alt-svc] => clear [x-request-id] => b0cee1d1-a355-4d33-bb90-409d2e959776 ) [response:protected] => Array ( [error] => 822: unexpected token at '{"asset":{"key":"sections\/product-template.liquid","value":"

n n n nn {% comment %}n Get first variant, or deep linked onen {% endcomment %}n {%- assign current_variant = product.selected_or_first_available_variant -%}n {%- assign product_image_zoom_size = '1024x1024' -%}n {%- assign product_image_scale = '2' -%}n {%- assign enable_zoom = section.settings.enable_zoom -%}nn {% case section.settings.image_size %}n {% when 'small' %}n {%- assign product_image_width = 'medium-up--one-third' -%}n {%- assign product_description_width = 'medium-up--two-thirds' -%}n {%- assign product_thumbnail_width = 'medium-up--one-third' -%}n {%- assign height = 345 -%}n {% when 'medium' %}n {%- assign product_image_width = 'medium-up--one-half' -%}n {%- assign product_description_width = 'medium-up--one-half' -%}n {%- assign product_thumbnail_width = 'medium-up--one-quarter' -%}n {%- assign height = 530 -%}n {% when 'large' %}n {%- assign product_image_width = 'medium-up--two-thirds' -%}n {%- assign product_description_width = 'medium-up--one-third' -%}n {%- assign product_thumbnail_width = 'medium-up--one-fifth' -%}n {%- assign height = 720 -%}n {% when 'full' %}n {%- assign product_image_width = '' -%}n {%- assign product_description_width = '' -%}n {%- assign product_thumbnail_width = 'medium-up--one-eighth' -%}n {%- assign height = 1090 -%}n {%- assign enable_zoom = false -%}n {% endcase %}nnnn {%- assign featured_image = product.selected_or_first_available_variant.featured_image | default: product.featured_image -%}n {% for image in product.images %}n {% capture img_id %}FeaturedImage-{{ section.id }}-{{ image.id }}{% endcapture %}n {% capture img_class %}product-featured-img{% endcapture %}n {% capture zoom_img_id %}FeaturedImageZoom-{{ section.id }}-{{ image.id }}{% endcapture %}n {% capture img_wrapper_id %}{{ zoom_img_id }}-wrapper{% endcapture %}n {%- assign img_url = image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}nn {% include 'image-style' with small_style: true, width: height, height: height, wrapper_id: img_wrapper_id, img_id: img_id %}nnn

n {{ image.alt | escape }}n

nn {% endfor %}nn nn {% if product.images.size > 1 %}n {% if product.images.size > 3 %}n {%- assign enable_thumbnail_slides = true -%}n {% endif %}nn

n {% if enable_thumbnail_slides == true %}n

n          {% endif %}n          
  • n {% for image in product.images %}n
  • n n {{ image.alt | escape }}n n
  • n {% endfor %}n

n {% if enable_thumbnail_slides == true %}n


 

n {% endif %}n

n {% endif %}n

nn

nnn

{{ product.title }}

nn {% if section.settings.show_vendor %}n

{{ product.vendor }}

n {% endif %}nnn nn nn

n {% if current_variant.compare_at_price > current_variant.price %}n {{ 'products.product.regular_price' | t }}n {{ current_variant.compare_at_price | money }}n n n {{ current_variant.price | money }}n n {{ 'products.product.on_sale' | t }}n n {% else %}n {{ 'products.product.regular_price' | t }}n {{ current_variant.compare_at_price | money }}n n n {{ current_variant.price | money }}n n {{ 'products.product.on_sale' | t }}n n {% endif %}n

nn

n {% unless product.options.size == 1 and product.variants[0].title == 'Default Title' %}n {% for option in product.options_with_values %}n

n n {{ option.name }}n n


 

n

n {% endfor %}n {% endunless %}nn

nn            {% if section.settings.show_quantity_selector %}n              

n {{ 'products.product.quantity' | t }}n n

n {% endif %}nn

n


 

n

n

nnnn

n {{ product.description }}n

nn {% if section.settings.show_share_buttons %}n {% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %}n {% endif %}nnnnn

nn{% if collection %}n

n n {% include 'icon-arrow-left' %}n {{ 'products.product.back_to_collection' | t: title: collection.t...n

n{% endif %}nn{% unless product == empty %}n n{% endunless %}nnn{% schema %}n {n "name": "Product pages",n "settings": [n {n "type": "select",n "id": "image_size",n "label": "Image size",n "options": [n {n "value": "small",n "label": "Small"n },n {n "value": "medium",n "label": "Medium"n },n {n "value": "large",n "label": "Large"n },n {n "value": "full",n "label": "Full-width"n }n ],n "default": "medium"n },n {n "type": "checkbox",n "id": "show_quantity_selector",n "label": "Show quantity selector",n "default": falsen },n {n "type": "checkbox",n "id": "show_variant_labels",n "label": "Show variant labels",n "default": truen },n {n "type": "checkbox",n "id": "show_vendor",n "label": "Show vendor",n "default": falsen },n {n "type": "checkbox",n "id": "enable_zoom",n "label": "Enable image zoom",n "default": truen },n {n "type": "checkbox",n "id": "show_share_buttons",n "label": "Show social sharing buttons",n "default": truen }n ]n }n{% endschema %}n"}}' ) [message:protected] => Bad Request [string:Exception:private] => [code:protected] => 400 [file:protected] => /Applications/XAMPP/xamppfiles/htdocs/DemoApp/application/libraries/Shopifyapi.php [line:protected] => 77 [trace:Exception:private] => Array ( [0] => Array ( [file] => /Applications/XAMPP/xamppfiles/htdocs/DemoApp/application/controllers/Homepage.php [line] => 560 [function] => call [class] => Shopifyapi [type] => -> [args] => Array ( [0] => PUT [1] => /admin/themes/182107796/assets.json [2] => Array ( [asset] => Array ( [key] => sections\/product-template.liquid [value] =>

{% comment %} Get first variant, or deep linked one {% endcomment %} {%- assign current_variant = product.selected_or_first_available_variant -%} {%- assign product_image_zoom_size = '1024x1024' -%} {%- assign product_image_scale = '2' -%} {%- assign enable_zoom = section.settings.enable_zoom -%} {% case section.settings.image_size %} {% when 'small' %} {%- assign product_image_width = 'medium-up--one-third' -%} {%- assign product_description_width = 'medium-up--two-thirds' -%} {%- assign product_thumbnail_width = 'medium-up--one-third' -%} {%- assign height = 345 -%} {% when 'medium' %} {%- assign product_image_width = 'medium-up--one-half' -%} {%- assign product_description_width = 'medium-up--one-half' -%} {%- assign product_thumbnail_width = 'medium-up--one-quarter' -%} {%- assign height = 530 -%} {% when 'large' %} {%- assign product_image_width = 'medium-up--two-thirds' -%} {%- assign product_description_width = 'medium-up--one-third' -%} {%- assign product_thumbnail_width = 'medium-up--one-fifth' -%} {%- assign height = 720 -%} {% when 'full' %} {%- assign product_image_width = '' -%} {%- assign product_description_width = '' -%} {%- assign product_thumbnail_width = 'medium-up--one-eighth' -%} {%- assign height = 1090 -%} {%- assign enable_zoom = false -%} {% endcase %}{%- assign featured_image = product.selected_or_first_available_variant.featured_image | default: product.featured_image -%} {% for image in product.images %} {% capture img_id %}FeaturedImage-{{ section.id }}-{{ image.id }}{% endcapture %} {% capture img_class %}product-featured-img{% endcapture %} {% capture zoom_img_id %}FeaturedImageZoom-{{ section.id }}-{{ image.id }}{% endcapture %} {% capture img_wrapper_id %}{{ zoom_img_id }}-wrapper{% endcapture %} {%- assign img_url = image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%} {% include 'image-style' with small_style: true, width: height, height: height, wrapper_id: img_wrapper_id, img_id: img_id %}

{{ image.alt | escape }}

{% endfor %} {% if product.images.size > 1 %} {% if product.images.size > 3 %} {%- assign enable_thumbnail_slides = true -%} {% endif %}

{% if enable_thumbnail_slides == true %}

          {% endif %}
          
  • {% for image in product.images %}
  • {{ image.alt | escape }}
  • {% endfor %}

{% if enable_thumbnail_slides == true %}


 

{% endif %}

{% endif %}

{{ product.title }}

{% if section.settings.show_vendor %}

{{ product.vendor }}

{% endif %}

{% if current_variant.compare_at_price > current_variant.price %} {{ 'products.product.regular_price' | t }} {{ current_variant.compare_at_price | money }} {{ current_variant.price | money }} {{ 'products.product.on_sale' | t }} {% else %} {{ 'products.product.regular_price' | t }} {{ current_variant.compare_at_price | money }} {{ current_variant.price | money }} {{ 'products.product.on_sale' | t }} {% endif %}

{% unless product.options.size == 1 and product.variants[0].title == 'Default Title' %} {% for option in product.options_with_values %}

{{ option.name }}


 

{% endfor %} {% endunless %}


            {% if section.settings.show_quantity_selector %}
              

{{ 'products.product.quantity' | t }}

{% endif %}


 

{{ product.description }}

{% if section.settings.show_share_buttons %} {% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %} {% endif %}

{% if collection %}

{% include 'icon-arrow-left' %} {{ 'products.product.back_to_collection' | t: title: collection.titl...

{% endif %} {% unless product == empty %} {% endunless %} {% schema %} { "name": "Product pages", "settings": [ { "type": "select", "id": "image_size", "label": "Image size", "options": [ { "value": "small", "label": "Small" }, { "value": "medium", "label": "Medium" }, { "value": "large", "label": "Large" }, { "value": "full", "label": "Full-width" } ], "default": "medium" }, { "type": "checkbox", "id": "show_quantity_selector", "label": "Show quantity selector", "default": false }, { "type": "checkbox", "id": "show_variant_labels", "label": "Show variant labels", "default": true }, { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false }, { "type": "checkbox", "id": "enable_zoom", "label": "Enable image zoom", "default": true }, { "type": "checkbox", "id": "show_share_buttons", "label": "Show social sharing buttons", "default": true } ] } {% endschema %} ) ) ) ) [1] => Array ( [file] => /Applications/XAMPP/xamppfiles/htdocs/DemoApp/system/core/CodeIgniter.php [line] => 514 [function] => themeupdate [class] => Homepage [type] => -> [args] => Array ( ) ) [2] => Array ( [file] => /Applications/XAMPP/xamppfiles/htdocs/DemoApp/index.php [line] => 295 [args] => Array ( [0] => /Applications/XAMPP/xamppfiles/htdocs/DemoApp/system/core/CodeIgniter.php ) [function] => require_once ) ) [previous:Exception:private] => )

 

I think the following error response sorted from above response may be helpful:

[response_headers:protected] => Array
        (
            [http_status_code] => 400
            [http_status_message] => Bad Request
            [server] => nginx
            [date] => Thu, 12 Apr 2018 06:55:21 GMT
            [content-type] => application/json
            [transfer-encoding] => chunked
            [connection] => keep-alive
            [x-sorting-hat-podid] => 79
            [x-sorting-hat-podid-cached] => 1
            [x-sorting-hat-shopid] => 22383817
            [x-sorting-hat-section] => pod
            [x-sorting-hat-shopid-cached] => 1
            [x-content-type-options] => nosniff
            [x-download-options] => noopen
            [x-permitted-cross-domain-policies] => none
            [x-xss-protection] => 1; mode=block
            [x-dc] => chi2,gcp-us-central1
            [via] => 1.1 google
            [alt-svc] => clear
            [x-request-id] => b0cee1d1-a355-4d33-bb90-409d2e959776
        )

    [response:protected] => Array
        (
            [error] => 822: unexpected token at '{"asset":{"key":"sections\/product-template.liquid","value":"

n n n nn {% comment %}n Get first variant, or deep linked onen {% endcomment %}n {%- assign current_variant = product.selected_or_first_available_variant -%}n {%- assign product_image_zoom_size = '1024x1024' -%}n {%- assign product_image_scale = '2' -%}n {%- assign enable_zoom = section.settings.enable_zoom -%}nn {% case section.settings.image_size %}n {% when 'small' %}..........

0 Likes
Alex
Shopify Staff
Shopify Staff
1555 81 293

It looks to me like your json might not be formatted correctly. I would suggest running everything past "822: unexpected token at" through a JSON linter.

Milind2
Excursionist
25 0 6

Hi Alex Richter,
Thank you for your help but I am still not able to update the theme files using API.

Can you please create one demo code that works and I will implement in my app.

I am requesting you for this. Please help me out am stuck into this for so many days.

Please help me.

 

Thanks and regards

 

0 Likes
Milind2
Excursionist
25 0 6

Hi Alex Richter,

Waiting for your reply. Still I have got nothing and stucked at same thing.

Any help will be appreciated.

 
0 Likes
Alex
Shopify Staff
Shopify Staff
1555 81 293

I'm not going to be able to give you a code example in your language of choice, but maybe showing you how to do it in my preferred language will help. I'll update a theme file using Ruby with the HTTParty library.

require "httparty"

uri = URI("https://shop.myshopify.com/admin/assets.json")
options = {
  headers: { "X-Shopify-Access-Token" => "9db6c3dba7b61676357aedf7nnb6b0c9" },
  body:    {
    asset: {
      key: "templates/product.liquid",
      value: "<h1>Foobar</h1>"
    }
  }
}

response = HTTParty.put(uri, options)

puts response

If you're still experiencing the same issue it's because your JSON is invalid (syntactically). I would recommend looking elsewhere for how to properly assembly a JSON body if that's what the issue still is. The above is how this is accomplished in Ruby without issue.

Cheers.

Milind2
Excursionist
25 0 6

Hi Alex Richter,

Thanks for your reply.

Can you show me how would you inject html code(for ex. <div class="my-class"></div>) at the end of product-template.liquid file?

The example you shown is one of the simplest example and I think everybody will able to add only

<h1>Foobar</h1>

into the file. i have already tried to add simple html data into the file and I am able to do it.

What I want to do is, I want to add "<div class="my-class"></div>" this html data at the end of "product-template.liquid" file with all old data exist in "product-template.liquid" file.

I hope you understood my requirement and will tell me what I should do.

0 Likes