Jump to content
Gadgetto

SnipWire - Snipcart integration for ProcessWire

Recommended Posts

8 hours ago, d'Hinnisdaël said:

I think there will be cases where custom fields will differ by product template, so the order might not be guaranteed and it's probably better to name them after their content (custom_field_size instead of custom_field_1). But how do you determine the option n° for Snipcart — if you move around the field in the template, should it keep its ID to keep order records consistent, or does that not matter as long as it's named properly?

Taking this example from Snipcart docs ...

data-item-custom1-name="Print label"
data-item-custom1-required="true"
data-item-custom2-name="Size"
data-item-custom2-options="Small|Medium|Large"
data-item-custom2-value="Medium"
data-item-custom3-name="Gift"
data-item-custom3-options="true|false"

... this could be translated to this naming convention:

snipcart-item-c-{fieldname}-{param}

(The "c" is to avoid naming collisions with existing snipcart-item fields)

snipcart-item-c-printlabel
snipcart-item-c-size
snipcart-item-c-gift

The n° option could be detected/added automatically by the field order within a template. But would this be flexible enough?

If we'd use this convention:

snipcart-item-c1-{fieldname}-{param}
snipcart-item-c2-{fieldname}-{param}
snipcart-item-c3-{fieldname}-{param}

We would block the reusability of fields in multiple templates.

Share this post


Link to post
Share on other sites
1 hour ago, szabesz said:

What do you mean by saying "start with"? Is the example above a prefix or the complete fieldname?

Yep it should be a prefix. Sorry for my bad English ...

Share this post


Link to post
Share on other sites
1 hour ago, szabesz said:

What do you mean by saying "start with"? Is the example above a prefix or the complete fieldname?

Why not? 🙂 

Good question! 🙂 Its probably the best way to have a separate "order" template. But then wouldn't I also need a separate "Order" page?

Share this post


Link to post
Share on other sites
1 hour ago, Gadgetto said:

Taking this example from Snipcart docs ...


data-item-custom1-name="Print label"
data-item-custom1-required="true"
data-item-custom2-name="Size"
data-item-custom2-options="Small|Medium|Large"
data-item-custom2-value="Medium"
data-item-custom3-name="Gift"
data-item-custom3-options="true|false"

... this could be translated to this naming convention:

snipcart-item-c-{fieldname}-{param}

(The "c" is to avoid naming collisions with existing data-item fields)


snipcart-item-c-printlabel-name="Print label"
snipcart-item-c-printlabel-required="true"
snipcart-item-c-size-name="Size"
snipcart-item-c-size-options="Small|Medium|Large"
snipcart-item-c-size-value="Medium"
snipcart-item-c-gift-name="Gift"
snipcart-item-c-gift-options="true|false"

The n° option could be detected/added automatically by the field order within a template. But would this be flexible enough?

Are you sure that's the final markup? Whenever I had to use custom fields, the attribute names were kept as custom1, custom2, etc. So the example from the Snipcart docs are copy-paste and not meant to be changed to the fieldnames you have. It's of course possible that both work and Snipcart will detect the fields either way. Just checking.

This is an example from an existing shop I'm running:

<?php if ($cart_has_options): ?>
  data-item-custom1-name="<?= $cart_option_name ?>"
  data-item-custom1-options="<?= join('|', $cart_option_data) ?>"
  data-item-custom1-value="<?= $cart_option_value ?>"
<?php endif; ?>

 

Share this post


Link to post
Share on other sites
7 hours ago, d'Hinnisdaël said:

Are you sure that's the final markup? Whenever I had to use custom fields, the attribute names were kept as custom1, custom2, etc. So the example from the Snipcart docs are copy-paste and not meant to be changed to the fieldnames you have. It's of course possible that both work and Snipcart will detect the fields either way. Just checking

Sorry, I didn’t mean this as the final html markup. I meant the naming convention for PW fields.

I edited my post above.

Share this post


Link to post
Share on other sites
11 hours ago, Gadgetto said:

Its probably the best way to have a separate "order" template. But then wouldn't I also need a separate "Order" page?

