Building a webshop with SimplyEdit

Combine SimplyEdit and Snipchart for a really simple e-commerce solution

Auke van Slooten
SimplyEdit
8 min readSep 21, 2017

--

Snipcart is a shopping cart system that is very easy to include on any website. Just like SimplyEdit, you can use simple attributes in your HTML to define products and prices. Snipcart then takes care of the rest.

An example of Snipcart and Rating Widget working together with SimplyEdit.

Here is an example of a ‘Buy Now’ button:

<button class=”snipcart-add-item” 
data-item-id=”1"
data-item-name=”Bonsai Kitten”
data-item-description=”A cute kitten in a bottle.”
data-item-price=”99.00"
data-item-url=”/products/bonsai-kitten/”
>Buy Now</button>

Just like SimplyEdit, Snipcart also needs a bit of javascript, so include the following javascript and css in the head of your page:

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src=”https://cdn.snipcart.com/scripts/2.0/snipcart.js" data-api-key=”YOUR-API-KEY” id=”snipcart”></script>
<link href=”https://cdn.snipcart.com/themes/2.0/base/snipcart.min.css" rel=”stylesheet” type=”text/css”>

You can create an account at https://snipcart.com/ and then you’ll get your own personal API key.

This is pretty simple, but you can’t edit or add products yet. So lets mark up the button so you can edit the name, description and price:

<button class=”snipcart-add-item” 
data-item-id=”1"
data-item-name=”Bonsai Kitten”
data-item-description=”A cute kitten in a bottle.”
data-item-price=”99.00"
data-item-url=”/products/bonsai-kitten/”
data-simply-field=”product”
data-simply-content=”attributes”
data-simply-attributes=”data-item-name data-item-price data-item-description”
>Buy Now</button>

The data-simply-fieldattribute tells SimplyEdit that this element (the button) is an editable field. However the data-simply-content=”attributes” marks it as an element in which the attributes can change, instead of the content. Finally data-simply-attributes tells SimplyEdit which attributes can be modified.

However, there is no way for the user to edit these fields directly. SimplyEdit has no default user interface to edit just any attribute. But we can make use of another feature of SimplyEdit: The ability to show and edit the same content in multiple places:

<h1 data-simply-field=”product.data-item-name” data-simply-content=”text”>Bonsai Kitten</h1>

Here the data-simply-field attribute uses the name product.data-item-name. This way SimplyEdit stores the content in the property data-item-name of the object product. Which in this case is the exact same place where the button field stores the attribute of the same name. In addition data-simply-content=”text” tells SimplyEdit to only allow plain text content here. This makes sure that the content is appropriate for the data-item-name attribute.

Now whenever you change the name in the <h1> element, SimplyEdit will automatically update the data-item-name property of the <button>. And this way you update the information for Snipcart. All without a line of javascript.

The same works for the price and description:

<p data-simply-field=”product.data-item-description” 
data-simply-content=”text”
>A cute kitten in a bottle.</p>
<p class=”price”>&euro;
<span data-simply-field=”product.data-item-price”
data-simply-content=”text”
>99.00</span>
</p>

However, there is one problem left. Snipcart doesn’t trust the browser and for good reasons. What would happen if a customer opened the development tools and changed the price attribute to read 0.01 and then pressed the ‘Buy Now’ button? A naïve implementation would then happily let you buy a bonsai kitten for 1 cent. Clearly they are worth much more.

So Snipcart does a check on the website. It requests the same webpage you are looking at, but directly from the Snipcart server. This means that your browser cannot change anything, the communication is between the Snipcart server and the webserver directly. Snipcart checks the price and product id and maybe other stuff in the page it requested by itself. That information is what is actually used to buy the product.

However Snipcarts crawler is not as smart as Google, it doesn’t actually execute any Javascript. So SimplyEdit can’t render the product page and enter the correct information. Luckily there is another tool we can use to solve this problem: Prerender.io.

Prerender.io is a tool that checks which browser or crawler wants to see a specific page and if that browser or crawler is one of a select set, it will actually redirect the browser to a special website that will get the page and render it in an internal browser, with Javascript enabled. After the Javascript has run, it will send the result to the original requestor, the browser or crawler that had no Javascript support itself.

