All Projects → vapor-community → Htmlkit

vapor-community / Htmlkit

Licence: mit
A type-safe DSL that renders dynamic HTML templates in Swift

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Htmlkit

Leaf
🍃 An expressive, performant, and extensible templating language built for Swift.
Stars: ✭ 310 (+35.37%)
Mutual labels:  server-side-swift, vapor, swift-linux, template-language
routing-kit
🚍 High-performance trie-node router.
Stars: ✭ 95 (-58.52%)
Mutual labels:  vapor, server-side-swift, swift-linux
Http
🚀 Non-blocking, event-driven HTTP built on Swift NIO.
Stars: ✭ 220 (-3.93%)
Mutual labels:  server-side-swift, vapor, swift-linux
Core
🌎 Utility package containing tools for byte manipulation, Codable, OS APIs, and debugging.
Stars: ✭ 62 (-72.93%)
Mutual labels:  server-side-swift, vapor, swift-linux
Fluent Sqlite Driver
Fluent driver for SQLite
Stars: ✭ 51 (-77.73%)
Mutual labels:  server-side-swift, vapor, swift-linux
auth
👤 Authentication and Authorization framework for Fluent.
Stars: ✭ 51 (-77.73%)
Mutual labels:  vapor, server-side-swift, swift-linux
Vapor Clean
A Vapor 3 template with no additional cruft.
Stars: ✭ 80 (-65.07%)
Mutual labels:  server-side-swift, vapor, swift-linux
sqlite-kit
Non-blocking SQLite client library with SQL builder built on SwiftNIO
Stars: ✭ 51 (-77.73%)
Mutual labels:  vapor, server-side-swift, swift-linux
Open Crypto
🔑 Hashing (BCrypt, SHA2, HMAC), encryption (AES), public-key (RSA), and random data generation.
Stars: ✭ 115 (-49.78%)
Mutual labels:  server-side-swift, vapor, swift-linux
Redis
Vapor provider for RediStack
Stars: ✭ 434 (+89.52%)
Mutual labels:  server-side-swift, vapor, swift-linux
async
⏱ Promises and reactive-streams in Swift built for high-performance and scalability.
Stars: ✭ 35 (-84.72%)
Mutual labels:  vapor, server-side-swift, swift-linux
Api Template
💧 A starting point for Vapor APIs.
Stars: ✭ 130 (-43.23%)
Mutual labels:  server-side-swift, vapor, swift-linux
fluent-postgres-driver
🐘 PostgreSQL driver for Fluent.
Stars: ✭ 120 (-47.6%)
Mutual labels:  vapor, server-side-swift, swift-linux
Fluent
Vapor ORM (queries, models, and relations) for NoSQL and SQL databases
Stars: ✭ 1,071 (+367.69%)
Mutual labels:  server-side-swift, vapor, swift-linux
fluent-mysql-driver
🖋🐬 Swift ORM (queries, models, relations, etc) built on MySQL.
Stars: ✭ 69 (-69.87%)
Mutual labels:  vapor, server-side-swift, swift-linux
sourcery-templates
Building Vapor projects using meta programming with Sourcery ✨
Stars: ✭ 24 (-89.52%)
Mutual labels:  template-language, vapor, server-side-swift
Console Kit
💻 APIs for creating interactive CLI tools.
Stars: ✭ 252 (+10.04%)
Mutual labels:  server-side-swift, vapor, swift-linux
Jwt
Vapor JWT provider
Stars: ✭ 266 (+16.16%)
Mutual labels:  server-side-swift, vapor, swift-linux
Sockets
🔌 Non-blocking TCP socket layer, with event-driven server and client.
Stars: ✭ 559 (+144.1%)
Mutual labels:  server-side-swift, vapor, swift-linux
Mysql Kit
🐬 Pure Swift MySQL client built on non-blocking, event-driven sockets.
Stars: ✭ 159 (-30.57%)
Mutual labels:  server-side-swift, vapor, swift-linux

HTMLKit logo

HTMLKit

Render dynamic HTML templates in a typesafe and performant way! By using Swift's powerful language features and a pre-rendering algorithm, HTMLKit will render insanely fast templates but also catch bugs that otherwise might occur with other templating options.

Getting Started

Add the following in your Package.swift file

.package(url: "https://github.com/vapor-community/HTMLKit.git", from: "2.0.0"),

You can use the following providers in order to use HTMLKit with Vapor 3 and for Vapor 4

