FROM CACHE - en_header

Adding products/collection to a blog post WITHOUT the Buy Button

Solved
sanctumhealth
Tourist
5 0 1

Hi,

 

I'm hoping someone can help with this or at least, there be an easy solution.

 

I need to add products and/or collections to the bottom of a blog post.

 

I researched this and found the solution using the Buy Button but this solution conflicts with a discounts plugin we're using - via the Buy Button cart, the discounts don't appear and aren't applied.

 

The developer of the plugin has got back to say that unfrotunately, the plugin wasn't developeed to work with the dynamic checkout. The plugin is definitely more important that the buy button, so the plugin stays.

 

Is there another convenient way to list products on blog posts? Doesn't even need to be Add to Cart/Buy Now - just listings with the product images, titles and More Details links to the actual product pages would do.


Thanks in advance for any help you can offer.

Accepted Solution (1)

Accepted Solutions
Ninthony
Shopify Partner
2272 342 968

This is an accepted solution.

Depending on where you wanted to do it, you could do it inside of liquid. Say you wanted to have the products show at the bottom of the blog post, you could do this under {{ article.content }} in article.liquid. You cannot access liquid inside of your WYSIWYG editor. So if it was below the blog post it could be as simple as going under {{ article.content }} and using a forloop kind of like:

 

{{ article.content }}
{% if article.title = "Your Title for Your Blog Post" %}
{% for product in collections.your-collection.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}"
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}

Alternatively, you CAN use javascript inside your editor if you toggle the html editor (<> button on the top right).  With javascript you can create an array of products urls from the collection you want to use. You can use those urls to access the products with jQuery.

 

So this would go in script tags inside your HTML editor:

 

