easy-digital-downloads icon indicating copy to clipboard operation
easy-digital-downloads copied to clipboard

Allowing easier/future-proof checkout customisations

Open amdrew opened this issue 6 years ago • 8 comments

I think our /includes/checkout/template.php file can be improved so it's easier to customize certain aspects of checkout without having to re-hook entire functions.

@cklosowski puts it nicely here (https://github.com/easydigitaldownloads/easy-digital-downloads/issues/6943#issuecomment-423292703)

a lot of people do custom checkout pages for some of the smallest changes, and if we can avoid those by making things like this easier, then 👍 from me.

Use-case

As an example, Themedd v1.1 uses Bootstrap 4 which provides consistent form styling I can use anywhere in the theme. The only way to utilize the existing styling at EDD checkout is to copy each function in template.php and add the required class names to form elements. I also modified the HTML to my liking to be consistent with the rest of theme. Since every form element needed custom class names it resulted in a large amount of code to maintain.

EDD was subsequently updated to fix a couple of issues with the template.php file (one related to nonces) and although I updated Themedd to match, I ultimately decided to drop all the functions in case there was anything super important related to checkout that needed to be updated in the future.

Proposal

EDD has a helper class for outputting common HTML elements (class-edd-html-elements.php) so I think a good start would be to make the checkout utilize the relevant methods.

Some quick example

The select() method could be used for:

  • billing country
  • card expiry month
  • card expiry year
  • card state

The checkbox() method could be used for agree to terms agree to privacy policy

The text() method could be used for

  • any input field

etc

In addition, several key aspects of each method could be filterable so it's easy to change them without re-hooking any functions in template.php. The most notable being the class names of any field type. This would allow me to add the specific class names I need, without ever having to worry about future core updates breaking the theme (if I had chosen to keep all the modified functions).

amdrew avatar Sep 21 '18 18:09 amdrew

@easydigitaldownloads/core-team I think this and #6943 should switch milestones and semi-merge ideas. Implementing #6943 will mean any extension that isn't updated before 3.0 that adds fields to the checkout will have not reflect that setting. I would imagine this will impact a lot of payment gateways.

Instead 3.0 can be used as a "best-practices" example on how to upgrade a lot of the hard-coded HTML elements used to build the purchase form in extensions.

This change also has breaking template changes while the "having the descriptions be a key value array to match up with the input name" suggestion #6943 can technically be implemented to default fields without the need for theme updates.

My proposal for this would be to include the field registry aspect of #6943 alongside of using EDD's helper HTML functions. This would result in the default email field looking something like:

<?php
echo EDD()->html->text( array(
	'id' => 'edd_email',
	'name' => 'edd_email',
	'label'  => edd_get_purchase_form_field_label( 'edd_email' ),
	'desc' => edd_get_purchase_form_field_desc( 'edd_email' ),
	'required' => edd_field_is_required( 'edd_email' ),
) );
?>

It requires a few changes to the helper functions (such as an option to show the required indicator) but overall the backwards compatible changes would be relatively minimal.

Once the default fields and as many extensions as possible are updated to use this method then implementing a setting that can globally and easily affect all checkout fields makes more sense.

spencerfinnell avatar Oct 15 '18 21:10 spencerfinnell

Proof of concept for the customer info fields: https://github.com/easydigitaldownloads/easy-digital-downloads/compare/release/3.0...test/checkout-modularity

spencerfinnell avatar Oct 15 '18 22:10 spencerfinnell

After some discussion in Slack discussion it's clear that we can ditch the "registry" -- feed the strings directly to the helper methods.

Beyond that it's a matter of the best way of supplying the fields to the purchase form.

spencerfinnell avatar Oct 16 '18 20:10 spencerfinnell

Implementation of previous discussion: https://github.com/easydigitaldownloads/easy-digital-downloads/compare/release/3.0...test/checkout-modularity

Feels much better. Going to work on converting the other fields.

spencerfinnell avatar Oct 17 '18 12:10 spencerfinnell

Latest commits add support for credit card fields and billing address.

I found the HTML generator methods to be inconsistent so I tried to remedy that but introducing a new method that allows creating the markup for the standard wrapped form element that includes a label and description. The text() method supported this originally, but things like select() only output the actual <select> element.

spencerfinnell avatar Oct 17 '18 14:10 spencerfinnell

I ended up doing similar with some of our settings functions. Things like checkboxes didn’t allow for description paragraphs underneath them, so a new function was invented. It’s OK. I’ll check it over. Thanks!

JJJ avatar Oct 17 '18 14:10 JJJ

I did not feel this needed a separate issue (since it was related), but the way the fields are outputted isn't exactly ideal and makes the checkout page huge which will definitely be reducing conversions and creating checkout friction.

For example, bootstrap suggests this type of layout:

https://getbootstrap.com/docs/4.0/examples/checkout/

At the minute no wrappers are provided around elements that should be (really) be on a single row like the first and last name fields. Other fields like "state" and "country" should be wrapped.

arraypress avatar Nov 06 '18 23:11 arraypress

I'm going to remove this from 3.1. Currently we're working on our first implementation of a checkout block, and I want to get that field tested in the live environments before we start refactoring things futher.

cklosowski avatar Aug 27 '22 08:08 cklosowski