From f90597fba1ce90450369f7ce4c834ace284c5676 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Thu, 1 Dec 2016 01:30:33 +0000 Subject: [PATCH] refactor: Revamp docs to separate template writers/devs --- README.md | 20 +++--- docs/api.rst | 140 +++++++++++++++++++++++++++++++++++++++ docs/api/context.rst | 45 ------------- docs/api/environment.rst | 43 ------------ docs/api/loader.rst | 38 ----------- docs/getting-started.rst | 37 +++++++++++ docs/index.rst | 32 ++++++--- docs/installation.rst | 29 ++++++++ docs/templates.rst | 4 +- 9 files changed, 240 insertions(+), 148 deletions(-) create mode 100644 docs/api.rst delete mode 100644 docs/api/context.rst delete mode 100644 docs/api/environment.rst delete mode 100644 docs/api/loader.rst create mode 100644 docs/getting-started.rst create mode 100644 docs/installation.rst diff --git a/README.md b/README.md index 9426a7a..d03c3b4 100644 --- a/README.md +++ b/README.md @@ -39,16 +39,6 @@ let rendered = try environment.renderTemplate(name: context) print(rendered) ``` -## Installation - -Installation with Swift Package Manager is recommended. - -### CocoaPods - -```ruby -pod 'Stencil' -``` - ## Philosophy Stencil follows the same philosophy of Django: @@ -61,8 +51,16 @@ Stencil follows the same philosophy of Django: ## The User Guide -- [Templates](http://stencil.fuller.li/en/latest/templates.html) +Resources for Stencil template authors to write Stencil templates: + +- [Language overview](http://stencil.fuller.li/en/latest/templates.html) - [Built-in template tags and filters](http://stencil.fuller.li/en/latest/builtins.html) + +Resources to help you integrate Stencil into a Swift project: + +- [Installation](http://stencil.fuller.li/en/latest/installation.html) +- [Getting Started](http://stencil.fuller.li/en/latest/getting-started.html) +- [API Reference](http://stencil.fuller.li/en/latest/api.html) - [Custom Template Tags and Filters](http://stencil.fuller.li/en/latest/custom-template-tags-and-filters.html) ## License diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..0afb6a7 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,140 @@ +Template API +============ + +This document describes Stencils Swift API, and not the Swift template language. + +.. contents:: :depth: 2 + +Environment +----------- + +An environment contains shared configuration such as custom filters and tags +along with template loaders. + +.. code-block:: swift + + let environment = Environment() + +You can optionally provide a loader or namespace when creating an environment: + +.. code-block:: swift + + let environment = Environment(loader: ..., namespace: ...) + +Rendering a Template +~~~~~~~~~~~~~~~~~~~~ + +Environment provides convinience methods to render a template either from a +string or a template loader. + +.. code-block:: swift + + let template = "Hello {{ name }}" + let context = ["name": "Kyle"] + let rendered = environment.renderTemplate(string: template, context: context) + +Rendering a template from the configured loader: + +.. code-block:: swift + + let context = ["name": "Kyle"] + let rendered = environment.renderTemplate(name: "example.html", context: context) + +Loading a Template +~~~~~~~~~~~~~~~~~~ + +Environment provides an API to load a template from the configured loader. + +.. code-block:: swift + + let template = try environment.loadTemplate(name: "example.html") + +Loader +------ + +Loaders are responsible for loading templates from a resource such as the file +system. + +Stencil provides a ``FileSytemLoader`` which allows you to load a template +directly from the file system. + +FileSystemLoader +~~~~~~~~~~~~~~~~ + +Loads templates from the file system. This loader can find templates in folders +on the file system. + +.. code-block:: swift + + FileSystemLoader(paths: ["./templates"]) + +.. code-block:: swift + + FileSystemLoader(bundle: [Bundle.main]) + + +Custom Loaders +~~~~~~~~~~~~~~ + +``Loader`` is a protocol, so you can implement your own compatible loaders. You +will need to implement a ``loadTemplate`` method to load the template, +throwing a ``TemplateDoesNotExist`` when the template is not found. + +.. code-block:: swift + + class ExampleMemoryLoader: Loader { + func loadTemplate(name: String, environment: Environment) throws -> Template { + if name == "index.html" { + return Template(templateString: "Hello", environment: environment) + } + + throw TemplateDoesNotExist(name: name, loader: self) + } + } + + +Context +------- + +A ``Context`` is a structure containing any templates you would like to use in +a template. It’s somewhat like a dictionary, however you can push and pop to +scope variables. So that means that when iterating over a for loop, you can +push a new scope into the context to store any variables local to the scope. + +You would normally only access the ``Context`` within a custom template tag or +filter. + +Subscripting +~~~~~~~~~~~~ + +You can use subscripting to get and set values from the context. + +.. code-block:: swift + + context["key"] = value + let value = context["key"] + +``push()`` +~~~~~~~~~~ + +A ``Context`` is a stack. You can push a new level onto the ``Context`` so that +modifications can easily be poped off. This is useful for isolating mutations +into scope of a template tag. Such as ``{% if %}`` and ``{% for %}`` tags. + +.. code-block:: swift + + context.push(["name": "example"]) { + // context contains name which is `example`. + } + + // name is popped off the context after the duration of the closure. + +``flatten()`` +~~~~~~~~~~~~~ + +Using ``flatten()`` method you can get whole ``Context`` stack as one +dictionary including all variables. + +.. code-block:: swift + + let dictionary = context.flatten() diff --git a/docs/api/context.rst b/docs/api/context.rst deleted file mode 100644 index 85d9a06..0000000 --- a/docs/api/context.rst +++ /dev/null @@ -1,45 +0,0 @@ -Context -======= - -A Context is a structure containing any templates you would like to use in a -template. It’s somewhat like a dictionary, however you can push and pop to -scope variables. So that means that when iterating over a for loop, you can -push a new scope into the context to store any variables local to the scope. - -API ----- - -Subscripting -~~~~~~~~~~~~ - -You can use subscripting to get and set values from the context. - -.. code-block:: swift - - context["key"] = value - let value = context["key"] - -``push()`` -~~~~~~~~~~ - -A ``Context`` is a stack. You can push a new level onto the ``Context`` so that -modifications can easily be poped off. This is useful for isolating mutations -into scope of a template tag. Such as ``{% if %}`` and ``{% for %}`` tags. - -.. code-block:: swift - - context.push(["name": "example"]) { - // context contains name which is `example`. - } - - // name is popped off the context after the duration of the closure. - -``flatten()`` -~~~~~~~~~~~~~ - -Using ``flatten()`` method you can get whole ``Context`` stack as one -dictionary including all variables. - -.. code-block:: swift - - let dictionary = context.flatten() diff --git a/docs/api/environment.rst b/docs/api/environment.rst deleted file mode 100644 index 190e3fe..0000000 --- a/docs/api/environment.rst +++ /dev/null @@ -1,43 +0,0 @@ -Environment -=========== - -An environment contains shared configuration such as custom filters and tags -along with template loaders. - -.. code-block:: swift - - let environment = Environment() - -You can optionally provide a loader or namespace when creating an environment: - -.. code-block:: swift - - let environment = Environment(loader: ..., namespace: ...) - -Rendering a Template --------------------- - -Environment providences coninience methods to render a template either from a -string or a template loader. - -.. code-block:: swift - - let template = "Hello {{ name }}" - let context = ["name": "Kyle"] - let rendered = environment.render(templateString: template, context: context) - -Rendering a template from the configured loader: - -.. code-block:: swift - - let context = ["name": "Kyle"] - let rendered = environment.render(templateName: "example.html", context: context) - -Loading a Template ------------------- - -Environment provides an API to load a template from the configured loader. - -.. code-block:: swift - - let template = try environment.loadTemplate(name: "example.html") diff --git a/docs/api/loader.rst b/docs/api/loader.rst deleted file mode 100644 index 945372b..0000000 --- a/docs/api/loader.rst +++ /dev/null @@ -1,38 +0,0 @@ -Loader -====== - -Loaders are responsible for loading templates from a resource such as the file -system. - -Stencil provides a ``FileSytemLoader`` which allows you to load a template -directly from the file system. - -``Loader`` is a protocol, so you can implement your own compatible loaders. You -will need to implement a ``loadTemplate`` method to load the template, -throwing a ``TemplateDoesNotExist`` when the template is not found. - -.. code-block:: swift - - class ExampleMemoryLoader: Loader { - func loadTemplate(name: String, environment: Environment) throws -> Template { - if name == "index.html" { - return Template(templateString: "Hello", environment: environment) - } - - throw TemplateDoesNotExist() - } - } - -FileSystemLoader ----------------- - -Loads templates from the file system. This loader can find templates in folders -on the file system. - -.. code-block:: swift - - FileSystemLoader(paths: ["./templates"]) - -.. code-block:: swift - - FileSystemLoader(bundle: [Bundle.main]) diff --git a/docs/getting-started.rst b/docs/getting-started.rst new file mode 100644 index 0000000..f4965f7 --- /dev/null +++ b/docs/getting-started.rst @@ -0,0 +1,37 @@ +Getting Started +=============== + +The easiest way to render a template using Stencil is to create a template and +call render on it providing a context. + +.. code-block:: swift + + let template = Template(templateString: "Hello {{ name }}") + try template.render(["name": "kyle"]) + +For more advanced uses, you would normally create an ``Environment`` and call +the ``renderTemplate`` convinience method. + +.. code-block:: swift + + let environment = Environment() + + let context = ["name": "kyle"] + try template.renderTemplate(string: "Hello {{ name }}", context: context) + +Template Loaders +---------------- + +A template loader allows you to load files from disk or elsewhere. Using a +``FileSystemLoader`` we can easily render a template from disk. + +For example, to render a template called ``index.html`` inside the +``templates/`` directory we can use the following: + +.. code-block:: swift + + let fsLoader = FileSystemLoader(paths: ["templates/"]) + let environment = Environment(loader: fsLoader) + + let context = ["name": "kyle"] + try template.renderTemplate(name: "index.html", context: context) diff --git a/docs/index.rst b/docs/index.rst index 4afac4c..9d1987e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,20 +31,34 @@ feel right at home with Stencil. ] ] - do { - let template = try Template(named: "template.html") - let rendered = try template.render(context) - print(rendered) - } catch { - print("Failed to render template \(error)") - } + let environment = Environment(loader: FileSystemLoader(paths: ["templates/"]) + let rendered = try environment.renderTemplate(name: context) -Contents: + print(rendered) + +The User Guide +-------------- + +For Template Writers +~~~~~~~~~~~~~~~~~~~~ + +Resources for Stencil template authors to write Stencil templates. .. toctree:: :maxdepth: 2 templates builtins - api/context + +For Developers +~~~~~~~~~~~~~~ + +Resources to help you integrate Stencil into a Swift project. + +.. toctree:: + :maxdepth: 1 + + installation + getting-started + api custom-template-tags-and-filters diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..204d2b1 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,29 @@ +Installation +============ + +Swift Package Mangaer +--------------------- + +If you're using the Swift Package Manager, you can add ``Stencil`` to your +dependencies inside ``Package.swift``. + +.. code-block:: swift + + import PackageDescription + + let package = Package( + name: "MyApplication", + dependencies: [ + .Package(url: "https://github.com/kylef/Stencil.git", majorVersion: 0, minor: 7), + ] + ) + +CocoaPods +--------- + +If you're using CocoaPods, you can add Stencil to your ``Podfile`` and then run +``pod install``. + +.. code-block:: ruby + + pod 'Stencil' diff --git a/docs/templates.rst b/docs/templates.rst index 6db5e4b..4aafa4c 100644 --- a/docs/templates.rst +++ b/docs/templates.rst @@ -1,5 +1,5 @@ -Templates -========= +Language overview +================== - ``{{ ... }}`` for variables to print to the template output - ``{% ... %}`` for tags