How to integrate with a legacy theme?

Currently, most themes already support Online Store 2.0, however if you are using a legacy theme, follow the steps below to integrate with your theme.

This tutorial requires technical knowledge and Shopify Liquid. If you're not very technical, contact us and we'll help you implement it.

Open your theme editor

To get started, open Shopify Admin > Theme editor

Prepare Liquid snippet files

First of all, you need to create 3 Liquid snippet files

  • snippets/doran-sv-video.liquid
  • snippets/doran-sv-product.liquid
  • snippets/doran-sv-widget.liquid
...
doran-sv-widget.liquid
doran-sv-product.liquid
doran-sv-video.liquid
...
{%- liquid
  assign default_variant = product.selected_or_first_available_variant
  assign reviews_count = blank
  assign average_rating = blank
  assign review_app_type = shop.metafields.doran.sv_review_app
  assign is_carousel_view_external_product = shop.metafields.doran.sv_is_carousel_view_external_product | default: false
  assign is_grid_view_external_product = shop.metafields.doran.sv_is_grid_view_external_product | default: false
  assign is_popup_view_external_product = shop.metafields.doran.sv_is_popup_view_external_product | default: false
  assign custom_product_section_id = shop.metafields.doran.custom_product_section_id
  assign is_external_product = false
  
  if widget_type == 'carousel' and is_carousel_view_external_product == true and is_popup_view_external_product == true
    assign is_external_product = true
  endif
    
  if widget_type == 'grid' and is_grid_view_external_product == true and is_popup_view_external_product == true
    assign is_external_product = true
  endif

  if custom_product_section_id != blank
    assign is_external_product = true
  endif

  case review_app_type
    when 'Doran'
      assign reviews_count = product.metafields.doran.prReviewCount | default: 0
      assign average_rating = product.metafields.doran.prAvgRating | default: 0
    when 'JudgeMe'
      assign reviews_count = product.metafields.reviews.rating_count | default: 0
      assign average_rating = product.metafields.reviews.rating.value | default: 0
    when 'Loox'
      assign reviews_count = product.metafields.loox.num_reviews | default: 0
      assign average_rating = product.metafields.loox.avg_rating | default: 0
    when 'AirReviews'
      assign reviews_count = product.metafields.air_reviews_product.review_count | default: 0
      assign average_rating = product.metafields.air_reviews_product.review_avg | default: 0
  endcase
-%}

var pv{{product.id}} = [];
var powv{{product.id}} = [];
var pmd{{product.id}} = [];

{%- if is_external_product == false -%}
  {%- for variant in product.variants -%}
    pv{{product.id}}.push({
      "id": "{{ variant.id }}",
      "title": "{{ variant.title | replace: '"', '%22' }}",
      {%- if variant.featured_image -%}
        "featuredImage": "{{ variant.featured_image | image_url: width: 300, height: 400 | replace: '"', '%22' }}",
      {%- endif -%}
      "price": "{{ variant.price | default: 0 | money_with_currency | replace: '"', '%22' }}",
      "options": {{ variant.options | json }},
      "available": {{ variant.available }},
      "compareAtPrice": "{{ variant.compare_at_price | default: 0 | money_with_currency | replace: '"', '%22' }}"
    });
  {%- endfor -%}

  {%- for productOption in product.options_with_values -%}
    var productOptionValueItem = [
      {%- if productOption.values.size > 0 -%}
        {%- for productOptionValue in productOption.values -%}
          {
            "id": "{{ productOptionValue.id }}",
            "name": "{{ productOptionValue.name | replace: '"', '%22' }}",
            "available": {{ productOptionValue.available | default: false }},
            {%- if productOptionValue.variant.image -%}
              "image": "{{ productOptionValue.variant.image | image_url: width: 300, height: 400 | replace: '"', '%22' }}",
            {%- endif -%}
            "price": "{{ productOptionValue.variant.price | default: 0 | money_with_currency | replace: '"', '%22' }}"
          },
        {%- endfor -%}
      {%- endif -%}
    ];
    powv{{product.id}}.push({
      "name": "{{ productOption.name | replace: '"', '%22' }}",
      "position": {{ productOption.position }},
      "values": productOptionValueItem
    });
  {%- endfor -%}
{%- endif -%}