Each pw order page could store the data of the related extra order fields. Order pages could be saved under Admin (page id 2) > Snipcart Orders > [order#n] similar to the way PW saves repeaters "hidden" under the Admin page.

Share this post


Link to post
Share on other sites
8 hours ago, szabesz said:

Each pw order page could store the data of the related extra order fields. Order pages could be saved under Admin (page id 2) > Snipcart Orders > [order#n] similar to the way PW saves repeaters "hidden" under the Admin page.

A single order template with a single order page should be enough (for handling custom order fields). Or do you mean creating a page for each order?

Share this post


Link to post
Share on other sites
13 hours ago, Gadgetto said:

Or do you mean creating a page for each order?

Yes I do. I thought there is "custom data" related to each order but if not, then that is a different story.

Share this post


Link to post
Share on other sites
On 1/24/2020 at 9:43 AM, d'Hinnisdaël said:

That's what I've done in the past: create an order template with fields that I map to custom options. Also good to have the consent text editable by site editors.

Regarding "custom order fields": It seems you have some experience integrating Snipcart into PW. I'm following your suggestion by preinstalling a "snipcart-order" template and a "snipcart-order" page under Admin / Setup / SnipWire. The goal is, that an admin could add PW fields to this page which should later be mapped (or "translated") to the required Snipcart markup.

But how should a PW field look like to get the required values from? 

Here is a sample Snipcart custom order field markup (taken from @Noborus sample) which should be generated from a PW field:

data-cart-custom1-name="By checking this box, I have read and agree to the <a href=\'https://www.processwire.com\' class=\'js-real-link\' target=\'_blank\'>Terms &amp; Conditions</a>"
data-cart-custom1-options="true|false"
data-cart-custom1-required="true"

One idea is, that I simply add a Textarea field where an admin could enter the config string from above. SnipWire will then render this to the <script> tag.

BTW, in this case we wouldn't even need a template/page/field. I could simply add a Textarea to module config where these strings could be stored.

What do you think?

Share this post


Link to post
Share on other sites
21 hours ago, szabesz said:

Yes I do. I thought there is "custom data" related to each order but if not, then that is a different story.

Ah, ok! Snipcart custom order fields are global and valid/used for each order/cart.

  • Like 1

Share this post


Link to post
Share on other sites
19 hours ago, Gadgetto said:

One idea is, that I simply add a Textarea field where an admin could enter the config string from above. SnipWire will then render this to the <script> tag.

BTW, in this case we wouldn't even need a template/page/field. I could simply add a Textarea to module config where these strings could be stored.

This might just be enough, but will this work reliably with multi-language setups?

The way I've done it in the past is by creating a repeater matrix field that has a string, an integer and a bool type for creating and editing options. But you'd have to create a field on installation and the matrix module isn't free, so I guess that's out of the question?

Share this post


Link to post
Share on other sites
1 hour ago, d'Hinnisdaël said:

This might just be enough, but will this work reliably with multi-language setups?

The way I've done it in the past is by creating a repeater matrix field that has a string, an integer and a bool type for creating and editing options. But you'd have to create a field on installation and the matrix module isn't free, so I guess that's out of the question?

Yep, multi-language will require to use PW fields (at least to keep things simple). So I’ll stay with installing a cart template and a cart page where admins could add their custom cart fields. In the first version, I’ll solve this with a textarea field where the custom field config can be stored as is.

  • Like 1

Share this post


Link to post
Share on other sites
57 minutes ago, Gadgetto said:

Yep, multi-language will require to use PW fields (at least to keep things simple). So I’ll stay with installing a cart template and a cart page where admins could add their custom cart fields. In the first version, I’ll solve this with a textarea field where the custom field config can be stored as is.

Sounds about right. Unfortunately, I've been too busy to try out the module properly and give more useful feedback 👽

Share this post


Link to post
Share on other sites

UPDATE 2020-01-28

I just added the Snipcart "Custom Order Fields" feature!

Thank's @Noboru & @d'Hinnisdaël & @szabesz for your help and hints!

Custom order fields can be added/configured by editing a hidden config page under Admin > Setup > SnipWire > Custom Cart Fields.
The corresponding template/page/field resources are preinstalled by SnipWire installer. If you update to the new module versions, those resources will be added too!

1913208257_Bildschirmfoto2020-01-28um17_09_12.thumb.png.8845f692a8f2628b6991b9ca0a43e6a6.png

The config page has a single textarea field where you can add the configuration strings for your custom cart fields:
(multi language support is also available)

2020778956_Bildschirmfoto2020-01-28um17_09_54.thumb.png.e88956822a23fd27f9b24c403b8afc27.png

... can also be edited and enabled/disabled from within SnipWire module config.

581430103_Bildschirmfoto2020-01-29um12_22_36.thumb.png.ebb25dd301e0a425d5a9049bb639ebba.png

 

The config from the screenshot above leads to the custom step "Order Info" in checkout process:

324682490_Bildschirmfoto2020-01-28um17_29_04.thumb.png.9d857e73f9a3290703c1eabfd68827d7.png

The Snipcart docs for Custom Order Fields (v 2.0) can be read here:
https://docs.snipcart.com/v2/configuration/custom-fields

Next step is to implement custom product fields! When this is done, I'll release the first official version. SnipWire will then be added to the ProcessWire module directory (as far as @ryan accepts it).

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

UPDATE 2020-01-30

SnipWire 0.8.0 (beta) first public release!

It is done! After almost 1 year of hard work and a lot of help from the usual suspects I just released the first public version!
Please note that this is still a beta so please test, test, test before you use this plugin in a real project.

The module can be loaded via PW modules directory (just submitted - in review I think) or directly via GitHub.

More infos will be added soon ...

  • Like 3
  • Thanks 5

Share this post


Link to post
Share on other sites

UPDATE 2020-02-03

SnipWire 0.8.1 (beta) released!

This update mainly serves to move all custom classes into their own namespaces! This should fix the annoying class naming conflicts with other modules.

Its now time to put some effort into the SnipWire docs!

  • Like 2

Share this post


Link to post
Share on other sites

I'm just struggling with a problem regarding my MarkupSnipWire module (which is a part of SnipWire) and maybe I can get some hints here.

MarkupSnipWire is an autoloader module which - amongst other things - writes CSS and JS output required by Snipcart on page render. One of the required JS params is the currency in which the Snipcart shopping cart should run. By default it uses the "first" currency from SnipCarts module config.

I now want to implement a kind of "currency switcher" which should allow to (as the name says) switch the currency from within a ProcessWire template on the fly. So MarkupSnipWire should be able to receive the currency string (ISO 3 letters) and internally switch the used currency formats.

What would be the best method to send a param to an autoloader module?

If you have a look at the module code you can see there is a renderCSSJS method which is triggered by a hook after pager render in init().

https://github.com/gadgetto/SnipWire/blob/3d7af17a37fb20dcdd4038cd99339ecb704e5aef/MarkupSnipWire/MarkupSnipWire.module.php#L154

When this method is called, the $this->currency property already needs to be set.

setCurrency method is already available!

The goal is to let a developer use the SnipWire API variable in his templates like this:

$snipwire->setCurrency('usd');

 

Share this post


Link to post
Share on other sites

Can't you just save the currency in the user's $session ?

Share this post


Link to post
Share on other sites
26 minutes ago, bernhard said:

Can't you just save the currency in the user's $session ?

Hey @bernhard, this is not the problem. In front-end we could set the currency via POST, GET or SESSION or even via a API call $snipwire->setCurrency('usd');

But I'd like to set a parameter for MarkupSnipWire so that the module internally uses the desired currency for output rendering.

Share this post


Link to post
Share on other sites

@Gadgetto First of all a big thank you for creating such a module!

I have installed it just now for the first time. I followed the installation / configuration steps, defined templates etc. But in the frontend I get an error when trying to access mysite.com/snipcart-shop/

1743277425_Screenshot_2020-02-07ErrorCalltoundefinedfunctionProcessWireukIcon().thumb.png.07d7e5be5916178130e7f01c95d74d1c.png

Any ideas what went wrong? I'm using latest PW dev, and AdminTheme UIKit is installed + active.

Share this post


Link to post
Share on other sites
11 minutes ago, dragan said:

Any ideas what went wrong? I'm using latest PW dev, and AdminTheme UIKit is installed + active

Hi @dragan, this is a front-end problem:

The sample templates, which come as an additional installation, are based on the Regular site profile which is based on Markup regions output strategy and UIKit CSS framework.

ukIcon is a function in _uikit.php which is part of the regular site profile.

If you are using another profile or output strategy, you'll need to adapt the template source. If you like to run a quick test - just install PW using the "regular" profile.

Share this post


Link to post
Share on other sites

Thank you. I'm using the multilanguage as base... getting the _uikit.php from Github did the trick!

Share this post


Link to post
Share on other sites
Just now, dragan said:

Thank you. I'm using the multilanguage as base... getting the _uikit.php from Github did the trick!

Great! Just let me know if you need some help in using SnipWire as the docs are in the early stages at best... 😀

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By d'Hinnisdaël
      Happy new year, everybody 🥬
      I've been sitting on this Dashboard module I made for a client and finally came around to cleaning it up and releasing it to the wider public. This is how it looks.
      ProcessWire Dashboard

      If anyone is interested in trying this out, please go ahead! I'd love to get some feedback on it. If this proves useful and survives some real-world testing, I'll add this to the module directory.
      Download
      You can find the latest release on Github.
      Documentation
      Check out the documentation to get started. This is where you'll find information about included panel types and configuration options.
      Custom Panels
      My goal was to make it really simple to create custom panels. The easiest way to do that is to use the panel type template and have it render a file in your templates folder. This might be enough for 80% of all use cases. For anything more complex (FormBuilder submissions? Comments? Live chat?), you can add new panel types by creating modules that extend the DashboardPanel base class. Check out the documentation on custom panels or take a look at the HelloWorld panel to get started. I'm happy to merge any user-created modules into the main repo if they might be useful to more than a few people.
       Disclaimer
      This is a pre-release version. Please treat it as such — don't install it on production sites. Just making sure 🍇
      Roadmap
      These are the things I'm looking to implement myself at some point. The wishlist is a lot longer, but those are the 80/20 items that I probably won't regret spending time on.
      Improve documentation & add examples ⚙️ Panel types Google Analytics ⚙️ Add new page  🔥 Drafts 🔥 At a glance / Page counter 404s  Layout options Render multiple tabs per panel panel groups with heading and spacing between ✅ panel wrappers as grid item (e.g. stacked notices) ✅ Admin themes support AdminThemeReno and AdminThemeDefault ✅ Shortcuts panel add a table layout with icon, title & summary ✅ Chart panel add default styles for common chart types ✅ load chart data from JS file (currently passed as PHP array) Collection panel support image columns ✅ add buttons: view all & add new ✅
    • By Pip
      Hi everyone!
      I'm trying out the Login/Register module for my site. Noted that the module assigns the newly registered user to login-register role. 
      Once you modify the login-register role's permissions, particularly adding page-edit, the new member role will be set to guest. 
      Thing is I'd like to grant my new users the power to create their own pages. Any advice? 
      Thanks. 
    • By Sten
      Hello
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      Requirements
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      Adding custom path not supporting anymore !
      // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files.
      All config files need to return a PHP ARRAY like examples.
      Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example.
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
    • By Robin S
      This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure.
      I'm not using this module anywhere myself but maybe it's useful to somebody.
      Repeater Depth Helper
      This module does two things relating to Repeater fields that have the "Item depth" option enabled:
      It enforces some depth rules for Repeater fields on save. Those rules are:
      The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value.
      Helper method
      The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children.
      Example

      The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list.
      // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items);
       
      https://github.com/Toutouwai/RepeaterDepthHelper
      https://modules.processwire.com/modules/repeater-depth-helper/
×
×
  • Create New...