sc0ttj / mdsh

A simple static site generator, using Markdown and Bash
https://sc0ttj.github.io/mdsh/
10 stars 0 forks source link

e-commerce #88

Closed sc0ttj closed 4 years ago

sc0ttj commented 4 years ago

Support creation of very simple e-commerce websites using mdsh.

This would include nicer/clearer ways to:

Implementation

1. Multiple products:

a. Add in assets/data/products.yml:

product1
  id: my-cool-page
  name: 'Nice toaster or something' 
  price: 10
product2
  id: some-other-page
  name: 'Nice coat or something' 
  price: 20

b. To list multiple products per page:

{{foreach product in products}}
  Name: {{product.name}}
  ...
{{/foreach}}

Also see limit, sort_by and sort_array liquid filters for manipulating the list in the templates.

To access specific products, you'd also be able to do (probably less useful) stuff like this:

Name: {{lookup products[3].name}}
Price: {{lookup products[3].price | money £}}

c. A better way to show one product per page, create a _product_info.mustache template partial, containing something like:

{{foreach product in products | where id = $page_slug}}
  Name: {{product.name}}
  Price {{product.price | money £}}
  ...
{{/foreach}}

The benefit of this is that we can put only one product per page, and each page gets a different product, and we only have to define this one partial, and include it in our main templates, using something like so:

  {{>product_info}}

2. Adding a single product to a page

Add this in front-matter of posts/*/*/*/my-cool-page.mdsh:

product
  id: my-cool-page
  name: 'Nice toaster or something' 
  price: 10  

And access in a _page_product.mustache template, like so:

{{#page_product_name}}
Name: {{page_product_name}}
Price: {{page_product_price | money £}}
{{/page_product_name}}

...which could be included in the main templates like so:

{{>_page_product}}

This is probably the best approach, as we don't need an iterator to get to the product info, or the lookup method, and we can iterate over product options more easily.

3. Available payment methods

shopping cart

Build as a tiny cash-js plugin (basically a jQuery plugin), and add to app.js.

Use localStorage to save items to a cart object, and a little bit of JS to detect the cart is not empty, then put a button on the page, and provide a nice popup modal cart.

Show in cart modal popup:

Alternative merchants

Don't tie people in to one or the other too much, or at all if possible..

sc0ttj commented 4 years ago

Snipcart

Adds a nice shopping cart, requires, JS, can define product data on your own site as HTML attributes (in our case, in the yaml, then compiled into the templates).. But very pricey - £8 a month minimum, or 4.5% commission if you sell over £500 a month.

How to add products to your pages:

Pricing:

sc0ttj commented 4 years ago

PayPal buttons

Implementation 1: Multiple products per page

  1. Create some "Buy Now", "Add to Cart" or "Subscription" buttons, using the PayPal Button Designer

Normally, you would need to create a new button for every single product you wish to sell... which can be a pain.

However, using mdsh, you only need to create buttons for each button type and price you wish to sell at - you can set different titles, names, options (etc) for each one later, in your mdsh YAML files.

Example: I want to sell lots of different t-shirts, each at £10, so I create one button called 'tshirts', with a price of £10 .. I'll re-use this button for all my £10 tshirts, by defining their unique titles, description, etc in my YAML files.

  1. Add the products YAML to assets/data/products.yml - copy in the hosted_button_id as paypal_btn_id, add the price you chose above, and any other info you like.
product_1:
  paypal_btn_id: SSXB2QBGUGVDW
  paypal_btn_label: Buy Now
  price:          10
  name:           Spongebob t-shirt
product_2:
  paypal_btn_id: SSXB2QBGUGVDW
  paypal_btn_label: Buy Now
  price:          10
  name:           Family Guy t-shirt
  1. Add product options to your site YAML (assets/data/site.yml):
product_options:
  colour: Colour
  size: Size
product_colour_options:
  - Red
  - Blue
product_size_options:
  - Small
  - Medium
  - Large
  1. Add templates:
{{#foreach item in products}}
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">

  <p>Price: {{item.price}}</p>

  <p>{{site_product_options_colour}}:
  <select name="os0">
    {{#site_product_colour_options}}
    <option value="{{. | lowercase}}">{{.}}</option>
    {{/site_product_colour_options}}
  </select>
  <input type="hidden" name="on0" value="{{site_product_options_colour}}">
  </p>

  <p>{{site_product_options_size}}:
  <input type="hidden" name="on1" value="{{site_product_options_size}}">
  <select name="os1">
    {{#site_product_size_options}}
    <option value="{{. | lowercase}}">{{.}}</option>
    {{/site_product_size_options}}
  </select>
  </p>

  <input type="submit" name="submit" value="{{item.paypal_btn_label}}">

  <!-- add the unique product name, from page data -->
  <input type="hidden" name="on3" value="name">
  <input type="hidden" name="os3" value="{{item.name}}">

  <!-- hidden values expected by paypal -->
  <input type="hidden" name="cmd" value="_s-xclick">
  <input type="hidden" name="hosted_button_id" value="{{item.paypal_btn_id}}">
  <img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>
{{/form}}

Note, to pass product options to PayPal, you need to set onX (option name) and osX (option value), where X is a number, like so (as above):

  <input type="hidden" name="on3" value="name">
  <input type="hidden" name="os3" value="{{item.name}}">

Implementation 2 - Single product per page

You can also define your product data in the YAML front matter of your pages. This is better if you only have a few products, or they are all quite different.

  1. Create a PayPal Buy Now button as above.

  2. Add the following YAML to the front matter of one of your .mdsh files:

product:
  name:           A cool t-shirt
  paypal_btn_id:  U8R375VMEZPNN
  paypal_btn_label: Buy Now
  price:          5.00
  shipping:       0.50

This will make variables like {{page_product_name}}, {{page_product_price}}, and so on available in your templates.

  1. Add the template:

Add this to one of your main templates:

{{>paypal_product_details}}

The contents of .app/templates/html/_paypal_product_details.mustache:

<!-- show products from page front matter YAML -->
{{#page_product_name}}
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
  <h4>{{page_product_name}}</h4>

  <ul>
  <li>Price: {{page_product_price | money £ }}</li>
  {{#page_product_shipping}}
  <li>Shipping: {{page_product_shipping | money £ }}</li>
  {{/page_product_shipping}}
  </ul>

  <p>Options:</p>
  <ul>

    {{#site_product_options_colour}}
    <li>
      <p>{{site_product_options_colour}}:
        <select name="os0">
          {{#site_product_colour_options}}
          <option value="{{. | lowercase}}">{{.}}</option>
          {{/site_product_colour_options}}
        </select>
        <input type="hidden" name="on0" value="{{site_product_options_colour}}">
      </p>
    </li>
    {{/site_product_options_colour}}

    {{#site_product_options_size}}
    <li>
      <p>{{site_product_options_size}}:
        <select name="os1">
          {{#site_product_size_options}}
          <option value="{{. | lowercase}}">{{.}}</option>
          {{/site_product_size_options}}
        </select>
        <input type="hidden" name="on1" value="{{site_product_options_size}}">
      </p>
    </li>
    {{/site_product_options_size}}

  </ul>

  <input type="submit" name="submit" value="{{page_product_paypal_btn_label}}">

  <!-- add the unique product identifier from page data -->
  <input type="hidden" name="on2" value="name">
  <input type="hidden" name="os2" value="{{page_product_name}}">

  <!-- hidden values expected by paypal -->
  <input type="hidden" name="cmd" value="_s-xclick">
  <input type="hidden" name="hosted_button_id" value="{{page_product_paypal_btn_id}}">
  <img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>
{{/page_product_name}}
sc0ttj commented 4 years ago

The last 2 PayPal implementations were done and merged.. Didn't bother with Stripe, Snipcart. Closing this issue anyway, bored of it now.