{%- for media in product.media -%}
  var mediaByType{{media.id}};
  {%- case media.media_type -%}
    {%- when 'image' -%}
      mediaByType{{media.id}} = "{{ media.preview_image | image_url: width: 600, height: 600 | replace: '"', '%22' }}";
    {%- when 'video' -%}
      {%- liquid
        assign mp4_source = media.sources | where: "format", "mp4" | first
      -%}
      mediaByType{{media.id}} = {
        "mp4": "{{ mp4_source.url | default: '' }}"
      };
    {%- when 'external_video' -%}
      mediaByType{{media.id}} = "{{ media | external_video_url | replace: '"', '%22' }}";
    {%- when 'model' -%}
      mediaByType{{media.id}} = "{{ media | model_viewer_tag | replace: '"', '%22' }}";
    {%- else -%}
      mediaByType{{media.id}} = '';
  {%- endcase -%}
  pmd{{product.id}}.push({
    "media": mediaByType{{media.id}},
    "position": {{ media.position }},
    "mediaType": "{{ media.media_type }}",
    "previewImage": "{{ media.preview_image | image_url: width: 600, height: 600 | replace: '"', '%22' }}"
  });
{%- endfor -%}

var p{{product.id}} = {
  "id": "{{ product.id }}",
  "url": "{{ product.url | replace: '"', '%22'}}",
  "name": "{{ product.title }}",
  "variantsCount": {{ product.variants_count | default: 0 }},
  "available": {{ product.available | default: false }},
  {%- unless reviews_count == blank -%}
  "reviewsCount": {{ reviews_count }},
  {%- endunless -%}
  {%- unless average_rating == blank -%}
  "averageRating": {{ average_rating }},
  {%- endunless -%}
  {%- if is_external_product == false -%}
  "variants": pv{{product.id}},
  {%- endif -%}
  {%- if product.featured_image -%}
    "featuredImage": "{{ product.featured_image | image_url: width: 60, height: 60 | replace: '"', '%22' }}",
  {%- endif -%}
  "media": pmd{{product.id}},
  "price": "{{ product.price | default: 0 | money_with_currency | replace: '"', '%22' }}",
  {%- if product.price_max != product.price_min -%}
    "priceMax": "{{ product.price_max | default: 0 | money_with_currency | replace: '"', '%22' }}",
  {%- endif -%}
  {%- if product.price_max != product.price_min -%}
    "priceMin": "{{ product.price_min | default: 0 | money_with_currency | replace: '"', '%22' }}",
  {%- endif -%}
  "compareAtPrice": "{{ product.compare_at_price | default: 0 | money_with_currency | replace: '"', '%22' }}",
  {%- if product.description != blank and is_external_product == false -%}
    "description": "{{ product.description | strip_newlines | replace: '"', "'" | replace: '\', '\\' }}",
  {%- endif -%}
  {%- if is_external_product == false -%}
    "optionWithValues": powv{{product.id}},
  {%- endif -%}
  "compareAtPriceMin": "{{ product.compare_at_price_min | default: 0 | money_with_currency | replace: '"', '%22' }}",
  "compareAtPriceMax": "{{ product.compare_at_price_max | default: 0 | money_with_currency | replace: '"', '%22' }}"
  {%- if is_external_product == false -%}
    ,
    "selectedVariant": {
      "id": "{{ default_variant.id }}",
      "available": {{ default_variant.available | default: false }},
      "title": "{{ default_variant.title | replace: '"', '%22' }}",
      "price": "{{ default_variant.price | default: 0 | money_with_currency | replace: '"', '%22' }}",
      "compareAtPrice": "{{ default_variant.compare_at_price | default: 0 | money_with_currency | replace: '"', '%22' }}",
      {%- if default_variant.featured_image -%}
        "featuredImage": "{{ default_variant.featured_image | image_url: width: 300, height: 400 | replace: '"', '%22' }}",
      {%- elsif product.featured_image -%}
        "featuredImage": "{{ product.featured_image | image_url: width: 300, height: 400 | replace: '"', '%22' }}",
      {%- endif -%}
      "options": {{ default_variant.options | json }}
    }
  {%- endif -%}
};
{%- if video.status == "Published" -%}
  {%- liquid
    assign mp4_source = video.main_video.value.sources | where: "format", "mp4" | first
    assign mp4_loop_video_source = video.loop_video.value.sources | where: "format", "mp4" | first
    assign custom_video = video.custom_video | default: '' | replace: '"', '%22'
    assign story_thumbnail_source = video.main_video.value.preview_image | image_url: width: 100, height: 100 | replace: '"', '%22'
    assign carousel_thumbnail_source = video.main_video.value.preview_image | image_url: width: 900, height: 1600 | replace: '"', '%22'
    assign pop_thumbnail_source = video.main_video.value.preview_image | image_url: width: 300, height: 400 | replace: '"', '%22'
    assign custom_loop_video = video.custom_loop_video | default: '' | replace: '"', '%22'
    assign custom_thumbnail = video.custom_thumbnail
  -%}

  var productsList = [{%- for product in products -%}p{{ product.id }},{%- endfor -%}];

  videos.push({
    "id": "{{ video.system.handle }}",
    "name": "{{ video.name | replace: '"', "'" }}",
    {%- if custom_video != blank -%}
      "mp4Video": "{{ custom_video }}",
    {%- elsif mp4_source != blank -%}
      "mp4Video": "{{ mp4_source.url | default: '' }}",
    {%- endif -%}
    {%- if custom_loop_video != blank -%}
      "customLoopVideo": "{{ custom_loop_video }}",
    {%- elsif mp4_loop_video_source != blank -%}
      "mp4LoopVideo": "{{ mp4_loop_video_source.url | default: '' }}",
    {%- endif -%}
    {%- if widget_type == 'carousel' or widget_type == 'grid' -%}
      {%- if custom_thumbnail != blank -%}
        "carouselThumbnail": "{{ custom_thumbnail | image_url: width: 900, height: 1600 | replace: '"', '%22' }}",
      {%- elsif carousel_thumbnail_source != blank -%}
        "carouselThumbnail": "{{ carousel_thumbnail_source }}",
      {%- endif -%}
    {%- elsif widget_type == 'pop' -%}
      {%- if custom_thumbnail != blank -%}
        "popThumbnail": "{{ custom_thumbnail | image_url: width: 300, height: 300 | replace: '"', '%22' }}",
      {%- elsif pop_thumbnail_source != blank -%}
        "popThumbnail": "{{ pop_thumbnail_source }}",
      {%- endif -%}
    {%- elsif widget_type == 'story' -%}
      {%- if custom_thumbnail != blank -%}
        "storyThumbnail": "{{ custom_thumbnail | image_url: width: 100, height: 100 | replace: '"', '%22' }}",
      {%- elsif story_thumbnail_source != blank -%}
        "storyThumbnail": "{{ story_thumbnail_source }}",
      {%- endif -%}
    {%- endif -%}
    "products": productsList
  });
{%- endif -%}
{%- liquid
  assign widget = metaobjects["app--257812725761--widget"][widget_id]
  assign published_widget_videos = widget.videos.value | where: "status", "Published"

  assign proceed_product_ids = ''

  assign published_videos = widget.videos.value | where: 'status', 'Published'
  capture scripts
    for video in published_videos
      for product in video.products.value
        if proceed_product_ids contains product.id
          continue
        endif
        assign proceed_product_ids = proceed_product_ids | append: product.id | append: ','
        render 'doran-sv-product', product: product
      endfor
    endfor

    for video in published_widget_videos
      render 'doran-sv-video', video: video, products: video.products.value, widget_type: widget_type
    endfor
  endcapture
-%}

<script>
  (function(){
    window.$svDoranInit = window.$svDoranInit || {};
    window.$svDoranInit.widgets = window.$svDoranInit.widgets || [];
    var widget = {"id":"{{ widget.system.handle }}","videos":[]};
    var videos = [];
    {{ scripts }}
    widget.videos = videos;
    window.$svDoranInit.widgets.push(widget);
  })();
</script>

<div
  class="dr-basic-widget"
  data-dr="{{ widget_type | default: "carousel" | downcase }}-widget"
  data-dr-widget-id="{{ widget.system.handle }}"></div>

Render the liquid

You have prepared all the necessary files, now you can display the widget where you want it to appear.

{%- render "doran-sv-widget", widget_id: "[Widget ID]", widget_type: "[Widget Type]" -%}

In the snippet above, we use 2 variables that you can change.

[Widget ID]

This is the variable that tells us which widget you want to display, follow our steps to get the Widget ID.

Access your widget in Shopify Admin

Access the menu

Copy the widget ID

Copy the Widget ID

[Widget Type]

We support 4 types of widgets.

Widget Type
Grid
Carousel
Pop
Stories

On this page

Need help?

You are having problems and need our support. Please contact us here.