Snipcart has such a crawler and support for Prerender.io and it is baked into the SimplyEdit quickstart templates. All you need to do is change the .htaccess file in the document root, like this:

<Limit GET>
RewriteCond %{HTTP_USER_AGENT} Snipcart|Lynx|w3m|googlebot|baiduspider|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora\ link\ preview|showyoubot|outbrain|pinterest|slackbot|vkShare|Validator [NC,OR]
RewriteCond %{QUERY_STRING} _escaped_fragment_
# Only proxy the request to Prerender if it’s a request for HTML
RewriteRule ^(?!.*?(\.js|\.css|\.xml|\.less|\.png|\.jpg|\.jpeg|\.gif|\.pdf|\.doc|\.txt|\.ico|\.rss|\.zip|\.mp3|\.rar|\.exe|\.wmv|\.doc|\.avi|\.ppt|\.mpg|\.mpeg|\.tif|\.wav|\.mov|\.psd|\.ai|\.xls|\.mp4|\.m4a|\.swf|\.dat|\.dmg|\.iso|\.flv|\.m4v|\.torrent|\.ttf|\.woff))(.*) prerender.php [L]
</Limit>

This looks complex and it is, but luckily you can just copy this verbatim into your .htaccess file and everything should work.

Prerender.io is not entirely free to use however. If your website has many pages, you may need to get a subscription. Or if you want to change the default cache time from a day to something a little less. But you can also download and install Prerender yourself, it is also an open source tool.

The final step is to allow more than one product in your website. For this you can use the Lists feature of SimplyEdit:

<section class=”products” 
data-simply-list=”products”
data-simply-sortable
>
<template>
<div class=”product”>
<h1 data-simply-field=”product.data-item-name”
data-simply-content=”text”
>Bonsai Kitten</h1>
<p data-simply-field=”product.data-item-description”
data-simply-content=”text”
>A cute kitten in a bottle.</p>
<p class=”price”>&euro;
<span data-simply-field=”product.data-item-price”
data-simply-content=”text”
>99.00</span>
</p>
<button class=”snipcart-add-item”
data-item-id=”1"
data-item-name=”Bonsai Kitten”
data-item-description=”A cute kitten in a bottle.”
data-item-price=”99.00"
data-item-url=”/products/bonsai-kitten/”
data-simply-field=”product”
data-simply-content=”attributes”
data-simply-attributes=”data-item-name data-item-price data-item-description”
>Buy Now</button>
</div>
</template>
</section>

Now you can add more than one product. However, they all get the same data-item-id. A simple solution is to just add a paragraph or span with the correct field name, just like we did with data-item-name. However then you’d see the product id in the webpage and this may not be what you want. A simple solution is to add a CSS rule that hides the product id and only shows it when you are editing the page:

<style>
.product-hidden {
display: none;
}
body[data-simply-edit] .product-hidden {
display: block;
}
</style>

And now we can add the product id:


<div class=”product”>
<p class=”product-hidden”
data-simply-field=”product.data-item-id”
data-simply-content=”text”
>1</p>

And the same thing can be done for the URL as well:

<section class=”products” 
data-simply-list=”products”
data-simply-sortable
>
<template>
<div class=”product”>
<p class=”product-hidden”
data-simply-field=”product.data-item-id”
data-simply-content=”text”
>1</p>
<p class=”product-hidden”
data-simply-field=”product.data-item-url”
data-simply-content=”text”
>/products/</p>
<p class=”product-url”
data-simply-field=”product.data-item-id”
data-simply-content=”text”
>1</p>
<h1 data-simply-field=”product.data-item-name”
data-simply-content=”text”
>Bonsai Kitten</h1>
<p data-simply-field=”product.data-item-description”
data-simply-content=”text”
>A cute kitten in a bottle.</p>
<p class=”price”>&euro;
<span data-simply-field=”product.data-item-price”
data-simply-content=”text”
>99.00</span>
</p>
<button class=”snipcart-add-item”
data-item-id=”1"
data-item-name=”Bonsai Kitten”
data-item-description=”A cute kitten in a bottle.”
data-item-price=”99.00"
data-item-url=”/products/bonsai-kitten/”
data-simply-field=”product”
data-simply-content=”attributes”
data-simply-attributes=”data-item-name data-item-price data-item-description data-item-id data-item-url”
>Buy Now</button>
</div>
</template>
</section>

