Skip to content
/ htmx Public

An augmenter and companion to the HTMX JavaScript library.

License

Notifications You must be signed in to change notification settings

bkuhlmann/htmx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTMX

A haiku from the HTMX team:

javascript fatigue:
longing for a hypertext
already in hand

…​and from Hypermedia Systems:

The goal of [HTMX] is not less JavaScript, but less code, more readable and hypermedia-friendly code.

This gem provides native Ruby support for the HTMX JavaScript library so you can build sophisticated web applications using pure Hypermedia REST APIs while avoiding unnecessary bloat and complexity common with the JavaScript ecosystem. By building upon the original foundations of Hypermedia REST APIs, you can build rich web applications with no additional JavaScript!

At the moment, the functionality of this gem is still in the early stages of development but the goal of this gem is to aid with the development of HTMX applications.

đź’ˇ This is used with the Hanamismith gem when building Hanami applications. Even better, you can play with the Hanami demo application to learn more. Enjoy!

Features

  • Augments the HTMX JavaScript library.

  • Speeds up HTMX development.

  • Compatible with Hanami, Roda, and other web frameworks.

Requirements

  1. A strong understanding of Hypermedia Systems.

  2. HTMX.

  3. Ruby.

Setup

To install with security, run:

# đź’ˇ Skip this line if you already have the public certificate installed.
gem cert --add <(curl --compressed --location https://alchemists.io/gems.pem)
gem install htmx --trust-policy HighSecurity

To install without security, run:

gem install htmx

You can also add the gem directly to your project:

bundle add htmx

Once the gem is installed, you only need to require it:

require "htmx"

Usage

One of the first tasks you’ll want to tackle, when working with the HTMX library, is building HTMX specific HTML attributes. This can be accomplished by using the .[] method. For example, when implementing a Hanami view part, you could use the following:

tag.button(
  "Delete",
  class: "button decline",
  type: "submit",
  **HTMX[target: "closest .task", delete: "/tasks/#{value.id}"]
)

The above would produce the following:

<button class="button decline" type="submit" hx-target="closest .task" hx-delete="/tasks/1">
  Delete
</button>

Notice the appropriate HTMX hx-target and hx-delete attributes are built which are compatible with the HTMX library while not having to manually prefix each one of these attributes with the hx- prefix. You can even use symbols, strings, or a mix of both as well.

HTML Attribute Prefixes

As shown above, building HTMX attributes takes minimal effort but if you’d prefer the HTML data- prefix, which the HTMX library supports, you can customize by using the following:

prefixer = HTMX::Prefixer.new "data-hx"

tag.button(
  "Delete",
  class: "button decline",
  type: "submit",
  **prefixer.call(target: "closest .task", delete: "/tasks/#{value.id}")
)

This would then produce the following HTML code:

<button class="button decline"
        type="submit"
        data-hx-target="closest .task"
        data-hx-delete="/tasks/1"
>
  Delete
</button>

As you can see, the data-hx-target and data-hx-delete keys are used. These are definitely more verbose than the hx- keys. By the way, the HTMX::Prefixer is called when using the HTMX .[] as shown earlier. This means the following are equivalent:

HTMX[delete: "/tasks/1"]
HTMX::Prefixer.new.call delete: "/tasks/1"
HTMX::Prefixer.new("hx").call delete: "/tasks/1"

All three of the above will produce the same output which means you’ll most likely want to use the .[] method since it has the shortest syntax.

If you attempt to use an unsupported prefix, you’ll get an error:

HTMX::Prefixer.new "bogus"
# Invalid prefix: "bogus". Use: "hx" or "data-hx". (HTMX::Error)

Some HTMX attributes use dashes. For those situations, you can use strings for keys or underscored symbols to produce the correct HTMX syntax. Here’s and example using both a string and symbol for keys:

HTMX["swap-oob" => true, push_url: "/demo/123"]
# {"hx-swap-oob"=>true, "hx-push-url"=>"/demo/123"}

HTTP Headers

When working with HTTP requests/responses, especially HTTP headers, there are a few objects that can parse and make the data easier to work with. These objects are named accordingly: request and response. Here’s how to use them.

Request

The request object allows you to obtain a Data object to interact with when parsing HTMX HTTP request headers. Example:

HTMX::Headers::Request.new

# <data HTMX::Headers::Request boosted=nil,
#                              current_url=nil,
#                              history_restore_request=nil,
#                              prompt=nil,
#                              request=nil,
#                              target=nil,
#                              trigger_name=nil,
#                              trigger=nil
# >

Notice you get a Data instance where all members have the HX- prefix removed while each value defaults to nil. Even better — and more practical — is you can ask the request object to parse the incoming HTTP headers directly and give you exactly what you need:

HTMX::Headers::Request.for request.env

# <data HTMX::Headers::Request boosted="true",
#                              current_url="/demo",
#                              history_restore_request=nil,
#                              prompt="Yes",
#                              request="true",
#                              target="demo",
#                              trigger_name="save",
#                              trigger="demo"
# >

With the above, the .for method plucks out only the HTMX specific headers which may or may not have values. Extra header keys, which are not specific to HTMX, are ignored.

Response

The response object allows you to obtain a Data object to interact with when parsing HTMX HTTP response headers. Example:

HTMX::Headers::Response.new

# <data HTMX::Headers::Response location=nil,
#                               push_url=nil,
#                               redirect=nil,
#                               refresh=nil,
#                               replace_url=nil,
#                               reswap=nil,
#                               retarget=nil,
#                               trigger=nil,
#                               trigger_after_settle=nil,
#                               trigger_after_swap=nil
# >

Notice you get a Data instance where all members have the HX- prefix removed while each value defaults to nil. Even better — and more practical — is you can ask the response object to parse the incoming HTTP headers directly and give you exactly what you need:

HTMX::Headers::Response.for response.headers

# <data HTMX::Headers::Response location="/",
#                               push_url="/demo",
#                               redirect="/demo",
#                               refresh="true",
#                               replace_url="/demo",
#                               reswap="none",
#                               retarget=".demo",
#                               trigger="demo",
#                               trigger_after_settle="demo",
#                               trigger_after_swap="demo"
# >

With the above, the .for method plucks out only the HTMX specific headers which may or may not have values. Extra header keys, which are not specific to HTMX, are ignored.

Errors

As you’ve probably picked up by now, any/all errors issued by this gem will be an instance of the HTMX::Error class which inherits from StandardError. you can use this classification to catch and deal with these errors in your own implementation as desired.

Development

To contribute, run:

git clone https://github.com/bkuhlmann/htmx
cd htmx
bin/setup

You can also use the IRB console for direct access to all objects:

bin/console

Tests

To test, run:

bin/rake

Credits

About

An augmenter and companion to the HTMX JavaScript library.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Languages