diff --git a/README.md b/README.md index 8c61216..03a6a28 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,6 @@ Examples showing how to do many things in Gleam! ## Formats +- [Rendering HTML](./universal/test/formats/rendering_html.gleam) - [Rendering JSON](./universal/test/formats/rendering_json.gleam) - [Rendering XML](./universal/test/formats/rendering_xml.gleam) diff --git a/universal/gleam.toml b/universal/gleam.toml index 99d7f9a..9f044cf 100644 --- a/universal/gleam.toml +++ b/universal/gleam.toml @@ -17,6 +17,7 @@ gleam_stdlib = ">= 0.34.0 and < 2.0.0" simplifile = ">= 2.1.0 and < 3.0.0" xmb = ">= 1.0.0 and < 2.0.0" gleam_json = ">= 1.0.1 and < 2.0.0" +lustre = ">= 4.4.4 and < 5.0.0" [dev-dependencies] gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/universal/manifest.toml b/universal/manifest.toml index ec26927..a843c49 100644 --- a/universal/manifest.toml +++ b/universal/manifest.toml @@ -3,9 +3,12 @@ packages = [ { name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" }, + { name = "gleam_erlang", version = "0.26.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "3DF72F95F4716883FA51396FB0C550ED3D55195B541568CAF09745984FD37AD1" }, { name = "gleam_json", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "9063D14D25406326C0255BDA0021541E797D8A7A12573D849462CAFED459F6EB" }, + { name = "gleam_otp", version = "0.12.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "CD5FC777E99673BDB390092DF85E34EAA6B8EE1882147496290AB3F45A4960B1" }, { name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" }, { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, + { name = "lustre", version = "4.4.4", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "35A8597B3054AFAF734A54979B7C92D8AB43273B843717F854CF5A05CF2BC00E" }, { name = "simplifile", version = "2.1.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "BDD04F5D31D6D34E2EDFAEF0B68A6297AEC939888C3BFCE61133DE13857F6DA2" }, { name = "thoas", version = "1.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "E38697EDFFD6E91BD12CEA41B155115282630075C2A727E7A6B2947F5408B86A" }, { name = "xmb", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "xmb", source = "hex", outer_checksum = "99425CD67BA2AF3E4A38515FB4BFCC121007B69444C81DE6EB837421290F14B4" }, @@ -15,5 +18,6 @@ packages = [ gleam_json = { version = ">= 1.0.1 and < 2.0.0" } gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } gleeunit = { version = ">= 1.0.0 and < 2.0.0" } +lustre = { version = ">= 4.4.4 and < 5.0.0" } simplifile = { version = ">= 2.1.0 and < 3.0.0" } xmb = { version = ">= 1.0.0 and < 2.0.0" } diff --git a/universal/test/formats/rendering_html.gleam b/universal/test/formats/rendering_html.gleam new file mode 100644 index 0000000..9dddc30 --- /dev/null +++ b/universal/test/formats/rendering_html.gleam @@ -0,0 +1,70 @@ +//// # Generate JSON +//// +//// Lustre is often used for complex stateful HTML applications, but it also +//// makes a great type-safe HTML templating system. It works on all targets. +//// +//// ## Dependencies +//// +//// - https://hex.pm/packages/lustre + +import gleam/string +import gleeunit/should +import lustre/attribute +import lustre/element +import lustre/element/html + +pub fn main_test() { + // Lustre provides functions for HTML elements and attributes that can be used + // to construct a HTML document. + // + let document = + html.html([], [ + html.head([], [html.title([], "Greetings!")]), + html.body([], [ + html.h1([attribute.id("greeting")], [ + html.text("Hello, Joe! Hello, Mike!"), + ]), + ]), + ]) + + // The document can be converted to a string. + document + |> element.to_document_string + |> should.equal(normalise_test_html( + " + + + + Greetings! + + +

Hello, Joe! Hello, Mike!

+ + + ", + )) + + // Or you can render a fragment without a doctype. + html.input([ + attribute.for("name"), + attribute.type_("text"), + attribute.value("Lucy"), + ]) + |> element.to_string + |> should.equal("") +} + +// +// Lustre has excellent documentation. Check it out for more information +// https://hexdocs.pm/lustre/ +// + +fn normalise_test_html(html: String) -> String { + // We write the text expectations in a pretty-printed format to make it easier + // to understand, but Lustre produces minified HTML for performance and + // compactness, so this functional normalises it so they match. + html + |> string.replace(" ", "") + |> string.replace("\n", "") + |> string.replace("", "\n") +}