Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

e-commerce #88

Closed
sc0ttj opened this issue Sep 20, 2019 · 3 comments
Closed

e-commerce #88

sc0ttj opened this issue Sep 20, 2019 · 3 comments
Labels
enhancement New feature or request

Comments

@sc0ttj
Copy link
Owner

sc0ttj commented Sep 20, 2019

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

This would include nicer/clearer ways to:

  • make a product a proper "thing" with a title, description, price, payment merchant
  • add payment merchant credentials to site data
  • add a catalogue of products to site data (in assets/data/ folder)
  • add a single product to page data (in front matter)
  • to add multiple products to a page (templating)
  • to add a single product to a page (templating)

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

  • Buy now and one-off payments (see comments below)
  • Subscriptions and recurring payments (see comments below)
  • Add to cart buttons, with a simple shopping cart

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:

  • a "Shopping cart" header
  • a list of items in the cart, with a buy now button next to each one
  • a "Checkout" button at the bottom

Alternative merchants

  • stripe
  • snipcart

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

@sc0ttj sc0ttj added the enhancement New feature or request label Sep 20, 2019
@sc0ttj sc0ttj mentioned this issue Sep 21, 2019
14 tasks
@sc0ttj
Copy link
Owner Author

sc0ttj commented Sep 29, 2019

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
Copy link
Owner Author

sc0ttj commented Sep 29, 2019

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
Copy link
Owner Author

sc0ttj commented Oct 20, 2019

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

@sc0ttj sc0ttj closed this as completed Oct 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant