Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/juliojimenez/hypermedia.systems

Examples from the book Hypermedia Systems.
https://github.com/juliojimenez/hypermedia.systems

flask htmx hypermedia hyperview mypy pytest python python3

Last synced: 2 months ago
JSON representation

Examples from the book Hypermedia Systems.

Awesome Lists containing this project

README

        

# hypermedia.systems

[![Type Checker](https://github.com/juliojimenez/hypermedia.systems/actions/workflows/typechecker.yml/badge.svg)](https://github.com/juliojimenez/hypermedia.systems/actions/workflows/typechecker.yml) [![Tests](https://github.com/juliojimenez/hypermedia.systems/actions/workflows/tests.yml/badge.svg)](https://github.com/juliojimenez/hypermedia.systems/actions/workflows/tests.yml)

Examples from building the Contacts app in the book [Hypermedia Systems](https://hypermedia.systems).

The code here is slightly different from the book, as I try to use types where I can, and check for them using [Mypy](https://mypy.readthedocs.io/en/stable/index.html), a static type checker for Python.

[PyTest](https://docs.pytest.org/en/7.4.x/) is used for testing. While inside an example directory simply run `pytest` to run the tests for that example.

## Running an Example

Clone the repo...
```bash
git clone https://github.com/juliojimenez/hypermedia.systems
cd hypermedia.systems
```
Install dependencies...
```bash
pip3 install -r requirements.txt
```
Go to an example...
```bash
cd chapter-3/1-simple-hello-world/
```
And run it...
```bash
python3 app.py
```

Each example runs on a different port. Run multiple examples simultaneously and compare them in the browser!

## Examples

### Chapter 3

- [Simple Hello World](./chapter-3/1-simple-hello-world/)
- [Simple Hello World to a Redirect](./chapter-3/2-simple-hello-world-to-a-redirect/)
- [Showing a Searchable List of Contacts](./chapter-3/3-showing-a-searchable-list-of-contacts/)
- [Adding a New Contact](./chapter-3/4-adding-a-new-contact/)
- [Viewing the Details of a Contact](./chapter-3/5-viewing-the-details-of-a-contact/)
- [Editing a Contact](./chapter-3/6-editing-a-contact/)
- [Deleting a Contact](./chapter-3/7-deleting-a-contact/)

### Chapter 4

- [Installing HTMX as a Third Party Dependency](./chapter-4/1-installing-htmx-third-party/)
- [Triggering HTTP Requests](./chapter-4/2-triggering-http-requests/)
- [HTMX vs. Plain HTML Responses](./chapter-4/3-htmx-vs-plain-html-responses/)
- [Targeting Other Elements](./chapter-4/4-targeting-other-elements/)
- [Swap Styles](./chapter-4/5-swap-styles/)
- Using Events
- [mouseenter](./chapter-4/6-using-events-mouseenter/)
- [click and keyup](./chapter-4/7-using-events-click-and-keyup/)
- Passing Request Parameters
- [Enclosing Forms](./chapter-4/8-passing-request-parameters-enclosing-forms/)
- [Including Inputs](./chapter-4/9-passing-request-parameters-including-inputs/)
- [Inline Values](./chapter-4/10-passing-request-parameters-inline-values/)
- [History Support](./chapter-4/11-history-support/)

### Chapter 5

- [Installing HTMX as a Vendored Dependency](./chapter-5/1-installing-htmx-vendored/)
- [Adding hx-boost to Contacts.app](./chapter-5/2-adding-hx-boost-to-contact-app/)
- [A Second Step: Deleting Contacts With HTTP DELETE](./chapter-5/3-a-second-step-deleting-contacts-with-http-delete/)
- Next Steps: Validating Contact Emails
- [Update Our Input Type](./chapter-5/4-next-steps-validating-contact-emails-update-our-input-type/)
- [Inline Validation](./chapter-5/5-next-steps-validating-contact-emails-inline-validation/)
- [Validating Emails Server-Side](./chapter-5/6-next-steps-validating-contact-emails-validating-emails-server-side/)
- [Taking The User Experience Further](./chapter-5/7-next-steps-validating-contact-emails-taking-the-user-experience-further/)
- [Debouncing Our Validation Requests](./chapter-5/8-next-steps-validating-contact-emails-debouncing-our-validation-requests/)
- [Ignoring Non-Mutating Keys](./chapter-5/9-next-steps-validating-contact-emails-ignoring-non-mutating-keys/)
- Another Application Improvement: Paging
- [Adding Paging Widgets](./chapter-5/10-another-application-improvement-paging-adding-paging-widgets/)
- [Click To Load](./chapter-5/11-another-application-improvement-paging-click-to-load/)
- [Infinite Scroll](./chapter-5/12-another-application-improvement-paging-infinite-scroll/)

### Chapter 6

- [Adding Active Search](./chapter-6/1-adding-active-search/)
- [Targeting The Correct Element](./chapter-6/2-targeting-the-correct-element/)
- [Paring Down Our Content](./chapter-6/3-paring-down-our-content/)
- [HTTP Headers In HTMX](./chapter-6/4-http-headers-in-htmx/)
- [Factoring Your Templates](./chapter-6/4-http-headers-in-htmx/)
- [Using Our New Template](./chapter-6/4-http-headers-in-htmx/)
- [Updating The Navigation Bar With "hx-push-url"](./chapter-6/5-updating-the-navigation-bar-with-hx-push-url/)
- [Adding A Request Indicator](./chapter-6/6-adding-a-request-indicator/)
- [Lazy Loading](./chapter-6/7-lazy-loading/)
- [Pulling Out The Expensive Code](./chapter-6/8-pulling-out-the-expensive-code/)
- [Adding An Indicator](./chapter-6/9-adding-an-indicator/)
- [But That's Not Lazy!](./chapter-6/10-but-thats-not-lazy/)
- [Inline Delete](./chapter-6/11-inline-delete/)
- [Narrowing Our Target](./chapter-6/12-narrowing-our-target/)
- [Updating The Server Side](./chapter-6/13-updating-the-server-side/)
- [Taking Advantage of "htmx-swapping"](./chapter-6/14-taking-advantage-of-htmx-swapping/)
- [Bulk Delete](./chapter-6/15-bulk-delete/)
- [The "Delete Selected Contacts" Button](./chapter-6/16-the-delete-selected-contacts-button/)
- [The Server Side for Delete Selected Contacts](./chapter-6/17-the-server-side-for-delete-selected-contacts/)

### Chapter 7

- [Beginning Our Implementation](./chapter-7/1-beginning-our-implementation/)
- [Adding The Archiving Endpoing](./chapter-7/2-adding-the-archiving-endpoint/)
- [Conditionally Rendering A Progress UI](./chapter-7/3-conditionally-rendering-a-progress-ui/)
- [Using Polling To Update The Archive UI](./chapter-7/4-using-polling-to-update-the-archive-ui/)
- [Downloading The Result](./chapter-7/5-downloading-the-result/)
- [Downloading The Completed Archive](./chapter-7/6-downloading-the-completed-archive/)
- [Our Smoothing Solution](./chapter-7/7-our-smoothing-solution/)
- [Dismissing The Download UI](./chapter-7/8-dismissing-the-download-ui/)
- [An Alternative UX: Auto-Download](./chapter-7/9-an-alternative-ux-auto-download/)

### Chapter 9

- [VanillaJS in Action: An Overflow Menu](./chapter-9/1-vanillajs-in-action-an-overflow-menu)
- [Alpine.js](./chapter-9/2-alpine.js)
- [_hyperscript](./chapter-9/3-hyperscript)
- [Integrating Using Callbacks](./chapter-9/4-integrating-using-callbacks)
- [Integrating Using Events](./chapter-9/5-integrating-using-events)

### Chapter 10

- [Our First JSON Endpoint: Listing All Contacts](./chapter-10/1-listing-all-contacts)
- [Adding Contacts](./chapter-10/2-adding-contacts)
- [Viewing Contact Details](./chapter-10/3-viewing-contact-details)
- [Updating & Deleting Contacts](./chapter-10/4-updating-and-deleting-contacts)

## Support

Python 3.11+

## Dependencies

- [HTMX v1.9.5](https://htmx.org)
- [missing.css v1.0.10](https://missing.style)
- Not sure what's going on with the package hosting for this, but I had to grab the artifact from the latest tag in the [repo](https://github.com/bigskysoftware/missing).
- It was working fine when I started this repository. If it starts working again, please submit an issue or hit me up on [X](https://twitter.com/LispDev).