Jump to content

Module Development: Inline Frontend Applications?


Inxentas
 Share

Recommended Posts

I have a pretty broad question about module development. At the moment I have a module (a webshop) which contains some template and class files, which the module will move into the relevant folders (site/templates and site/classes) on install. It will also create a few pages to create the initial page structure, as well as a Process that I place beneath the Admin page. Now imagine that a page with the "product" template contains a form that posts the product ID and a quantity to itself, or another page which then redirects the request. So far so good, that would work. I would like to make it so the module works "out of the box" with some bare-bones templates the developer can modify / style after install. 

What I am not so sure about is how I'd typically create inline interaction that works "out of the box". On most webshops, a user might click the "add to cart" button and then some Javascript fires, adding the product to the cart through an AJAX call. Now, I could make it so some file (let's call it _webshop.php) is prefixed to a template instead of _main.php, that ensures any Javascript I supply gets loaded on pages that have such interactions. But I am unsure what kind of Javascript to use for AJAX related stuff in the frontend. I would have no issues having the module copy a .JS file into the /template/scripts folder, but I'm unsure on how to structure the JS itself.

I've developed apps with Vue3 and (in the olden days) AngularJS or jQuery, but I also see some AJAX interaction in ProcessWire's page tree. Whenever you click on a page that has children, I can see an URL gets called in the Network tab of Chrome's inspector. That means there must already be a methodology the backend uses. Looking at the <head> section of a backend page, I suspect this was done using JQuery. Here is an example url I plucked from the inspector. It's clearly a GET, whereas I would be using POST, but that's just a detail.

/page/list/?id=1110&render=JSON&start=0&lang=0&open=undefined&mode=actions

Now I am hesitant to use JQuery (as anyone used to Vue would, I reckon). I was wondering if anyone else has ideas on how to best implement frontend AJAX interactions for inline actions, when working in the context of a module? I've considered to write a Vue3 app and simpy have _webshop.php load Vue3 from a CDN, but this feels "messy" to me and not very self-contained. I would also want to prevent introducing a whole Javascript framework, especially when the existing codebase already includes a methodology for AJAX calls. I know this "question" is pretty vague, but I had hoped the community could push me in the right direction. Thank you for reading my post.

Link to comment
Share on other sites

51 minutes ago, Inxentas said:

I was wondering if anyone else has ideas on how to best implement frontend AJAX interactions for inline actions, when working in the context of a module?

I think there is no consensus right now about this and indeed pretty much all the asynchronous interactions you see on the backend are powered by jQuery. I'd say go with Vue if that is what you feel most comfortable with. 

Link to comment
Share on other sites

Hi @Inxentas With ProcessWire, you can use whatever you want on the frontend: Vanilla JS, jQuery, Vue.

I would recommend that you take a look at htmx, which seems very interesting and should align well with ProcessWire's philosophy. As far as I know, Alpine.js is often used in conjunction with HTMX for frontend scripting.

By the way, there are some excellent essays on htmx's website. I highly recommend reading them for everyone involved in web development.

  • Like 1
Link to comment
Share on other sites

Damn - ninja'd by @slkwrm but I was just saying the same thing:

 

There's been a lot chat in this forum recently about htmx so I'm giving it a go on a dashboard webapp we're currently building and it's been working very well indeed.

In our case we've built a module where we create URL hooks that handle ajax requests from htmx

// initialize the hook in your AutoLoad module
public function init()
{

	wire()->addHook('/api/log-activity', function($event) {
		include('ajax_log_activity.php');
	});

}

Then it's just a case of marking up your button or form to post whatever you need to that url:

<form id="log_form" hx-post="/api/log-activity" hx-target="#log_form_bits">

<!-- or a button -->

<button class="butt butt_secondary" hx-post="/api/log-activity-delete/<?=$some_id?>" hx-target="#your_target" hx-confirm="Are you sure you wish to delete this log entry?">Delete</button>
Link to comment
Share on other sites

1 hour ago, slkwrm said:

I would recommend that you take a look at htmx, which seems very interesting and should align well with ProcessWire's philosophy. As far as I know, Alpine.js is often used in conjunction with HTMX for frontend scripting.

 

I think you meant to tag @Inxentas ??

I'm a big fan of both of these libraries and I also think they match really well (specifically htmx in this regard) with ProcessWire's existing PHP API, the Inputfield objects, for example. 

Link to comment
Share on other sites

First of all if you are coming from vue, alpine.js syntax might look familiar to you. You can think of alpine as TailwindCSS but for JavaScript.

Both frameworks / libraries have small footprint, but serve different purposes. But the also share some silmiarities like declarative syntax and progressive enhancement.

Here a some differences between htmx and alpine.js.

Approach: HTMX focuses on accessing server-side functionality for creating dynamic components using AJAX, WebSockets, and Server Sent Events. In contrast, Alpine.js is an in-browser framework that brings the minimalism and simplicity of Vue.js to your markup, keeping the behavior and data manipulation on the client side.

Data-binding: While Alpine.js incorporates two-way data binding and can manage multiple state objects with the $data attribute, HTMX does not offer full data-binding capabilities and generally interacts more with server-rendered content.

Server-side vs Client-side: HTMX does not force you to use client-side rendering like many popular frameworks. It aims to work with server-generated HTML, which can be advantageous for SEO and page load speeds. On the other hand, Alpine.js is entirely client-side and handles creating and manipulating DOM elements using reactive data properties.

Event Handling: Alpine.js includes event handling with the @ syntax, allowing you to attach event listeners directly to elements. HTMX, in contrast, primarily uses event handling for AJAX-related events like onLoad and onError.

Link to comment
Share on other sites

Thanks for your replies, dear people! I am going to take a look at the suggested JS libraries / frameworks and see what's most suitable for the application. Your descriptions of Alpine and htmx's features were very helpful. It sounds like Alpine would be something I could learn quite easily, but htmx's SEO advantage might be something I end up liking very much. One last question though: do module developers usually supply the JS code with the module, or do module devs tend to lean on a CDN? Performance and footprint is less important to me, but I like the idea of having the module work "out of the box" without requiring code from a CDN, and offering alternate solutions for client who want custom designs for everything. 

  • Like 1
Link to comment
Share on other sites

alpine.js does not have any disadvantages to SEO, depending on what you do with it.

I normally ship my modules with my custom code (if that is what you meant). I also include libraries like tabulator.info or alpine.js not using a CDN.

Link to comment
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
 Share

×
×
  • Create New...