Don’t forget to also update the data-simply-attributes list, so that the changes will actually end up in the button attributes.

So this is all you need to get a basic webshop running with SimplyEdit and Snipcart. However any decent webshop needs product ratings as well. Adding product ratings makes your webshop much more search engine friendly.

Snipcart and Rating Widget in the SimplyEdit editor.

Rating-Widget is a popular tool to include and it is simple as well. First create an account at http://rating-widget.com/. Just click on ‘Get my free widget’. There you can set all kinds of styling preferences and download a small piece of javascript, like this:

<script type=”text/javascript”>(function(d, t, e, m){ 
// Async Rating-Widget initialization.
window.RW_Async_Init = function(){
RW.init({
huid: “…”,
uid: “…”,
source: “website”,
options: {
“size”: “medium”,
“style”: “oxygen”,
“isDummy”: false
}
});
RW.render();
};
// Append Rating-Widget JavaScript library.
var rw, s = d.getElementsByTagName(e)[0], id = “rw-js”,
l = d.location, ck = “Y” + t.getFullYear() +
“M” + t.getMonth() + “D” + t.getDate(), p = l.protocol,
f = ((l.search.indexOf(“DBG=”) > -1) ? “” : “.min”),
a = (“https:” == p ? “secure.” + m + “js/” : “js.” + m);
if (d.getElementById(id)) return;
rw = d.createElement(e);
rw.id = id; rw.async = true; rw.type = “text/javascript”;
rw.src = p + “//” + a + “external” + f + “.js?ck=” + ck;
s.parentNode.insertBefore(rw, s);
}(document, new Date(), “script”, “rating-widget.com/”));</script>

You can add this to your webpage, and add the rating widget container to the product template. However, there are two things that need a tweak to work with SimplyEdit:

First, if you have more than one product on a page, you also need more than one rating widget. So you need the `data-title` attribute and you must be able to edit this in SimplyEdit as well. So add the following to the product template:

<p class=”product-hidden”
data-simply-field=”rating.data-title”
data-simply-content=”text”>my rating</p>
<div class=”rw-ui-container”
data-title=”my rating”
data-simply-field=”rating”
data-simply-content=”attributes”
data-simply-attributes=”data-title”></div>

Second, the rating widget javascript code must run after SimplyEdit has rendered all the content, otherwise it may run before the `data-title` fields are set correctly. So instead of the original javascript, change it slightly like this:

<script type=”text/javascript”>
document.addEventListener(‘simply-content-loaded’, function() {
(function(d, t, e, m){
// Async Rating-Widget initialization.
window.RW_Async_Init = function(){
RW.init({
huid: “…”,
uid: “…”,
source: “website”,
options: {
“size”: “medium”,
“style”: “oxygen”,
“isDummy”: false
}
});
RW.render();
};
// Append Rating-Widget JavaScript library.
var rw, s = d.getElementsByTagName(e)[0], id = “rw-js”,
l = d.location, ck = “Y” + t.getFullYear() +
“M” + t.getMonth() + “D” + t.getDate(), p = l.protocol,
f = ((l.search.indexOf(“DBG=”) > -1) ? “” : “.min”),
a = (“https:” == p ? “secure.” + m + “js/” : “js.” + m);
if (d.getElementById(id)) return;
rw = d.createElement(e);
rw.id = id; rw.async = true; rw.type = “text/javascript”;
rw.src = p + “//” + a + “external” + f + “.js?ck=” + ck;
s.parentNode.insertBefore(rw, s);
}(document, new Date(), “script”, “rating-widget.com/”));
});
</script>

As you can see, we wrapped the original javascript code inside an EventListener. SimplyEdit fires an event called ‘simply-content-loaded’ immediately after the page is rendered and all the information is available. At that point the rating widget has the data-title attribute and only then can it initialize its javascript code.

And that’s it. You now have a complete webshop, with user ratings. You may need to setup some more stuff in Snipcart, but the snipcart website and dashboard will help you get that sorted.

--

--