Skip to content

Releases: vapor-community/HTMLKit

2.0.0-beta.3.1

15 Jan 20:38
Compare
Choose a tag to compare

Performance improvements

Changed to using reduce(into: ) in more places, like when escaping variables for HTML. This cut the render time of 10 000 test templates almost in half. From 1.29 seconds to 0.82 seconds.

Added a new modifier

Div {
    "May be modify"
}
.modify(unwrap: someOptional) { value, node in
    // This will only be added if the value is defined
    node.class(value)
}

Other bug-fixes

Some improvements when using modify(if: )

2.0.0-beta.2

30 Dec 10:58
Compare
Choose a tag to compare

Made passing a TemplateValue around easier, since there are now fewer generics.

// HTMLKit 1.0.0-beta.1
struct BaseTemplate<T>: HTMLComponent {

    let context: TemplateValue<T, BaseTemplateContent>

    var body: HTML { ... }
}

// HTMLKit 1.0.0-beta.2
struct BaseTemplate: HTMLComponent {

    @TemplateValue(BaseTemplateContent.self)
    let context

    var body: HTML { ... }
}

Document also adds <html></html> tags and not only the doctype tag

Added a few higher-level tags like Stylesheet, Author, Description. These and Title also add Twitter and OpenGraph metadata.

2.0.0-beta.1

27 Dec 22:33
Compare
Choose a tag to compare

Moved the Vapor providers into two different repositories for Vapor 3 and Vapor 4. As well as performance and stability improvements. There is also added more protocols in order to limit the possibility of adding an attribute that is meaningless attribute to a node.

Added a Unwrap feature:

Unwrap(context.user) { user in
    P { "Welcome, " }
    Bold { user.name }
}

Made TemplateValue a property wrapper:

struct UserTemplate: HTMLTemplate {

    @TemplateValue(User.self) 
    var context

    var body: HTML { ... }
}

New Localisation system, and Date formatting

06 May 07:56
Compare
Choose a tag to compare

I is now possible to use a new protocol LocalizedTemplate in order to simplify localisation. This removes the locale: \.localePath argument in 1.2.0, by using a static var localePath = \.locale. It will also provide a enum LocalizationKeys where you can store the different keys (like "footer.about.us"), and therefore making it easier when referencing this key. E.g:

localize(.missingValues)
localize(key: "missing.values") // optional

// With a context
localize(.helloWorld, with: \.helloWorldContext)
localize(.helloWorld, with: ["name" : variable(\.name)]) // Can send in a html template with bold etc.
localizeWithContext(.helloWorld) // Using the `Context` struct a long as it conforms to `Encodable`

There is also a new feature to format dates. You can formate the date with DateFormatter.Style for a more general purpose, with dateFormat: String, or send your own formatter, if this is needed.
The locale will automatically be sett if used inside a LocalizedTemplate. And therefore format the date in the most natural form.

The runtimeIf(...) is now renderIf(...).

Localisation example:

struct LocalizedView: LocalizedTemplate {

    static let localePath: KeyPath<LocalizedView.Context, String>? = \.locale

    enum LocalizationKeys: String {
        case helloWorld = "hello.world"
        case unreadMessages = "unread.messages"
    }

    /// The content needed to render LocalizationKeys.unreadMessages
    struct UnreadMessageContext: Codable {
        let number: Int
    }

    struct Context: Codable {
        let locale: String
        let description: UnreadMessageContext
        let number: Int
        let date: Date = Date()
    }

    func build() -> CompiledTemplate {
        return div.child(
            h1.child(
                localize(.helloWorld),
                small.child(
                    date(\.date, dateStyle: .medium, timeStyle: .medium)
                )
            ),
            p.child(
                localize(.unreadMessages, with: \.description)
            ),
            p.child(
                localizeWithContext(.unreadMessages)
            )
        )
    }
}

This could lead to

<!-- locale = "en", number = 1  -->
<div>
    <h1>Hello World!
        <small>May 6, 2019 at 10:24:50 AM</small>
    </h1>
    <p>You have an unread message</p>
    <p>You have an unread message</p>
</div>

<!-- locale "nb", number = 2 -->
<div>
    <h1>Hei Verden!
        <small>6. mai 2019, 10:24:50</small>
    </h1>
    <p>Du har 2 uleste meldinger.</p>
    <p>Du har 2 uleste meldinger.</p>
</div>

Markdown, Localization and concatenation

16 Apr 10:58
Compare
Choose a tag to compare
  • Markdown is finally supported by using the markdown("# Title") function. (Using SwiftMarkdown)
  • Localization is also supported by using the localize("hello.world", in: \.local) function
    The Lingo framework is used to handle localization logic.
  • It is now possible to use + to concatenate different elements Eg:
div.child(
    "Hello, " + variable(\.name) + p.child("View More")
)

Better if-statements on html nodes

27 Mar 19:24
Compare
Choose a tag to compare

Added:

  • .if(isNil: ..., add: ...)
  • .if(isNotNil: ..., add: ...)

e.g: div.if(isNil: \.someValue, add: .class("bg-danger"))

And a little more documentation

1.1.1

11 Mar 14:02
Compare
Choose a tag to compare

Made the Request extension public, as this was left as internal by a mistake

1.1.0

11 Mar 13:44
Compare
Choose a tag to compare

Added

  • A Vapor HTMLKitProvider and an extension on Request for simpler usage.
  • All the nodes are dynamic by default, and therefore removed dynamic(...).
  • Added the possibility to reference context variables outside the specified context with unsafeVariable(...). Example to retrieve a value in a superview.
  • Changed forEachInContext(render: ...) to forEach(render: ...).
  • More flexible conditions when using && and ||.
  • Made TemplateBuilder internal as the developer should use StaticView or ContextualTemplate.
  • render(...) now returns a HTTPResponse and the old render function is therefore called renderRaw(...).