قالب وردپرس درنا توس
Home / IOS Development / Templating steam applications with blades

Templating steam applications with blades



Creating APIs in Steam and building an iOS app as a front end can be something you are quite familiar with, but you can create almost any type of client to consume the API & # 39; your.

In this tutorial you will create a website-based client against your Vapor API, and along the way you will learn how to use Leaf to create dynamic websites in Steam applications.

You use a Vapor app called TO (Today I learned) that hosts acronyms specified by users.

Note : This tutorial assumes that you have experience using Vapor to build web apps. See Getting Started with Server Page Swift with Steam if you are new to Steam. You must at least use the steps in this guide to install the Steam Toolbox to follow this tutorial. You will also need some knowledge of Docker (and have it installed), which you can learn more about in this tutorial.

What is Leaf?

Leaf is Vapor's templating language . A templating language allows you to transfer information to a page so that it can generate the final HTML without knowing everything at the front.

For example, in the TIL program, you do not know all the acronyms that users will create when you distribute your application. Templering lets you handle this easily.

Templating languages ​​also let you reduce duplication in your web pages. Instead of multiple pages for acronyms, you create a single template and specify the properties specific to displaying a particular acronym. If you decide to change the way you view an acronym, just change the code in one place and all the acronym pages will display the new format.

Finally, templates can add you to templates in other templates. For example, if you have navigation on your site, you can create a single template that generates the code for your navigation. You enter the navigation template in all templates that need navigation rather than duplication code.

Getting Started

Download the start project for this tutorial using the "Download Materials" button at the top or bottom of this page.

To use Leaf, you must add the project as an addiction. Use the startup project from this tutorial, open Package.swift . Replace the content with the following:

  // swift-tools version: 4.0
import package description

