Skip to content

Commit

Permalink
Minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
MatsMoll committed Dec 27, 2019
1 parent aa81be2 commit 7cf9c32
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 121 deletions.
80 changes: 40 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

# HTMLKit

Render **lightning fast** HTML templates in a *typesafe* way!
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
```swift
.package(url: "https://github.com/vapor-community/HTMLKit.git", from: "2.0.0-alpha.1"),
.package(url: "https://github.com/vapor-community/HTMLKit.git", from: "2.0.0-alpha.9"),
```
And register the provider and the different templates with in `configure.swift`
```swift
Expand All @@ -25,41 +25,66 @@ services.register(renderer)

## Usage

To create a HTML component, conform to the `HTMLComponent` protocol. Look at the example above for an Alert component.
To create a HTML template, conform to the `HTMLTemplate` protocol.

```swift
public struct Alert: HTMLComponent {
struct SimpleTemplate: HTMLTemplate {

let message: HTML
let isDisimissable: Conditionable
@TemplateValue(String?.self)
var context

public init(isDisimissable: Conditionable = true, @HTMLBuilder message: () -> HTML) {
self.isDisimissable = isDisimissable
self.message = message()
var body: HTML {
Document(type: .html5) {
Head {
Title { context }
}
Body {
Unwrap(context) { string in
P { string }
}
}
}
}
}

...
try SimpleTemplate().render(with: "Some string", for: req)
```

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

```swift
public struct Alert: HTMLComponent {

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

public var body: HTML {
Div {
message

IF(isDisimissable) {
Button {
Span { "×" }
.aria(for: "hidden", value: true)
}
.type(.button)
.class("close")
.data(for: "dismiss", value: "alert")
.aria(for: "label", value: "Close")
.data("dismiss", value: "alert")
.aria("label", value: "Close")
}
}
.class("alert alert-danger bg-danger" + IF(isDisimissable) { " fade show" })
.class("alert alert-danger bg-danger")
.modify(if: isDisimissable) {
$0.class("fade show")
}
.role("alert")
}
}
```
This can easily be used in another template or a static html page like:
This can then be used in another template or a static html page like:
```swift
struct SomePage: StaticView {
struct SomePage: HTMLPage {

var body: HTML {
Div {
Expand All @@ -71,31 +96,6 @@ struct SomePage: StaticView {
}
```

If you need a page that changes based on runtime given values. Then a `TemplateView` could be more appropriate. Here you will need to pass the context when rendering.

```swift

struct DummyPage: TemplateView {

struct Context {
let string: String
let int: Int?
}

var body: HTML {
Div {
P { context.string }
IF(context.int.isDefined) {
Small { context.int }
}
}
}
}
...
let context = DummyPage.Context(string: "Some string", int: nil)
try DummyPage().render(with: context, for: req)
```

## Mixing HTMLKit with Leaf

You can easily mix Leaf and HTMLKit in the same project.
Expand Down Expand Up @@ -136,7 +136,7 @@ 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 presentet to the user.
```swift
struct LocalizedDateView: TemplateView {
struct LocalizedDateView: HTMLTemplate {

struct Context {
let date: Date
Expand Down
12 changes: 12 additions & 0 deletions Sources/HTMLKit/AttributeNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public protocol GlobalAttributes {

func aria(for key: String, value: HTML) -> Self

func data(_ key: String, value: HTML) -> Self

func aria(_ key: String, value: HTML) -> Self

func style(css: HTML) -> Self

/// The contenteditable attribute specifies whether the content of an element is editable or not.
Expand Down Expand Up @@ -100,6 +104,10 @@ extension GlobalAttributes where Self: AttributeNode {
add(HTMLAttribute(attribute: "aria-" + key, value: value))
}

public func aria(_ key: String, value: HTML) -> Self {
self.aria(for: key, value: value)
}

public func accessKey(_ value: HTML) -> Self {
add(HTMLAttribute(attribute: "accessKey", value: value))
}
Expand All @@ -112,6 +120,10 @@ extension GlobalAttributes where Self: AttributeNode {
add(HTMLAttribute(attribute: "data-" + key, value: value))
}

public func data(_ key: String, value: HTML) -> Self {
self.data(for: key, value: value)
}

public func isEditable(_ value: Conditionable) -> Self {
add(HTMLAttribute(attribute: "contenteditable", value: value))
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/HTMLKit/ForEach.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ extension TemplateValue where Value: Sequence {
}

extension Sequence {
public func forEachHTML(@HTMLBuilder content: (RootValue<Element>) -> HTML) -> HTML {
public func htmlForEach(@HTMLBuilder content: (RootValue<Element>) -> HTML) -> HTML {
ForEach(in: .constant(self), content: content)
}
}
46 changes: 0 additions & 46 deletions Sources/HTMLKit/Markdown.swift

This file was deleted.

19 changes: 0 additions & 19 deletions Sources/HTMLKit/TemplateVariable.swift

This file was deleted.

6 changes: 3 additions & 3 deletions Tests/HTMLKitTests/HTMLKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ final class HTMLKitTests: XCTestCase {
let chaindDataRender = try renderer.render(raw: ChainedEqualAttributesDataNode.self)
//// let inputRender = try renderer.render(FormInput.self)

XCTAssertEqual(multipleEmbedRender, "<html><head><title>Welcome</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><span>Some text</span><div><p>String</p><p>String</p></div><div><p>String</p><p>Welcome</p></div></body></html>")
XCTAssertEqual(multipleEmbedRender, "<!DOCTYPE html><html><head><title>Welcome</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><span>Some text</span><div><p>String</p><p>String</p></div><div><p>String</p><p>Welcome</p></div></body></html>")
// XCTAssertEqual(varialbeRender, "<div><p>&lt;script&gt;&quot;&#39;&amp;&lt;/script&gt;</p><p><script>\"'&</script></p></div>")
XCTAssertEqual(staticEmbedRender, "<div><div><p>Text</p></div><p>Hello</p><small>2</small></div>")
XCTAssertEqual(someViewRender, "<html><head><title>Welcome</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><p>Hello Mats!</p></body></html>")
XCTAssertEqual(someViewRenderTitle, "<html><head><title>Test</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><p>Hello Mats!</p></body></html>")
XCTAssertEqual(someViewRender, "<!DOCTYPE html><html><head><title>Welcome</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><p>Hello Mats!</p></body></html>")
XCTAssertEqual(someViewRenderTitle, "<!DOCTYPE html><html><head><title>Test</title><link href='some url' rel='stylesheet'><meta name='viewport' content='width=device-width, initial-scale=1.0'></head><body><p>Hello Mats!</p></body></html>")
XCTAssertEqual(forEachRender, "<div id='array'><p>1</p><p>2</p><p>3</p></div>")
XCTAssertEqual(firstIfRender, "<div>I am a child</div>")
XCTAssertEqual(secondIfRender, "<div><p dir='ltr'>My name is: Mats!</p>I am growing<p>Simple bool</p></div>")
Expand Down
43 changes: 31 additions & 12 deletions Tests/HTMLKitTests/HTMLTestDocuments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ struct StaticEmbedView: HTMLTemplate {
}
}

struct SimplePage: HTMLTemplate {

@TemplateValue(String.self)
var context

var body: HTML {
Document(type: .html5) {
Head {
Title { context }
}
Body {
P { context }
}
}
}
}

struct BaseView<Root>: HTMLComponent {

let context: TemplateValue<Root, String>
Expand All @@ -55,18 +72,20 @@ struct BaseView<Root>: HTMLComponent {
}

var body: HTML {
HTMLNode {
Head {
Title { context }
Link()
.href("some url")
.relationship(.stylesheet)
Meta()
.name(.viewport)
.content("width=device-width, initial-scale=1.0")
}
Body {
content
Document(type: .html5) {
HTMLNode {
Head {
Title { context }
Link()
.href("some url")
.relationship(.stylesheet)
Meta()
.name(.viewport)
.content("width=device-width, initial-scale=1.0")
}
Body {
content
}
}
}
}
Expand Down

0 comments on commit 7cf9c32

Please sign in to comment.