for instance for Vapor 4, you have to add the HTMLKit vapor provider like this

.package(name: "HTMLKitVaporProvider", url: "https://github.com/MatsMoll/htmlkit-vapor-provider.git", from: "1.0.0"),
...
.product(name: "HTMLKit", package: "HTMLKit"),
.product(name: "HTMLKitVaporProvider", package: "HTMLKitVaporProvider"),

Usage

View the different tags and types defined in HTMLKit on the Wiki page.

To create a HTML template, conform to the HTMLTemplate protocol.

struct TemplateData {
    let name: String
    let handle: String
    let title: String?
}

struct SimpleTemplate: HTMLTemplate {

    @TemplateValue(TemplateData.self)
    var context

    var body: HTML {
        Document(type: .html5) {
            Head {
                Title { context.title }
                Author { context.name }
                    .twitter(handle: context.handle)
                Viewport(.acordingToDevice)
            }
            Body {
                Unwrap(context.title) { title in
                    P { title }
                }
            }
        }
    }
}

// For Vapor 4, you certainly want to preload the template in configure to optimize rendering.
// in configure.swift
import HTMLKitVaporProvider
...
public func configure(_ app: Application) throws {
    ...
    try app.htmlkit.add(view: SimpleTemplate())
    ...
}

// In one of your controllers
import HTMLKit
...
func get(req: Request) throws -> EventLoopFuture<View> {
    return Simple.query(on: req.db)
        .filter(...)
        .first()
        .unwrap(or: Abort(.notFound))
        .flatMap {
            SimpleTemplate().render(with: TemplateData(name: $0.name, ...), for: req)
        }
}

This will render something like this

<!DOCTYPE html>
<html>
    <head>
        <title>Some Title</title>
        <meta property='og:title' content='Some Title'>
        <meta name='twitter:title' content='Some Title'>
        <meta name='author' content='Mats'>
        <meta name='twitter:creator' content='@SomeTwitterHandle'>
        <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    </head>
    <body>
        <p>Some Title</p>
    </body>
</html>

And to create a HTML component, just conform to the HTMLComponent protocol.

public struct Alert: HTMLComponent {

    let isDismissable: Conditionable // This is a protocol that makes it possible to optimize if's
    let message: HTML

    public var body: HTML {
        Div {
            message

            IF(isDismissable) {
                Button {
                    Span { "&times;" }
                        .aria(for: "hidden", value: true)
                }
                .type(.button)
                .class("close")
                .data("dismiss", value: "alert")
                .aria("label", value: "Close")
            }
        }
        .class("alert alert-danger bg-danger")
        .modify(if: isDismissable) {
            $0.class("fade show")
        }
        .role("alert")
    }
}

This can then be used in another template or a static html page like:

struct SomePage: HTMLPage {

    var body: HTML {
        Div {
            Alert(isDismissable: false) {
                H3 { "Some Title" }
            }
        }
    }
}

Mixing HTMLKit with Leaf

You can easily mix Leaf and HTMLKit in the same project.

struct RenderingConfig: Content {
    let message: String
    let useHTMLKit: Bool
}

func renderLogin(on req: Request) -> Future<View> {
    let query = try req.query.decode(RenderingConfig.self)
    if config.useHTMLKit {
        return LoginPage().render(with: config, on: req)
    } else {
        return req.view().render("login-page", with: config)
    }
}

Localization

Much like SwiftUI, you can localize text by passing the localization key as a parameter.

...
var body: HTML {
    P("hello.world")
        .class("text-white")
}
...

This requires the Lingo framework, so you will also need to register the Lingo struct on the renderer.

var renderer = HTMLRenderer()
try renderer.registerLocalization(atPath: "workDir", defaultLocale: "en")

And if the locale changes based on some user input, then you can change the used locale in the template. This also effects how dates are presented to the user.

struct LocalizedDateView: HTMLTemplate {

    struct Context {
        let date: Date
        let locale: String
    }

    var body: HTML {
        Div {
            P {
                context.date
                    .style(date: .short, time: .short)
            }
            P {
                context.date
                    .formatted(string: "MM/dd/yyyy")
            }
        }
        .enviroment(locale: context.locale)
    }
}

Useful Resources to Get Started

Known Issues

  • Linux compiler can sometimes struggle with compiling the code when a combination of complex use of generics, default values or deeply nested function builders are used.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].