1563174852
“We haven’t played with Go in a while.”
Our lead developer, reflecting on our content roadmap.
“I haven’t worked with Go at all,” I think to myself.
Today, I’ll give it a go (yeah, I know 🤦♂️) by exploring the Golang ecosystem and the e-commerce possibilities it offers.
I’ll then show you how to craft your own Go-powered online shop with the help of Ponzu CMS.
Tutorial steps:
Let’s first take a step back and immerse ourselves in the Golang universe.
I think it’s still legitimate to call Go an up-and-coming programming language, since the developer community defines it as one of the languages it most wishes to learn. It also ranks as the fifth most loved one, higher than JavaScript and C## amongst others.
This post isn’t about learning the language. If you feel like you need a proper introduction to Golang’s strengths & weaknesses, read this excellent post.
Take Hugo for instance, one of the most popular static site generators out there. Widely recognized as the fastest of its kind, it’ll generate a neat blog or e-commerce frontend in no time.
Some of these tools are specifically made to generate online shops and e-commerce backends:
Looking at these e-commerce solutions, you’ll quickly get that they’re mostly massive platforms which might not give you lots of freedom as developers to craft custom shopping UX.
So, are there alternatives here? Two come to mind:
If none of these solutions seem to fit your needs, maybe Golang isn’t the right language/framework for your e-commerce backend. Have you thought about trying Node.js, Python/Django or PHP/Laravel?
I’ll use Ponzu CMS to manage the content of my e-commerce app here. In a nutshell, it is an efficient Go-powered open-source HTTP server framework and CMS.
In the words of its creator Steve Manuel:
“It’s easy to use, JSON friendly, and with a fast and concurrent API server. I wanted to pick the parts of other platforms that I liked: take a great CMS backend from WordPress, a developer-first CLI to generate code for me from Rails, and a blazing fast JSON API from Netty.”
It looks like a neat minimalist framework; an excellent choice for small use cases with crazy fast installation and setup, automatic HTTPS configuration, and top-notch performances.
As a headless CMS it allows me to take a JAMstack approach.
The stack will be Go all the way down to the store website: I’ll throw Hugo in the mix as my static site generator.
So, let’s get on with it!
Sea levels are rising. A rise of a few feet only could get some people’s feet wet. Better be prepared! So let’s start a simple store selling some goods to help people deal with these floods. We’ll have limited stocks, so it will be crucial to keep track of our inventory.
So let’s get started.
Having an instance of Ponzu running amounts to executing a few terminal commands:
$ go get -u -v github.com/ponzu-cms/ponzu/...
$ ponzu new snipcart-ponzu
$ cd $GOPATH/src/snipcart-ponzu
$ ponzu build
$ ponzu run --dev-https
Enabling self-signed HTTPS... [DEV]
Server listening on https://localhost:10443 for requests... [DEV]
If your browser rejects HTTPS requests, try allowing insecure connections on localhost.
on Chrome, visit chrome://flags/#allow-insecure-localhost
Server listening at localhost:8080 for HTTP requests...
Visit '/admin' to get started.
Once you’ve done the above, head over to https://localhost:10443/admin.
There’ll be a one-time configuration step before you can get your hands dirty:
You’ll end up in the admin interface. Looks a bit empty, right?
That’s because there still isn’t any content type available. Ponzu provides a command line generator for this.
Let’s create a product
content type. Stop the app (CTRL+C) and run the following:
$ ponzu generate content product name:"string" price:"float32" description:"string" image:string:file
$ ponzu build
$ ponzu run --dev-https
When executing the command above, Ponzu creates a product.go
file under the content
directory of your app. This is the base of this content type definition. You can extend it to make it fit your needs (we’ll get back to that).
Right now, just leave it as-is, restart the app, and go back to the admin dashboard.
You’ll notice that the Product content type is now available in the navigation bar. By clicking it, you access the list of product entries:
Create your first product:
Bam!
Once created, your new product will instantly be available through Ponzu’s API endpoint:
// https://localhost:10443/api/contents?type=Product
{
"data": [
{
"uuid": "62426fee-c78d-4072-b009-92e2d19795c0",
"id": 5,
"slug": "product-62426fee-c78d-4072-b009-92e2d19795c0",
"timestamp": 1536113556000,
"updated": 1536150096023,
"name": "Hot air balloons (pack of 2)",
"price": 23599,
"description": "Best way to go is up! Glide through the air boarding one of these majestic balloons.",
"image": "/api/uploads/2018/09/hot-air-balloons.jpg"
}
]
}
That last step wraps our basic headless CMS setup. Now, the crunchy part!
The store will be a Hugo site hosted on Netlify.
You’ll have to install Hugo. Now let’s create your site.
You can do so using the Beautiful Hugo theme and tweaking it a bit.
I won’t go to great lengths explaining the customization since this isn’t our primary focus. A more in-depth walkthrough is covered in this earlier piece.
$ hugo new site myshop.com
$ cd myshop.com
$ cd themes
$ git clone https://github.com/halogenica/beautifulhugo.git beautifulhugo
$ cp ./beautifulhugo/exampleSite/config.toml ../config.toml
Now, you could add a product archetype and run a command like hugo new product/my-awesome-product.md
to create content, but you remember this shiny Ponzu product catalog?
You want all of your products to be added automatically, right? Let’s do it this way.
What you’ll need to do is code a simple program that will read the products from your Ponzu API and generate Hugo Markdown content files for them.
Since there’s already Ponzu and Hugo in the mix, it just makes sense to use Go for that, doesn’t it?
Just create a simple Go package inside your Hugo site:
## I'm using VS Code here
$ code ponzuImport.go
Here’s the code:
package main
import (
"bufio"
"crypto/tls"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"os"
"time"
)
type PonzuProductResponse struct {
Data []PonzuProduct `json:"data"`
}
type PonzuProduct struct {
UUID string `json:"uuid"`
ID int `json:"id"`
Slug string `json:"slug"`
Timestamp int64 `json:"timestamp"`
Updated int64 `json:"updated"`
Name string `json:"name"`
Price float32 `json:"price"`
Description string `json:"description"`
Image string `json:"image"`
}
type HugoProduct struct {
ID string `json:"id"`
Title string `json:"title"`
Date time.Time `json:"date"`
LastModification time.Time `json:"lastmod"`
Description string
Price float32 `json:"price"`
Image string `json:"image"`
Stock int `json:"stock"`
}
func (dest *HugoProduct) mapPonzuProduct(
src PonzuProduct,
ponzuHostURL string,
client *http.Client) {
dest.ID = src.Slug
dest.Title = src.Name
dest.Price = src.Price
dest.Description = src.Description
dest.Image = ponzuHostURL + src.Image
dest.Date = time.Unix(src.Timestamp/1000, 0)
dest.LastModification = time.Unix(src.Updated/1000, 0)
}
func main() {
ponzuHostURL, ok := os.LookupEnv("PONZU_HOST_URL")
if !ok || ponzuHostURL == "" {
}
var productsEndpoint = ponzuHostURL + "/api/contents?type=Product"
// Fetch products
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // this line should be removed in production
}
client := &http.Client{Transport: tr}
request, err := http.NewRequest(http.MethodGet, productsEndpoint, nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
// Parse response JSON
var products PonzuProductResponse
if err = json.Unmarshal(body, &products); err != nil {
log.Fatal(err)
}
// Clear content/product directory
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
if err := os.RemoveAll(dir + "/content/product"); err != nil {
log.Fatal(err)
}
if err := os.MkdirAll(dir+"/content/product", 0777); err != nil {
log.Fatal(err)
}
// Write product content files
for _, sourceProduct := range products.Data {
var destProduct = HugoProduct{}
destProduct.mapPonzuProduct(sourceProduct, ponzuHostURL, client)
entryJSON, err := json.MarshalIndent(destProduct, "", " ")
if err != nil {
log.Fatal(err)
}
file, err := os.Create(dir + "/content/product/" + destProduct.ID + ".md")
if err != nil {
log.Fatal(err)
}
writer := bufio.NewWriter(file)
writer.WriteString(string(entryJSON) + "\n")
writer.WriteString("\n")
writer.WriteString(destProduct.Description)
writer.Flush()
file.Close()
}
}
The above is pretty simple; it reads through all products and creates a product content file for each one by mapping all relevant fields.
You can test this script by running go build ./ponzuImport.go
You’ll want to generate products on each build, so create the following build.sh
script at the root of your website:
#!/usr/bin/env bash
go build -o ./ponzuImport ./ponzuImport.go
./ponzuImport
hugo
Then, configure Netlify to run this script when building your site. Just add this netlify.toml file at the root of your website:
[build]
publish = "public"
command = "./build.sh"
[context.production.environment]
## I'm fixing Hugo version to make sure my theme doesn't break
HUGO_VERSION = "0.47.1"
HUGO_ENV = "production"
You’ll have to set the PONZU_HOST_URL
environment variable in your Netlify build configuration. It has to point to your live instance of Ponzu. Whether it’s a ngrok proxy of your local app (when still in development) or a cloud app, it’ll have to be set.
Let’s add required Snipcart markup under your layout’s <head>
element:
<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" id="snipcart" data-api-key="{{ .Site.Params.snipcartAPIKey }}"></script>
<link href="https://cdn.snipcart.com/themes/2.0/base/snipcart.min.css" type="text/css" rel="stylesheet" />
Then, render buy buttons like so in your template:
{{ if le .Params.stock 0 }}
<span>Out of stock</span>
{{ else }}
<button
class="snipcart-add-item"
data-item-id="{{ .Params.id }}"
data-item-name="{{ .Title }}"
data-item-price="{{ .Params.price }}"
data-item-image="{{ .Params.image }}"
data-item-url="/"
data-item-max-quantity="1"
data-item-description="{{ .Params.description }}">
Add to cart
</button>
{{end}}
Now, how about we handle this Stock
field seen earlier?
Snipcart offers inventory management in your Merchant Dashboard.
You don’t want to wait for your products to be purchased before you see them in the dashboard, so let’s crawl them in advance:
Your products are now available in Snipcart! Let’s set stocks for them:
Now, you have to adapt the import script to fetch your products stocks. To do so, you’ll have to use Snipcart’s API.
Open ponzuImport.go
and add these two structs:
type SnipcartProductResponse struct {
Items []SnipcartProduct `json:"items"`
}
type SnipcartProduct struct {
Stock int `json:"stock"`
}
type SnipcartProductResponse struct {
Items []SnipcartProduct `json:"items"`
}
type SnipcartProduct struct {
Stock int `json:"stock"`
}
Next, add the following at the end of the mapPonzuProduct
function:
// Fetch stock from Snipcart API
var url = "https://app.snipcart.com/api/products?userDefinedId=" + dest.ID
request, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatal(err)
}
var apiKey = base64.StdEncoding.EncodeToString([]byte(os.Getenv("SNIPCART_PRIVATE_API_KEY")))
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", "Basic "+apiKey)
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var products SnipcartProductResponse
if err = json.Unmarshal(body, &products); err != nil {
log.Fatal(err)
}
dest.Stock = products.Items[0].Stock
Note that your Snipcart private API key will have to be set in the SNIPCART_PRIVATE_API_KEY
environment variable in your Netlify build configuration.
Neat! From now on, running your build will feed the Stock
field as well.
There is one last piece missing to our grand scheme: triggering your Netlify build when data changes.
First, create a Netlify build hook for your website. Any POST request to this URL will trigger a new deployment.
Configuring webhooks in Snipcart is easy. Paste the URL in the Webhooks configuration page of your Merchant Dashboard:
You also want to call this webhook when a change occurs in your Ponzu data. Ponzu CMS offers a handful of extension points using interfaces.
Let’s extend your product content type definition by defining save hooks. Head back to your Ponzu app and add the following to content/product.go
:
func (p *Product) AfterAdminCreate(res http.ResponseWriter, req *http.Request) error {
sendWebHook()
return nil
}
func (p *Product) AfterAdminUpdate(res http.ResponseWriter, req *http.Request) error {
sendWebHook()
return nil
}
func (p *Product) AfterAdminDelete(res http.ResponseWriter, req *http.Request) error {
sendWebHook()
return nil
}
func sendWebHook() {
url := os.Getenv("NETLIFY_BUILD_HOOK_URL")
resp, err := http.Post(url, "application/json", nil)
if err != nil {
log.Fatal(err)
} else {
log.Println("Webhook called successfully at " + url + " with result " + resp.Status)
}
}
Aaaaaand you’re all set! You now have fresh Golang JAMstack e-commerce setup with inventory management. How cool is that?
See the live demo here.
See GitHub repo here.
Ponzu is great. The creator put a lot of thought into making the developer journey as simple as possible. Seamless HTTPS certificate setup through Let’s Encrypt is fantastic. The build process produces a native executable that you can run anywhere.
For the production environment, I faced an issue with Heroku’s buildpack for Go — wasn’t playing well with Ponzu’s structure. I recommend running your Ponzu app in Docker.
With some hurdles here and there, I spent about two days building this demo, including the learning curve. A more seasoned Go developer should get through this way faster.
To push this tutorial further? Ponzu CMS supports HTTP/2.0, which comes with a cool feature named Server Push. When building an SPA backed by Ponzu, you can reduce the amount of remote calls you make to the backend by using Server Push to bundle multiple payloads of data that the client is likely to ask in the future!
The Original Article can be found on https://snipcart.com/
#go #golang #web-development #developer
1628865079
At the initial stage of doing business, a website builder can be the optimal solution, but in the future it is recommended to create and promote a website independently or using the services of specialists https://mediaonemarketing.com.sg/ecommerce-developer-singapore/
1623130935
Looking to develop an E-Commerce app for your business or start-up? We at, AppClues Infotech have the best team of E-Commerce mobile app developers in USA for iOS & Android users. Get in touch with our E-Commerce experts to take your E-Commerce business to the next level.
E-Commerce App Development Services
• Ecommerce Technology Consulting
• Custom E-Commerce App Development
• E-Commerce Wallet Development
• E-Commerce Plugin Integration
• E-Commerce App UI/UX Designing
• B2B & B2C E-Commerce App Solutions
For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910
#e-commerce app development company in usa #hire e-commerce app developers in usa #custom e-commerce app development #create an e-commerce app #cost to build e-commerce app #m-commerce app development company in usa
1620367822
Looking to develop an eCommerce app for your business? We at, AppClues Infotech provide the best eCommerce mobile app development services for Android and iOS users. Get in touch with our eCommerce experts to take your e-commerce business to the next level.
For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910
#e-commerce app development company in usa #hire e-commerce app developers in usa #custom e-commerce app development #create an e-commerce app #cost to build e-commerce app #m-commerce app development company in usa
1611831324
Do you want to make a custom E-Commerce mobile app for your business? We at AppClues Infotech is the best E-Commerce mobile app development company in the USA that provides a complete E-Commerce app solution with the current trending technologies & features at an affordable cost.
For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910
#e-commerce app development #mobile commerce app development #e-ccommerce app development company usa #e-commerce development services usa #custom e-commerce app development #e-commerce app development services
1593144300
There comes a lot of benefits that bring more advantages to your business. Some of the top advantages of converting your online eCommerce store into a mobile App are given as follows.
Before building a customer mCommerce mobile application for your business, you will need to know the important steps or decisions that you need to make on the process. From choosing the right innovative technology to finding the right mobile development company, here is everything you need to know about mCommerce development.
The success of the business depends largely on the user experience that your application delivers to your customers. It is no secret that mobile applications provide you with the best features and opportunities than anything else. You can provide the best user experience that is exclusively customized to the needs of your users.
If you want to attain the most out of the benefits of mobile application, it is crucial to choose the right technology for your mobile application development. There are two well-known platforms that are android and iOS When you are building a mobile application, you will have to develop 2 native applications that cater to both platforms separately or you can invest in a cross-platform mobile application.
For a start-up, you can better go for cross-platform applications that are affordable, helps you in saving time and money. Because building native applications are a time-consuming process and also you will need to spend on two different mobile applications for two different platforms. Building native applications can bring you extensive user experience and features but it is expensive at the same time. There is another option that comes in the line. The Progressive Web Application is the technology that can bring all the benefits of mobile applications and also works in a browser as a web application.
You can better talk to our technology solutions experts to find the best solution for your business application.
#enterprise application #advantages of mobile commerce #different players in m commerce #features of m commerce #m commerce examples #m commerce wikipedia #m-commerce development #mobile commerce applications #mobile commerce statistics 2019 #mobile commerce trends
1619071494
Ranked among the best eCommerce development companies in India, we provide online store development solutions to both B2B & B2C customers spreading all across the globe!
Keep in touch with us👇🏻
🌎 e-commerce website design dubai
📲 91 94477 34981/ 91484 2428141
#ecommerce #marketing #business #entrepreneur #digitalmarketing #ecommercebusiness #onlineshopping #webdesign #seo #website #shopify #amazon #marketingdigital #online #onlineshop #onlinebusiness #startup #socialmedia #branding #smallbusiness #shopping #onlinestore #onlinemarketing #socialmediamarketing #design #ecommercewebsite
#e-commerce dubai #e-commerce websites dubai #electronic commerce dubai #e-commerce business dubai #e-commerce company dubai