HTMX example app that demonstrates how to use HTMX to add javascript interactivity to a serverside rendered PHP app

Overview

HTMX examle app

This demo app demonstrates how to use HTMX to transform a server side rendered PHP app into a more 'interactive' app with AJAX requests switching out parts of the webpage. It is 100% "degradeable" so it works exactly the same for a user that has Javascript blocked (each request just does a full page load).

What are the moving parts

In this example there is very few moving parts. The framework doesnt do anything special, nor relevant for this example. Requests are dispatched to the Router that calls a Controller. The Controller talks to a mock service (pretend it has a DB behind it) and picks a view to create a response from.

The one trick move

The one "clever" trick is a Middleware that looks for a request header (HX-Request) and uses it to tell the Response object wether it should pack the view into a layout or not. This along with the use of hx-push-url (or when it is done as automatic part of hx-boost), ensures that wether you navigated through ajax requests or not, you can always refresh the page or copy the url and it will take you to the complete page.

// config/middlewares.php
function(Request $request, Chain $chain): Response {
    $response = $chain->next($request, $chain);
    if ($response instanceof Page && $request->header('HX-Request')) {
        $response->layout = false;
    }
    return $response;
}

Editing the views to make them HTMX

If you look at the layout file /layouts/default/head.html.php you see we have a div target there with the id content. It is what is targeted by the HTMX boosting (instead of the body default) so that we can keep the layout (header and footer).

So what do we need to do to the view files to HTMXify them? Lets take a look at each of them:

The list

