You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/asciidoc/widgets.asciidoc
+18-20Lines changed: 18 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
== Widgets
2
2
3
3
One of the challenges in web development is that we have to coordinate three
4
-
different client-side technologies: HTML, CSS and Javascript. Worse still, we
4
+
different client-side technologies: HTML, CSS and JavaScript. Worse still, we
5
5
have to place these components in different locations on the page: CSS in a
6
-
style tag in the head, Javascript in a script tag before the closing body tag, and HTML in the
7
-
body. And never mind if you want to put your CSS and Javascript in separate
6
+
style tag in the head, JavaScript in a script tag before the closing body tag, and HTML in the
7
+
body. And never mind if you want to put your CSS and JavaScript in separate
8
8
files!
9
9
10
10
In practice, this works out fairly nicely when building a single page, because
11
-
we can separate our structure (HTML), style (CSS) and logic (Javascript). But
11
+
we can separate our structure (HTML), style (CSS) and logic (JavaScript). But
12
12
when we want to build modular pieces of code that can be easily composed, it
13
13
can be a headache to coordinate all three pieces separately. Widgets are
14
14
Yesod's solution to the problem. They also help with the issue of including
@@ -118,7 +118,7 @@ page. In particular:
118
118
* External stylesheets
119
119
* External Javascript
120
120
* CSS declarations
121
-
* Javascript code
121
+
* JavaScript code
122
122
* Arbitrary +<head>+ content
123
123
* Arbitrary +<body>+ content
124
124
@@ -148,7 +148,7 @@ style code appear in a separate file. The scaffolded site provides this for you
148
148
automatically.
149
149
150
150
But what if you want to add some +<meta>+ tags, which need to appear in
151
-
the head? Or if you want some Javascript to appear in the body instead of the
151
+
the head? Or if you want some JavaScript to appear in the body instead of the
152
152
head? For these purposes, Yesod provides two additional type classes:
153
153
+ToWidgetHead+ and +ToWidgetBody+. These work exactly as they seem they should. One example use case for this is to have fine-grained control of where your +<script>+ tags end up getting inserted.
154
154
@@ -207,7 +207,7 @@ referring to files hosted on a CDN, like Google's jQuery.
207
207
=== Combining Widgets
208
208
209
209
The whole idea of widgets is to increase composability. You can take these
210
-
individual pieces of HTML, CSS and Javascript, combine them together into
210
+
individual pieces of HTML, CSS and JavaScript, combine them together into
211
211
something more complicated, and then combine these larger entities into
212
212
complete pages. This all works naturally through the +Monad+ instance of
213
213
+Widget+, meaning you can use do-notation to compose pieces together.
@@ -322,26 +322,24 @@ answer is that each widget is a value of type +Widget+. But if you look through
322
322
the Yesod libraries, you'll find no definition of the +Widget+ type. What
323
323
gives?
324
324
325
-
Yesod defines a very similar type: +data WidgetT site m a+. This data type is a
326
-
*monad transformer*. The last two arguments are the underlying monad and the
327
-
monadic value, respectively. The site parameter is the specific foundation
328
-
type for your individual application. Since this type varies for each and every
329
-
site, it's impossible for the libraries to define a single +Widget+ datatype
330
-
which would work for every application.
325
+
Yesod defines a very similar type: +data WidgetFor site a+. This data
326
+
type is a *monad transformer*. The last argument +a+ is the monadic
327
+
value. The site parameter is the specific foundation type for your
328
+
individual application. Since this type varies for each and every
329
+
site, it's impossible for the libraries to define a single +Widget+
330
+
datatype which would work for every application.
331
331
332
332
Instead, the +mkYesod+ Template Haskell function generates this type synonym
333
333
for you. Assuming your foundation data type is called +MyApp+, your +Widget+
334
334
synonym is defined as:
335
335
336
336
[source, haskell]
337
337
--------
338
-
type Widget = WidgetT MyApp IO ()
338
+
type Widget = WidgetFor MyApp ()
339
339
--------
340
340
341
341
We set the monadic value to be +()+, since a widget's value will ultimately be
342
-
thrown away. +IO+ is the standard base monad, and will be used in almost all
343
-
cases. The only exception is when writing a *subsite*. Subsites are a more
344
-
advanced topic, and will be covered later in their own chapter.
342
+
thrown away.
345
343
346
344
Once we know about our +Widget+ type synonym, it's easy to add signatures to
347
345
our previous code samples:
@@ -372,14 +370,14 @@ page =
372
370
----
373
371
374
372
When we start digging into handler functions some more, we'll encounter a
375
-
similar situation with the +HandlerT+ and +Handler+ types.
373
+
similar situation with the +HandlerFor+ and +Handler+ types.
376
374
377
375
=== Using Widgets
378
376
379
377
It's all well and good that we have these beautiful Widget datatypes, but how
380
378
exactly do we turn them into something the user can interact with? The most
381
379
commonly used function is +defaultLayout+, which essentially has the type
382
-
signature +Widget -> Handler Html+.
380
+
signature +WidgetFor -> HandlerFor Html+.
383
381
384
382
+defaultLayout+ is actually a typeclass method, which can be overridden for
385
383
each application. This is how Yesod apps are themed. So we're still left with
@@ -535,7 +533,7 @@ tricks which were previously employed.
535
533
=== Summary
536
534
537
535
The basic building block of each page is a widget. Individual snippets of HTML,
538
-
CSS, and Javascript can be turned into widgets via the polymorphic +toWidget+
536
+
CSS, and JavaScript can be turned into widgets via the polymorphic +toWidget+
539
537
function. Using do-notation, you can combine these individual widgets into
540
538
larger widgets, eventually containing all the content of your page.
0 commit comments