https://postgrest.org/en/stable/how-tos/providing-html-content-using-htmx.html
PostgREST
stable
[ ]
Tutorials
* Tutorial 0 - Get it Running
* Tutorial 1 - The Golden Key
References
* Authentication
* API
* Transactions
* Connection Pool
* Schema Cache
* Errors
* Configuration
* Admin
Explanations
* Database Authorization
* Installation
* Nginx
* Schema Isolation
How-to guides
* SQL User Management
* SQL User Management using postgres' users and passwords
* Working with PostgreSQL data types
* Create a SOAP endpoint
* Providing HTML Content Using Htmx
+ Preparatory Configuration
+ Creating an HTML Response
+ Listing and Creating To-Dos
+ Editing and Deleting To-Dos
* Providing images for
Integrations
* Greenplum
* Heroku
* External JWT Generation
* pg-safeupdate
* systemd
Ecosystem
* Community Tutorials
* Templates
* Example Apps
* DevOps
* External Notification
* Extensions
* Client-Side Libraries
PostgREST
*
* Providing HTML Content Using Htmx
* Edit on GitHub
---------------------------------------------------------------------
Providing HTML Content Using Htmx
author
Laurence Isla
This how-to shows a way to return HTML content and use the htmx
library to handle the AJAX requests. Htmx expects an HTML response
and uses it to replace an element inside the DOM (see the htmx
introduction in the docs).
../_images/htmx-demo.gif
Preparatory Configuration
We will make a to-do app based on the Tutorial 0 - Get it Running, so
make sure to complete it before continuing.
To simplify things, we won't be using authentication, so grant all
permissions on the todos table to the web_anon user.
grant all on api.todos to web_anon;
grant usage, select on sequence api.todos_id_seq to web_anon;
Next, add the text/html as a Media Type Handlers. With this,
PostgREST can identify the request made by your web browser (with the
Accept: text/html header) and return a raw HTML document file.
create domain "text/html" as text;
Creating an HTML Response
Let's create a function that returns a basic HTML file, using
Tailwind CSS for styling.
create or replace function api.index() returns "text/html" as $$
select $html$
PostgREST + HTMX To-Do List
PostgREST + HTMX To-Do List
$html$;
$$ language sql;
The web browser will open the web page at http://localhost:3000/rpc/
index.
../_images/htmx-simple.jpg
Listing and Creating To-Dos
Now, let's show a list of the to-dos already inserted in the
database.
create or replace function api.html_todo(api.todos) returns text as $$
select format($html$
%3$s
$html$,
$1.id,
case when $1.done then 'line-through text-gray-400' else '' end,
$1.task
);
$$ language sql stable;
create or replace function api.html_all_todos() returns text as $$
select coalesce(
'
'
|| string_agg(api.html_todo(t), '' order by t.id) ||
'
',
'
There is nothing else to do.
'
)
from api.todos t;
$$ language sql;
These two functions are used to build the to-do list template. We
won't use them as PostgREST endpoints.
* The api.html_todo function uses the table api.todos as a
parameter and formats each item into a list element
. The
PostgreSQL format is useful to that end. It replaces the values
according to the position in the template, e.g. %1$s will be
replaced with the value of $1.id (the first parameter).
* The api.html_all_todos function returns the
wrapper for all
the list elements. It uses string_arg to concatenate all the
to-dos in a single text value. It also returns an alternative
message, instead of a list, when the api.todos table is empty.
Next, let's add an endpoint to register a to-do in the database and
modify the /rpc/index page accordingly.
create or replace function api.add_todo(_task text) returns "text/html" as $$
insert into api.todos(task) values (_task);
select api.html_all_todos();
$$ language sql;
create or replace function api.index() returns "text/html" as $$
select $html$
PostgREST + HTMX To-Do List
PostgREST + HTMX To-Do List
$html$
|| api.html_all_todos() ||
$html$
$html$;
$$ language sql;
* The /rpc/add_todo endpoint allows us to add a new to-do using the
_task parameter and returns an html with all the to-dos in the
database.
* The /rpc/index now adds the hx-headers='{"Accept": "text/html"}'
tag to the . This will make sure that all htmx elements
inside the body send this header, otherwise PostgREST won't
recognize it as HTML.
There is also a
element is configured as follows:
+ hx-post="/rpc/change_todo_state": does an AJAX POST request
to that endpoint. It will toggle the done state of the to-do.
+ hx-vals='{"_id": %1$s, "_done": %4$s}': adds the parameters
to the request. This is an alternative to using hidden inputs
inside the
.
+ hx-trigger="click": htmx does the request after clicking on
the element.
* For the first