sc0ttj / mdsh

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

Enable e-commerce (PayPal) #91

Closed sc0ttj closed 4 years ago

sc0ttj commented 4 years ago

This PR adds support for the creation of PayPal "buy now", "add to cart" and "subscription" buttons from YAML data and templates.

The e-commerce buttons work without JS :)

Relevant to his Issue: https://github.com/sc0ttj/mdsh/issues/88

New features:

Fixes:

Updates:

Implementation

The text below is stolen from an upcoming blog post, which describes the work in this PR, and how I did it.


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 to markdown (or other templates):
<div class="products">
{{#foreach item in products | where slug = $page_slug }}
  {{>.app/templates/html/_paypal_products_list.mustache}}
{{/foreach}}
</div>

Contents of _paypal_products_list.mustache:

{{#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}}