let package = package (
name: "APP",
dependencies: [
    .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
    .package(url: "https://github.com/vapor/fluent-postgresql.git", from: "1
.0.0"), .package(url: "https://github.com/vapor/leaf.git", from: "3.0.0") ], Goals: [ .target(name: "App", dependencies: ["FluentPostgreSQL", "Vapor", "Leaf"]), .target (name: "Run", dependencies: ["App"]), .testTarget (name: "AppTests", dependencies: ["App"]), ] )

The changes that were made were:

  • Make the package TILApp depending on the Leaf package.
  • Make the [App] target depending on the [Leaf goal to ensure that it is properly connected.

By default, Leaf expects templates to be in the catalog Resources / Views . In Terminal enter the following to create these directories:

  mkdir -p Resources / Impressions

Finally, you need to create new routes for your site. Create a new controller to contain these routes. Enter the following in the terminal:

  touch Sources / App / Controllers / WebsiteController.swift

With everything configured, the Xcode project regenerates to start using Leaf. Enter the following in the terminal:

  steam xcode -y

Restore a page

Open WebsiteController.swift and create a new type to keep all web page routes and a route that returns an index template:

  Import Steam
import sheet

// 1
struct WebsiteController: RouteCollection {
// 2
func boot (router: router) throws {
// 3
router.get (use: indexHandler)
}

// 4
func indexHandler (_ req: Request) cast -> Future  {
// 5
return sample req.view (). render ("index")
}
}

Here's what this does:

  1. Declare a new WebsiteController type that matches RouteCollection .
  2. Implement boot (router :) required by RouteCollection .
  3. IndexHandler (_ 🙂 to process GET requests to the routers rotation path, i.e., a request to / .
  4. Implement indexHandler (_ :) returning Future .
  5. Render index template and return the result. You learn about req.view () in an instant.

Leaf generates a page from a template named index.leaf in the catalog Resources / Views .

Note that the file type is not required by the rendering. Create this file and insert the following:


  # // 1


  
    # // 2
 Hello World 


    # // 3

Hei Verden

Here's what this file does:

  1. Declare a basic HTML 5 page with a and .
  2. Set the page title Hello World – this is the title that appears in a browser tab.
  3. Put your body to be a single

    title that says Hello World .

Note : You can create your . sheet files by which text editor you choose, including Xcode. If you are using Xcode, select Editor ▸ Syntax Coloring ▸ HTML for proper highlighting of items and indentation support.

You must register your new WebsiteController . Open routes.swift and add the following to the end of routes (_ :) :

  let websiteController = WebsiteController ()
try router.register (collection: websiteController)

Then, register the Leaf service. Open configure.swift and add the following to the import section below import Vapor :

  Import Leaf

Next, after try services.register (FluentPostgreSQLProvider ()) add the following:

  try services.register (LeafProvider ())

Using generic req.view () to achieve a rendering, you can easily switch to different templating engines. While this may not be helpful when running the program, it is extremely useful for testing. For example, you can use a test object to produce plain text to verify against, instead of analyzing HTML output in your test fields.

req.view () asks Damp to provide a type corresponding to ViewRenderer . TemplateKit – the module on which Leaf is based – provides PlaintextRenderer and Leaf provides LeafRenderer . In configure.swift add the following to the end of configure (_: _: _ :) :

  config.prefer (LeafRenderer.self, for: ViewRenderer.self)

This tells Damp to use LeafRenderer when prompted for a ViewRenderer type.

Before running the app, you must have PostgreSQL on the system. You run the Postgres server in a Docker container. Open `Terminal` and enter the following command:

  docker run - name postgres -e POSTGRES_DB = steam
-e POSTGRES_USER = vapor -e POSTGRES_PASSWORD = password
-p 5432: 5432 -d postgres

To verify that your database is running, enter the following in Terminal to list all active containers:

  docker ps

Now the program builds and runs in Xcode, remember to select the Run scheme, and then open your browser. Enter the URL http: // localhost: 8080 and you will receive the page generated from the template:

 Running the app

Injection variables

The template is currently only a static side and not at all impressive! Make the page more dynamic, open index.leaf and change the line </code> to the following: </p> <pre lang="html"> <title> # (title) | Acronyms

This extracts a parameter called title using the leaf function # () .

At the bottom of WebsiteController.swift add the following to create a new type containing the title:

  struct IndexContext: Encodable {
Leave the title: String
}

When data only flows to Leaf, you just have to abide by Encodable . IndexContext is the data for your display, similar to a display model in the MVVM pattern. Then change indexHandler (_ :) to send a IndexContext to the template. Replace the implementation with the following:

  func indexHandler (_ req: Request) cast -> Future  {
// 1
la context = IndexContext (title: "Website")
// 2
return sample req.view (). render ("index", context)
}

Here's what the new code does:

  1. Create a IndexContext containing the desired title.
  2. Pass the context to Leaf as the second parameter to render (_: _ :) .

Build and run, then update the page in your browser. You will see the updated title:

 Updated Title

Using Tags

The home page of the TIL site should list all acronyms. Continue in WebsiteController.swift add a new property to IndexContext under title :

  la acronyms: ?

This is an optional selection of acronyms; Change indexHandler (_ :) to get all the acronyms and insert them into . nil since there are no acronyms in the database. IndexContext .

Replace the implementation again with the following:

  func indexHandler (_ req: Request) cast -> Future  {
// 1
return Akronym.query (on: req) .all (). flat folder (for: View.self) {acronyms i
// 2
la acronymerData = acronym.Ompty? zero: acronyms
la context = IndexContext (title: "Website", acronyms: acronymsData)
return sample req.view (). render ("index", context)
}
}

Here's what this does:

  1. Use a floating query to get all the acronyms from the database. You can learn more about Floating in this tutorial.
  2. Add acronyms to IndexContext if any exist, otherwise set the variable to null . Sheets can look for zero in the template.

Finally open index.leaf and change the parts between tags to the following:

  # // 1

acronym

# // 2 #if (acronyms) { # // 3 # // 4 #for (acronym in acronyms) { # // 5 }
Short Long
# (acronym.short) # (acronym.long)
# // 6 } other {

There are no acronyms yet!

}

Here's what the new code does:

  1. Declare a new heading, "Acronyms".
  2. Use Leaf's #if () tag to see if the variable acronyms is set. #if () can validate variables for nullability, work on boolean or even evaluate expressions.
  3. If acronyms is set, create an HTML table. The table has a header row -

    - with two columns, Cards and Lang .
  4. Use Leaf's #for () tag to run through all acronyms. This works the same as Swift's loop.
  5. Create a row for each acronym. Use Leaf's # () function to extract the variable. Since everything is Encodable you can use point notation to access acronym properties, just like Swift!
  6. If there are no acronyms, print a suitable message.

Build and run, then update the page in your browser.

If you do not have any acronyms in the database, you will see the correct message:

 App without acronyms

] If there are acronyms in the database, you see them in the table: [19659002]  App Medacronyms

To test the page with acronyms you can use RESTed macOS app to add acronyms to the database, as described in our fluid training.

First, add a user to the database by sending a POST request to http: // localhost: 8080 / api / users in RESTed as follows:

 Add a user

Then enter id by the new user and add it (as parameter userID ) into another POST request to http: // localhost: 8080 / api / acronyms configured as follows:

 Add an acronym

Once you have submitted the request to add a New Acronym, you can update the page your in the browser to see the acronyms drawn from the database.

 Acronym added

Acronym Detail Page

Now you need a page to view the details of each acronym. At the end of WebsiteController.swift create a new type to keep the context for this page:

  struct AcronymContext: Encodable {
Leave the title: String
la acronym: Acronym
let the user: User
}

This AcronymContext contains a title for the page, the acronym itself and the user who created the acronym. Create the following acronym detail route page page under indexHandler (_ :) :

  // 1
func acronymHandler (_ req: Request) cast -> Future  {
// 2
return try req.parameters.next (Acronym.self) .flatMap (to: View.self) {acronym in
// 3
return acronym.user.get (on: req) .flatMap (to: View.self) {use in
// 4
leave context = AcronymContext (title: acronym.short, acronym: acronym,
user: user)
return sample req.view (). render ("acronym", context)
}
}
}

Here's what this route manager does:

  1. Declare a new route manager, acronymHandler (_ :) that returns Future .
  2. Extract the acronym from the request parameters and extract the result.
  3. Get the user acronym and unpack the result.
  4. Create a AcronymContext that contains the correct details and makes the page using the [acronymleaf template).

Finally, register the route at the bottom of boot (router :) :

  router.get ("acronyms", acronym.parameter, use: acronymHandler)
This records the route of  acronymHandler  for  / acronym / ACRONYM ID>  similar to API. Create the  acronym.leaf  template inside the directory  Resources / Views  and open the new file and add the following: 


  # // 1


  
    # // 2
 # (title) | Acronyms 


    # // 3

# (acronym.short)

# // 4

# (acronym.long)

# // 5

Created by # (username)

Here's what this template does:

  1. Declare an HTML5 page as index.leaf .
  2. Set the title to the value submitted.
  3. Print the acronym brief property in a

    heading.

  4. Print the long property of the acronym in a

    heading.

  5. Print the acronym user in a

    block

Finally, change index.leaf so you can navigate to the page. Replace the first column in the table for each acronym (

# (acronym.short)

) with:

    # (acronym.short)  

This breaks into the acronym short property in an HTML tag, which is a link. The link specifies the URL of each acronym to the route registered above. Build and run, then update the page in your browser:

 Acronyms with links

You will see that each acronym's short form is now a link. Click on the link and the browser navigates to the acronym page:

 Acronym details page

Where to go from here?

This tutorial introduced Leaf and showed you how to start building a dynamic website to consume your steam API.

If you liked this tutorial, why not check out our full length book on Steam Development: Server-Side Swift with Steam?

If you are a beginner for web development but have been working with Swift for a while, you will find it easy to create robust, full-featured web applications and web APIs with Vapor 3.

Whether you're looking to make a backend for your The iOS app or will make Vapor is the perfect platform for you.

Questions or comments on this tutorial? Leave them in the comments below!


Source link