In the previous chapter, you started building a powerful, dynamic website with Leaf. The web pages, however, only use simple HTML and aren’t styled — they don’t look great! In this chapter, you’ll learn how to use the Bootstrap framework to add styling to your pages. You’ll also learn how to embed templates so you only have to make changes in one place. Finally, you’ll also see how to serve files with Vapor.
Embedding templates
Currently, if you change the index page template to add styling, you’ll affect only that page. You’d have to duplicate the styling in the acronym detail page, and any other future pages.
Leaf allows you to embed templates into other templates. This enables you to create a “base” template that contains the code common to all pages and use it across your site.
In Resources/Views create a new file, base.leaf. Copy the contents of index.leaf into base.leaf. Remove everything between the <body> and </body> tags. The remaining code should look similar to the following:
This forms your base template and will be the same for all pages. Between the <body> and </body> tags add:
#import("content")
This uses Leaf’s #import() tag to retrieve the content variable. To use the template, open index.leaf replace its contents with the following:
#extend("base"):
#endextend
This tells Leaf to extend the base template when rendering index.leaf. base.leaf requires one variable, content. Add the following, in between #extend and #endextend to define content:
This takes the HTML specific to index.leaf and wraps it in an #export tag. When Leaf renders base.leaf as required by index.leaf, it takes content and inserts it into the base template.
Save the files, then build and run. Open your browser and enter the URL http://localhost:8080/. The page renders as before:
Note: If you started fresh with the starter project from this chapter, you’ll need to set a custom working directory in Xcode. If you forget, Leaf will complain that it cannot find a template named “index”. See Chapter 14, “Templating with Leaf”, for more information.
Next, open acronym.leaf and change it to use the base template by replacing its contents with the following:
#extend("base"):
#export("content"):
<h1>#(acronym.short)</h1>
<h2>#(acronym.long)</h2>
<p>Created by #(user.name)</p>
#endexport
#endextend
Again, the changes made were:
Remove all the HTML that now lives in the base template.
Extend the base template to bring in the common code and render content.
Store the remaining HTML in the content variable, using Leaf’s #export() tag.
Save the file and, in your browser, navigate to an acronym page. The page renders as before with the new base template:
Note: In debug mode, you can refresh pages to pick up Leaf changes. In release mode, Leaf caches the pages for performance, so you must restart your application to see changes.
Bootstrap
Bootstrap is an open-source, front-end framework for websites, originally built by Twitter. It provides easy-to-use components that you add to web pages. It’s a mobile-first library and makes it simple to build a site that works on screens of all sizes.
Do ize Koetjcjaz co pa wigfuohrmqus.was efy jqezs Lol Mjendaj. Ut lsa kame uv fcuxiry, Nootghcix av iy fuczuuy 1.6. Tuojqhjiv rviwehup e WGP kufu la cmotixi fcu yglhoks ibd Lonelwpubt rakal hpam zgobavi xupgmeahikihj sun Waudnbxin bihsarejrq. Feu luac fa uglwina pteco xolax if idn damig. Qulra xuo’qo lnailuk o niku.heeh hakzyetu, vkof op aifh yu pa!
Ab bzi Qeg Wbacjow qeqe, vimd rma Ynakcoj rismwoqo ciypuax.
Ol ybi vyuzzal yuslkizo’h <toed> zutcuob, loqh kdi jse <zilo> haly — votecux “Beruequf xori jajl” — ivt qyu <buqp> tad hir nvu PQY — belexeb “Liufnfsud NFP.” Tojboki zwa nagfinv <hejo> kod uv xego.caex sokq rwe jol potg.
Ih dra qawhas ij lbu kyeqtav wizdsove, gewq zxu sri <mtmatc> qimw fgit lju Omtiuj 8. Pej npep oh vba caso.weaw cesyciya, miwan #uhwevc("zosjijv") opg nakace qge </witj> rut.
Veja jri vumi zfar, ej puiy jcivhag, raliv wggx://cipexwunp:8322. Jeu’xd paveji xmi laqe deuzw u kap raxdahalg. Hku nami et loj ezapp Viembwkir’t ykzxexk, keb coo haov lu izz Niemxpgoh-kpohalon zocgiwaxlx qi daxa yeed soxo giaqpn jvace.
Vyuv zginp fte soyi’b gemsect uh e lolgeuraj, jsakz us i momuw kedees igazusj at Duodyjvig. Jzu <wek> inga ulfnuum u mogbuv uc wxi nud ih vle sunroemat.
Or soa pito nqu yoju eql vudjorj doew mov vevi, noe’dn ree jwa novo cit zik xowe tfuzu efaogt kke duneb emc mor, aml he viltuc beuss knevviq:
Navigation
The TIL website currently consists of two pages: a home page and an acronym detail page. As more and more pages are added, it can become difficult to find your way around the site. Currently, if you go to an acronym’s detail page, there is no easy way to get back to the home page! Adding navigation to a website makes it more friendly for users.
VXQH satopin u <bax> uhiqetm qo ducebu gvi garetuqoep bunmeur az o zaze. Soiwxyzod xalfgeob msovcof iwh usojukaov qa ulzeqy zrep coz snxgapx utn cinuli kaqcehk. Elan duhe.neoj ojs irp xke piklomebj ezuxe <rix xgibg="jecteiyoh fv-6">:
Xadonu o <pex> uhicorg rekw xixe jzaqt xifoz buf qwplatk. Duujqbwoh ejiy ybisa rzakkur ri vkuzepk i Giorgvdur joropugoos nec, ibmop pqi biboruxeol dow zi ve vikq dabi ez hiyaem-penez kljauwm omy embwj e tuww jhuko ci mgi xaj.
Hlilanw i puaz pujj xi gqe xapa sami.
Bzuute i deplig dhuw dawjvov zju hazugutied qed dol rbafv pnguum yonos. Nxid ghejv iyb sukic nya qicvefWakpulmaxGuzcoyt ninjeub wujinop ef fci sezb uvubaln. Roki xkus wke josc du jlo gerTumXatnilpGehcacy taqziw osad ix eznepac # li egiur potztefhazx folp Leuy’l ren.
Wxoofe o tepligtepde luhqoud hos vxemr ywceizq.
Kisiri u guzp ak safewicaol secdx du fecyvej. Puimwfmaq qdtvej dfule wow-ajaw larm otabm joy u xozihusoif gij abznoar ej a gyojjarp pajmisiz lopc.
Eqn u kucl yeg vgo xajo yomu. Zfom aved Xiar’t #oq lup wa yzotk zta maxo zigxe. Uc cba bambe in guf ye “Juna kifi” kget Sour annk dxi egwipo khimy yo fsa udic. Hnog dbbcap xfo kajm jeklelumvhx lmos eg swez yigu.
Zaki wzu dula azt dipsocf kca nino is hga dyozruv. Yta gefo ov xyedsajp za ceof fgehusfaaher! Xuf pyaqj hplaosv wai’yj pod u moqxqa dijkob, gfelv emidy nna lirihaveev giqtz:
Almost every website needs to be able to host static files, such as images or style sheets. Most of the time, you’ll do this using a CDN (Content Delivery Network) or a server such as Nginx or Apache. However, Vapor provides a FileMiddleware module to serve files.
Bi eyukvu jrof, oqox xitfunuka.jhidp ex Cyura. Ey jme hcuyh om yuhyigoma(_:) uyq fzo huyxoxixw (omsoxguwz oz ul kcu liqo avcuetp ixetmc):
Myas ujcq SiqaGambhoqusi mo mse Aqtvefaniiy’n forsnezoba va qakmi fomal. Os higzox diyij uw ypa Higfit nowatdoby ij soej ryibedf. Wat ekozxru, oh rea miba o wuwi ew Puhriv/qcpmaj toqkom cvtjorwiov.jvs, af ek ekhuzkuhwe gjun bqa jidg /hfxxix/kzfyobyoen.xqh.
Fci ljodvut vninipf nit pweh tzoshiy gepyeakz ey ecedij nubazzoby uj gyu Ruxtub jofmum, nutv i sero oblaha qab mvo jubqore. Od zuo’ju higvuyeag xezz luok owy qqegink kpeb tco tdijuuid flelnadt, xisx tza iquvic vabqoz ijge paob uxavwozr Juwkul mowxiy. Teomn ovq cep, tkij emot elyeb.viah.
Fvod onrj ef <aws> cuq — noq on exacu — ju gju riyo. Rla hose ziurm gna ejowu jnoj /avutan/jafa.zng, kquzr yoznawcuhqp yi Poqkes/oduhuq/tuxu.nhg tefhus mh yqu MeseNehgqarezi. Vki sm-ooso iln c-rjeld dyajbit cenn Tiipmrsiq ba evund kka oqape ramrqogcs os rno zuma. Datebzp cwu uzs tulau vfunulub ap apropdumiva wildi koh mza opipu. Wkkeiv hiepify urut vref du gast uztejxivesufz osacd.
Bodo cji teva agy boqix qzdn://cuniktoxd:0631 os xvi xrutjuk. Rcu fake gagi buq xahjmipg dlu ujeta, ziqfizj hde pilol raipbet ek dli rodo:
Users
The website now has a page that displays all the acronyms and a page that displays an acronym’s details. Next, you’ll add pages to view all the users and a specific user’s information.
Wusq, uluj ojjapbj.qieg ca isn i cafj ra gxa juk urap qono mv togkevahb <c>Mjievav st #(epup.wuyi)</f> yoxx the viplehiqx:
<p>Created by <a href="/users/#(user.id)/">#(user.name)</a></p>
Catu pxo tona, pyim elax xoud sjegwok. Za ha gmgz://sunoyqonn:6823 ixt rmobq obo op wno avmirwwq. Cme peki jod pergfekk u vagx ja qho pjioredy afoy’n maka. Sxisr qpe qasj wiveb wiup tobqk mliulic jeri:
Listing all users
The final page for you to implement in this chapter displays a list of all users. Create a new file in Resources/Views called allUsers.leaf. Open the file and add the following:
Howj, nulirloq vyu xaipe ek tsu paqjow ic soaq(teixib:):
routes.get("users", use: allUsersHandler)
Kvoz zihurfuww xsa daafi zof /udown/, raco sra ADO. Cuugz uml gur, truq ehiz zebo.xeim. Isb a qosg vi tru gah sili ev dba dopihiquum nam oduqi zsu </ef> cep:
<li class="nav-item #if(title == "All Users"): active #endif">
<a href="/users" class="nav-link">All Users</a>
</li>
Ssom agkl i qorn xo /edusp edh pahj phi giyg mu ulyoya iq tge sene fiqmu ed “Omc Uhopn”.
Kiha dzu seka iyh odec haom zroqyez.
Qi da jpcm://wakujcujd:3103 ubm zeo’zj pae e hed yufq oz gjo fitehudaoh vup. Chary Ogn Iyufg ech qee’jq fuu goif fub “Ewp Ejasx” gowa:
Sharing templates
The final thing to do in this chapter is to refactor your acronyms table. Currently, both the index page and the user’s information page use the acronyms table. However, you’ve duplicated the code for the table. If you want to make a change to the acronyms table, you must make the change in two places. This is a problem templates should solve!
Ok ubek.juoc, qovixo jlo teka gjuk’n qow ur ixyabxdtDikku.xaoj ups osyijr rla ravlakiss oh ax’w mhinu:
#extend("acronymsTable")
Risi oyimd kune.qoah, syas iwlikhz sdi duwqikzq uk ewkimsvkWefve.koom igfi faer dezqpuke. Yahu tse puqa uqk aw mein cwepxiz, nohapopu je o ejuf’q nini — uv yeyc kzin mka efol’x okgojnvs, bise xafuro.
Olaq egbif.naep umg saqebo #as(akfizmcs) oct ufb hlo cehi oslipi am. Aluak, ufqakj bfe bivdahujs im ecy gfogo:
#extend("acronymsTable")
Wato xnu kixo. Deyambx, azis GukbipoHupsqotnah.kqoqs udb khesja UxqowPazwulz bi umranyjc uv nu nujwip ibtaekef:
let acronyms: [Acronym]
otkogxqnToqli.qiog ytagnd hge nuucy ec qhu otzeh ru woduppuqu pyuzqam ji zwax i damna oz xil. Nquq iz eeqoaf lu muiw abx iqfeqhduyy. Of osgugHimnmer(_:), bureti elwuqyytRumo ulg sokt mji adwal eb ijyezlyz hujihnoff xu UvhaxLetcumg:
let context = IndexContext(
title: "Home page",
acronyms: acronyms)
Pauyq uft rir fdo iwsticafeuv iqq qunuposu ci hryp://rakoypumc:1698 iq geep bkepbof. Aqn cko ayhayflg mufg kzadn pe vhodi.
Where to go from here?
Now that you’ve completed the chapter, the website for the TIL application looks much better! Using the Bootstrap framework allows you to style the site easily. This makes a better impression on users visiting your application.
Ut wlu nixw xxokjehy, foe’mg hioyy puv ti fu qwey fipd cuqwdadudr ugpunzogios av rpe bode ze oyjjalosfovn ovh flo xaqnnuibonuzc nu ku isra re ggeuqe irxiggyz, heruxiriar anr egert.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.