// product1 and product2 are the handles of your products    
var unique_array = ['/products/product1.js', '/products/product2.js']
    for (var i=0; i < unique_array.length; i++){
      jQuery.getJSON(unique_array[i], function(product){
        var lastPeriod = product.images[0].lastIndexOf('.');
// here I split the product image url by the period in case it's a jpg, or png // and give it _200x because I only want the images to be that big
var imageStringOne = product.images[0].substring(0, lastPeriod); var imageStringTwo = product.images[0].substring(lastPeriod + 1); var productImage = imageStringOne + "_200x." + imageStringTwo; var productPrice = product.price;

//build an HTML template to inject into existing html code var suggestionTemplate = '<div class="image-title__container">' + '<div class="upsell-container__product-image">' + '<img src="'+ productImage + '">' + '</div>' + '<div class="title-price__container">' + '<div class="upsell-container__title">' + product.title + '</div>' + '<div class="upsell-container__price">' + Shopify.formatMoney(productPrice) + '</div>' + '<a href="' + product.url + '">' + '<div class="upsell-container__view-product">'+ 'View' + '</div>' + '</a>' + '</div>' + '</div>'; //then after all of this, I append the suggestionTemplate variable to an html // div with the class of "suggested-products__container" that you put //wherever you want the products to populate. $('.suggested-products__container').append(suggestionTemplate); }); }

It's kind of a long winded response, and something you'll probably only be able to do if you're a bit familiar with coding. But hopefully it helps you and anyone else who might want to know how to do something like that.

 

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄

View solution in original post

Replies 28 (28)
Nick
Shopify Staff
Shopify Staff
4531 434 1007

Hi @sanctumhealth,

 

Nick here from Shopify. Great question!

 

One way you could do this is by inserting a link to some text as a hyperlink so when someone clicks on the text it would take them to the product or collection page. It can be done natively from within the blog RTE and you wouldn't need an app or a plugin to do it. Once you know what word you want to select to highlight in the blog post, you can highlight it then select the tab in the RTE as seen in the screenshot below:

 

26-40-lkiph-aj2p0

 

It will then give you a couple of different options, such as do you want the person clicking on it to have a new tab opened or take them directly from the page they are on as well as some SEO options. You can see how this would look below:

 

26-42-kz4cv-wgenu

 

Hopefully, this helps and can do what you are looking for. 

 

All the best, Nick

Nick | Community Moderator @Shopify
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ninthony
Shopify Partner
2272 342 968

This is an accepted solution.

Depending on where you wanted to do it, you could do it inside of liquid. Say you wanted to have the products show at the bottom of the blog post, you could do this under {{ article.content }} in article.liquid. You cannot access liquid inside of your WYSIWYG editor. So if it was below the blog post it could be as simple as going under {{ article.content }} and using a forloop kind of like:

 

{{ article.content }}
{% if article.title = "Your Title for Your Blog Post" %}
{% for product in collections.your-collection.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}"
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}

Alternatively, you CAN use javascript inside your editor if you toggle the html editor (<> button on the top right).  With javascript you can create an array of products urls from the collection you want to use. You can use those urls to access the products with jQuery.

 

So this would go in script tags inside your HTML editor:

 

// product1 and product2 are the handles of your products    
var unique_array = ['/products/product1.js', '/products/product2.js']
    for (var i=0; i < unique_array.length; i++){
      jQuery.getJSON(unique_array[i], function(product){
        var lastPeriod = product.images[0].lastIndexOf('.');
// here I split the product image url by the period in case it's a jpg, or png // and give it _200x because I only want the images to be that big
var imageStringOne = product.images[0].substring(0, lastPeriod); var imageStringTwo = product.images[0].substring(lastPeriod + 1); var productImage = imageStringOne + "_200x." + imageStringTwo; var productPrice = product.price;

//build an HTML template to inject into existing html code var suggestionTemplate = '<div class="image-title__container">' + '<div class="upsell-container__product-image">' + '<img src="'+ productImage + '">' + '</div>' + '<div class="title-price__container">' + '<div class="upsell-container__title">' + product.title + '</div>' + '<div class="upsell-container__price">' + Shopify.formatMoney(productPrice) + '</div>' + '<a href="' + product.url + '">' + '<div class="upsell-container__view-product">'+ 'View' + '</div>' + '</a>' + '</div>' + '</div>'; //then after all of this, I append the suggestionTemplate variable to an html // div with the class of "suggested-products__container" that you put //wherever you want the products to populate. $('.suggested-products__container').append(suggestionTemplate); }); }

It's kind of a long winded response, and something you'll probably only be able to do if you're a bit familiar with coding. But hopefully it helps you and anyone else who might want to know how to do something like that.

 

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
sanctumhealth
Tourist
5 0 1

Thanks @Nick for your reply - I was looking for something that works a bit more with the product listing functions. I think the answer below maybe what I'm after. Thanks though - much appreciated for the timely response!

sanctumhealth
Tourist
5 0 1

@Ninthony - I shall try this out. I figured there must be a way to do this with Liquid. Much appreciated and I'll let you know the outcome.

Nick
Shopify Staff
Shopify Staff
4531 434 1007

No problem at all. I am not as comfortable with editing code and thought this way could be of some use. @Ninthony, on the other hand, is quite proficient and always offer's good advice in the community. Hope it works out for you. 

Nick | Community Moderator @Shopify
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ninthony
Shopify Partner
2272 342 968

Cool let, me know. I also noticed I forgot to close my image tag in the liquid example, so be sure you do that:

 

<img src="{{ product.images[0] | img_url: '300x300' }}">
If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
sanctumhealth
Tourist
5 0 1

@Ninthony - that pretty much worked. Thanks!

I was getting a JS error saying "shopify.formatmoney is not a function".

 

Did a bit of research and ended up adding the code from this comment: https://community.shopify.com/c/Shopify-Design/quot-shopify-formatmoney-is-not-a-function-quot-error...

 

That made the products visible. Need a bit of styling but that's all fine.

One small thing - the prices listed are in dollars - is there something that needs to be added to Shopify.formatmoney that lists them as GBP?

 

Also, as a further development of this solution - is there a way to build the array via the calling the product handles in a collection or do the product handles always have to added manually? Would just automate things a bit more.

 

Cheers!

Ninthony
Shopify Partner
2272 342 968

As far as I know, there is no way to get a hold of a collection or it's products outside of liquid, which you can't use for blog posts or pages. So I think it will always have to be done manually, if someone else knows, I'd certainly welcome that information cause lord knows I could use it. 

 

As for shopify.formatMoney() , I have only ever needed USD so I hadn't even thought about it. Here's a link to where I found those javascript functions, I don't see any documentation on them. There is a link on top to the minified javascript, which is like trying to read Sanskrit, but if you can decode it have at it. I do see the function accepts a second parameter, just no idea what it does:

 

https://mayert-douglas4935.myshopify.com/pages/api

 

Otherwise the only thing I could suggest is write your own function to handle the price.

 

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
sanctumhealth
Tourist
5 0 1

OK, I managed to format the price but it was a bit of a hack, not 100% perfect and I'm surprised there's not more dialogue out there about this.

 

First off - for some reason between yesterday and today, Shopify started added CDATA tags to the script I added to the test blog post - not sure why it started doing this several hours after I placed it but there you go. It stopped the script meaning I had to move it into the theme-custom.js file first of all.

 

So once that was in place, I replaced this code:

var productPrice = product.price; 

with with this

var productPrice = product.price;
var decimalPrice = (productPrice = (productPrice / 100).toFixed(2)).split('.');

that created the decimal place so the prices were listed as 20.00 rather than 2000 - although it's a comma and not a period.

 

Then in the HTML template of the script, I replaced,

shopify.FormatMoney(productPrice) +

with

'&pound;' + decimalPrice +

which nicely displays the prices as I need them.

 

As you've said - I'm open to neater solutions if anyone has one. Pretty sure the functionality is there to do it. This works for me though.

Ninthony
Shopify Partner
2272 342 968

For whatever reason, Shopify always adds CDATA at the ends of the script, but it's never interfered with my code. Glad to see you got it worked out. 

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
Henrik3
Excursionist
49 1 6

Hi @Ninthony 

Have i understood the way too implement products in a blog correctly, by using the liqued method?

All i have to do is: Open the Article.liqued template and locate where it says {{ article.content }}?

And then copy paste this code in to the liqued template. And then the products from our coffee collection will bee displayed in our blog post, right?

{{ article.content }}

{% if article.title = "Blog post title" %}
{% for product in collections.bentax-risteri.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}">
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}

<!--New code end-->

Product collection

https://www.homebarista.dk/collections/bentax-risteri

Blog post 

https://www.homebarista.dk/blogs/journal-guides/hvordan-vaelger-jeg-de-rigtige-kaffeboenner

Ninthony
Shopify Partner
2272 342 968

Yeah should work, though I don't know why I recommended using article.title -- Instead you should use article.handle:

 

{% if article.handle = "hvordan-vaelger-jeg-de-rigtige-kaffeboenner" %}
{% for product in collections.bentax-risteri.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}">
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}
If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
Henrik3
Excursionist
49 1 6

Thank you.

But what if i wanted to display products from our coffee collection in multiple blog post.  For example in posts like these 3:

https://www.homebarista.dk/blogs/journal-guides/hvordan-vaelger-jeg-de-rigtige-kaffeboenner

https://www.homebarista.dk/blogs/journal-guides/sadan-brygger-jeg-stempelkaffe

https://www.homebarista.dk/blogs/journal-guides/sadan-rister-du-selv-groenne-kaffeboenner-det-er-let...

 

Should the article.handle then be like this, with the handles separated with a " , "?

 

{% if article.handle = "hvordan-vaelger-jeg-de-rigtige-kaffeboenner, sadan-brygger-jeg-stempelkaffe, sadan-rister-du-selv-groenne-kaffeboenner-det-er-lettere-og-sjovere-end-du-tror" %}
{% for product in collections.bentax-risteri.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}">
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}

 

Ninthony
Shopify Partner
2272 342 968

You would use an "or" condition:

{% if article.handle == "hvordan-vaelger-jeg-de-rigtige-kaffeboenner" or article.handle == "sadan-brygger-jeg-stempelkaffe" or article.handle == "sadan-rister-du-selv-groenne-kaffeboenner-det-er-lettere-og-sjovere-end-du-tror" %}
{% for product in collections.bentax-risteri.products %}
<div class="product-container">
<div class="product-image">
<img src="{{ product.images[0] | img_url: '300x300' }}">
</div>
<div class="product-title">
{{ product.title }}
</div>
<div class="view-details">
<a href="{{ product.url }}">View Details</a>
</div>
</div>
{% endfor%}
{% endif %}

Also my apologies, I didnt notice I had a syntax error, you should be using double == signs in the if statement (article.handle == 'article-handle') -- One equal sign is an assignment operator, two equal signs is a comparison operator. If this is something that you plan on using often, I'd suggest creating a javascript function in your JS file that you can just call every blog post so you don't have to constantly be adding new conditions to the if statement.

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
moderntribe
Excursionist
11 0 5

Hi! I was able to figure this out using the District theme to put a featured collection preview. My full write up on this is here: https://moderntribe.com/blogs/news/how-to-add-a-featured-collection-to-blog-post-in-shopify

 

Paste this below this section in article-template.liquid below the following 2 lines:

            

   {{ article.content }}
   </div>

 

 

{%- assign tag = article.image.alt -%}
{%- assign collection = collections[tag] -%}
{%- assign product_limit = 8 -%}


{% if collection.products.size > 0 %}
<div class="featured-collection layout-8 lazyload" data-section-id="{{ section.id }}" data-section-type="featured-collection-section">
<div class="wrapper">
    <div class="grid">
      <div class="box header">
        <div class="image-table">
          <div class="details">
              <h4>Shop {{ collection.title | escape }}</h4>
          </div>
        </div>
      </div>
      {% for product in collection.products limit: product_limit  %}
       {% include 'product-grid-item' %}
      {% else %}
        {% for i in (1..product_limit) %}
          {% include 'placeholder-product-grid-item' %}
        {% endfor %}
      {% endfor %}
    </div>
       <div class="box header">
        <div class="image-table">
          <div class="details">
              <a href="{{ collection.url }}" class="button large outline">View more</a>             </div>
        </div>
      </div>
  </div>
</div>
{%endif%}

 

Henrik3
Excursionist
49 1 6

Hi 

That sound like a great solution. But we use a retina theme, which does have a feature-collection layout.

How ever, on our frontpage we have a section called "kaffebønner" homebarista.dk. Which just might do the trick.  Now i just have to locate the code somewhere. 

Ninthony
Shopify Partner
2272 342 968

Nice, I like the additions you made to my code too. Your blogs look very nice.

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄
Henrik3
Excursionist
49 1 6

Hi @Ninthony 

Have I understood the way to implement products in the blogs html correctly, by placing the script code in liqued after {{article.content}}.

And then place this html code in the blog post's html editor? Or is it two different methods of doing it ?

// product1 and product2 are the handles of your products    
var unique_array = ['/products/product1.js', '/products/product2.js']
    for (var i=0; i < unique_array.length; i++){
      jQuery.getJSON(unique_array[i], function(product){
        var lastPeriod = product.images[0].lastIndexOf('.');
// here I split the product image url by the period in case it's a jpg, or png // and give it _200x because I only want the images to be that big
var imageStringOne = product.images[0].substring(0, lastPeriod); var imageStringTwo = product.images[0].substring(lastPeriod + 1); var productImage = imageStringOne + "_200x." + imageStringTwo; var productPrice = product.price;

//build an HTML template to inject into existing html code var suggestionTemplate = '<div class="image-title__container">' + '<div class="upsell-container__product-image">' + '<img src="'+ productImage + '">' + '</div>' + '<div class="title-price__container">' + '<div class="upsell-container__title">' + product.title + '</div>' + '<div class="upsell-container__price">' + Shopify.formatMoney(productPrice) + '</div>' + '<a href="' + product.url + '">' + '<div class="upsell-container__view-product">'+ 'View' + '</div>' + '</a>' + '</div>' + '</div>'; //then after all of this, I append the suggestionTemplate variable to an html // div with the class of "suggested-products__container" that you put //wherever you want the products to populate. $('.suggested-products__container').append(suggestionTemplate); }); }

and then swap line of code that says :

var unique_array = ['/products/product1.js', '/products/product2.js']

With this:

var unique_array = ['/products/all-day-blend.js', '/products/all-day-espresso-roast.js']

 

I must bee missing something in the code, because the products are not displayed in my blog. https://www.homebarista.dk/blogs/journal-guides/sadan-brygger-jeg-stempelkaffe

Ninthony
Shopify Partner
2272 342 968

There are 2 different ways of doing it. If you're using liquid you would have to do it in article.liquid, but if you're using Javascript (which is what you posted, that's not HTML other than the string template I built), you would open your blog post and press the Show HTML button, which is located in the top right of the WYSIWYG Editor, looks kinda like this: [ <> ]

 

Then you would put the script at the bottom of the post inside script tags, and then make sure that you create an element with the class of "suggested-products__container" where you want your products to show up. If you need help just DM me your store and I can request access to your blog posts and tweak it for you so it's working, that way you can just copy and paste it into future blogs and just switch out the product handles.

Also, that is built using jQuery (a javascript library) -- you may not have that on your theme. I could rework it to just use javascript though if it needs it.

If my solution helped you, please like it and accept it as the solution!
If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish 😄