We start with (content/contact/list.html.php:

<h2>Contacts</h2>
<ul>
	<?php foreach ($contacts as $id => $name) : ?>
	<li>
		<a href="/contact/<?=$id?>"><?=$name?></a>
	</li>
	<?php endforeach; ?>
</ul>

We could keep the list and add the form somewhere else very easily, but in this example we will just replace the list content with the view content. This can be done by adding hx-boost to the link tags. We want to only replace part of the page we also add the hx-target attribute.

Since HTMX does something similar to JS hoisting, we can put the changes on the parent ul instead of each a tag. So we end up with:

<h2>Contacts</h2>
<ul hx-target="#content" hx-boost="true">
	<?php foreach ($contacts as $id => $name) : ?>
	<li>
		<a href="/contact/<?=$id?>"><?=$name?></a>
	</li>
	<?php endforeach; ?>
</ul>

Similarily the view view (content/contact/view.html.php) has a link to editing the contact, we also just change that link to HTMX like so <a class="btn btn-primary" href="/contact/<?=$id?>/edit" hx-boost="true" hx-target="#content" >Edit</a>

The form

The form view is almost as easily upgrade. We don't need to mess with the submit nor the cancel link. All the changes are done by adding hx-target and hx-boost to the form tag. The 1 gotcha here is that to ensure that the address bar in browser reflects the current state, we alost must add the hx-push-url:

<form method="POST" action="/contact/<?=$id?>"
      hx-target="#content"
      hx-push-url="/contact/<?=$id?>"
      hx-boost="true">
  <div>
    <label>First Name</label>
    <input type="text" name="firstName" value="<?=$person['firstName']?>">
  </div>
  <div class="form-group">
    <label>Last Name</label>
    <input type="text" name="lastName" value="<?=$person['lastName']?>">
  </div>
  <div class="form-group">
    <label>Email Address</label>
    <input type="email" name="email" value="<?=$person['email']?>">
  </div>
  <a class="btn" href="/contact/<?=$id?>">Cancel</a> |
    <input type="submit" name="Submit" />
</form>
You might also like...
The game is implemented as an example of scalable and high load architecture combined with modern software development practices
The game is implemented as an example of scalable and high load architecture combined with modern software development practices

Crossword game The game is implemented as an example of scalable and high load architecture combined with modern software development practices Exampl

my personal example of Laravel clean architecture

what is this repo about Clean Architect Laravel ###run we assume docker desktop is up and running open up a terminal cd project directory run "cp .env

A sample project to showcase a real world example and benchmarks for crowphp

CrowPHP Sample project This project is to showcase an example of how a real world project might look like. It has two basic endpoints to show-case the

Simple laravel5 example for tutorial

Laravel 5 example For Laravel 5.3 improved version look at this repository. Laravel 5 example is a tutorial application for Laravel 5.2 (in french the

TYPO3 Camp Rhein-Ruhr - Sitepackage Example

EXT:t3crr_sitepackage - A example TYPO3 Sitepackage Extension This extension was used in the T3CRR Talk "Sitepackage Einführung" in 2021! Notice Bewar

This example shows how to estimate pi, using generated random numbers that uniformly distributed.
This example shows how to estimate pi, using generated random numbers that uniformly distributed.

php-estimatepi This example shows how to estimate pi, using generated random numbers that uniformly distributed. Every pair of numbers produced will b

Phalcon Mooc an example API + Front End with automated tests
Phalcon Mooc an example API + Front End with automated tests

NovaMooc - a Phalcon project A Mooc project developed with Phalcon, a PHP framework. Key Features • How To Use • Contributing • Credits • License Key

This repository aims to build a fairly complete CI/CD example using GitHub workflows and actions.
This repository aims to build a fairly complete CI/CD example using GitHub workflows and actions.

CI/CD example This repository aims to build a fairly complete CI/CD example using GitHub workflows and actions. Keep in mind that the toolset used in

A list of documentation and example code to access the University of Florida's public (undocumented) API

uf_api A list of documentation and example code to access the University of Florida's public (undocumented) API Courses Gym Common Data (admissions an

Owner
Alexander Morland
Alexander Morland
This Statamic addon allows you to modify the tags rendered by the Bard fieldtype, giving you full control over the final HTML.

Bard Mutator This Statamic addon allows you to modify the tags rendered by the Bard fieldtype, giving you full control over the final HTML. You can ad

Jack Sleight 10 Sep 26, 2022
A SilverStripe module for conveniently injecting JSON-LD metadata into the header of each rendered page in SilverStripe

A SilverStripe module for conveniently injecting JSON-LD metadata into the header of each rendered page in Silver

null 4 Apr 20, 2022
This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

Kraken 48 Aug 11, 2021
This is a project demonstrates how to improve authoring experience Matrix Façades

About nystudio107/matrixfacades This is a project demonstrates how to improve authoring experience Matrix Façades Using nystudio107/matrixfacades Init

nystudio107 3 Aug 16, 2022
My intention with this app is that new developers can have a concrete application with Laravel + VueJS where they can use it as example to learn the right way

My intention with this app is that new developers can have a concrete application with Laravel + VueJS where they can use it as example to learn the right way, implementing the best practices possible and at the same time learn how TDD is done. So this will be an example application but completely usable for any similar case.

Eng Hasan Hajjar 2 Sep 30, 2022
This is an example app demonstrating how to deploy a php app to runway.

Runway Example php App This is an example app demonstrating how to deploy a php app to runway. clone this repo, and navigate into that directory runwa

Planetary Quantum GmbH 0 Aug 9, 2022
This example shows how to use Anychart library with the PHP programming language, Laravel framework and MySQL database.

PHP basic template This example shows how to use Anychart library with the PHP programming language, Laravel framework and MySQL database. Running To

AnyChart Integrations and Templates 23 Jul 17, 2022
Laravel & Solana Phantom wallet example built with Bootstrap, JQuery. App connects to Phantom wallet and fetching publicKey and balance information.

Phantom Wallet Authentication Example Laravel & Solana ($SOL) Phantom wallet example built with Bootstrap, JQuery. This is a Web 3.0 app that connects

Solanacraft 3 Oct 19, 2022
Nextcloud-App to add groups with AppDirect

App Direct Place this app in nextcloud/apps/ Building the app The app can be built by using the provided Makefile by running: make This requires the

Tim Vosskühler 3 Dec 2, 2022
Michael Pratt 307 Dec 23, 2022