Skip to content

Commit

Permalink
Merge pull request #284 from yesodweb/minor-docs
Browse files Browse the repository at this point in the history
book: Minor changes for Yesod 1.6
  • Loading branch information
snoyberg authored Dec 20, 2024
2 parents 8a54252 + 2bc9be6 commit 0fd3c6f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 49 deletions.
14 changes: 7 additions & 7 deletions book/asciidoc/basics.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ main = warp 3000 HelloWorld
----

If you save that code in +helloworld.hs+ and run it with +runhaskell
helloworld.hs+, you'll get a web server running on port 3000. Note,
helloworld.hs+, you'll get a web server running on port 3000. Note,
if you followed the quick start guide and installed yesod with +stack+
then you will not have +runhaskell+ and will need to run +stack runghc
helloworld.hs+ instead. If you point your browser to http://localhost:3000,
then you will not have +runhaskell+ and will need to run +stack runghc
helloworld.hs+ instead. If you point your browser to http://localhost:3000,
you'll get the following HTML:

[source, html]
Expand Down Expand Up @@ -112,7 +112,7 @@ instance YesodDispatch HelloWorld where
"GET" -> getHomeR
_ -> badMethod
type Handler = HandlerT HelloWorld IO
type Handler = HandlerFor HelloWorld
----

NOTE: In addition to using +-ddump-splices+, it can often be useful to generate
Expand Down Expand Up @@ -174,11 +174,11 @@ In our example, we pass +[whamlet|Hello World!|]+ to +defaultLayout+.
+whamlet+ is another quasi-quoter. In this case, it converts Hamlet syntax into
a Widget. Hamlet is the default HTML templating engine in Yesod. Together with
its siblings Cassius, Lucius and Julius, you can create HTML, CSS and
Javascript in a fully type-safe and compile-time-checked manner. We'll see much
JavaScript in a fully type-safe and compile-time-checked manner. We'll see much
more about this in the Shakespeare chapter.

Widgets are another cornerstone of Yesod. They allow you to create modular
components of a site consisting of HTML, CSS and Javascript and reuse them
components of a site consisting of HTML, CSS and JavaScript and reuse them
throughout your site. We'll get into more detail on them in the widgets
chapter.

Expand Down Expand Up @@ -212,7 +212,7 @@ NOTE: By the way, the word Yesod (יסוד) means _foundation_ in Hebrew.
Once again we mention +HelloWorld+ in our main function. Our foundation
contains all the information we need to route and respond to requests in our
application; now we just need to convert it into something that can run. A
useful function for this in Yesod is +warp+, which runs the Warp webserver with
useful function for this in Yesod is +warp+, which runs the Warp web server with
a number of default settings enabled on the specified port (here, it's 3000).

One of the features of Yesod is that you aren't tied down to a single
Expand Down
10 changes: 5 additions & 5 deletions book/asciidoc/haskell.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ which are available for reading online:
* link:http://book.realworldhaskell.org/read[Real World Haskell]

Additionally, there are a number of great articles on
link:https://www.fpcomplete.com/school[School of Haskell].
link:https://tech.fpcomplete.com/haskell/learn/[FP Complete's Haskell's hub].

In order to use Yesod, you're going to have to know at least the basics of
Haskell. Additionally, Yesod uses some features of Haskell that aren't covered
Expand All @@ -36,10 +36,10 @@ This is one of the core building blocks for a strongly typed
language like Haskell. Some data types, like +Int+, can be treated as primitive
values, while other data types will build on top of these to create more
complicated values. For example, you might represent a person with:
+
+
[source, haskell]
data Person = Person Text Int
+
+
Here, the +Text+ would give the person's name, and the +Int+ would give the
person's age. Due to its simplicity, this specific example type will recur
throughout the book. There are essentially three ways you can create a new data
Expand Down Expand Up @@ -128,7 +128,7 @@ are two other common approaches:
* In your +cabal+ file, add an +default-extensions+ block.

I personally never use the GHC command line argument approach. It's a personal
preference, but I like to have my settings clearly stated in a file. In general
preference, but I like to have my settings clearly stated in a file. In general,
it's recommended to avoid putting extensions in your +cabal+ file; however,
this rule mostly applies when writing publicly available libraries. When you're
writing an application that you and your team will be working on, having all of
Expand Down Expand Up @@ -287,7 +287,7 @@ with this].
A nice trick is that TH code is allowed to perform arbitrary +IO+ actions, and
therefore we can place some input in external files and have it parsed at
compile time. One example usage is to have compile-time checked HTML, CSS, and
Javascript templates.
JavaScript templates.

If your Template Haskell code is being used to generate declarations, and is
being placed at the top level of our file, we can leave off the dollar sign and
Expand Down
2 changes: 1 addition & 1 deletion book/asciidoc/introduction.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Since web programming began, people have been trying to make the development
process a more pleasant one. As a community, we have continually pushed new
techniques to try and solve some of the lingering difficulties of security
threats, the stateless nature of HTTP, the multiple languages (HTML, CSS,
Javascript) necessary to create a powerful web application, and more.
JavaScript) necessary to create a powerful web application, and more.

Yesod attempts to ease the web development process by playing to the strengths
of the Haskell programming language. Haskell’s strong compile-time guarantees
Expand Down
32 changes: 16 additions & 16 deletions book/asciidoc/shakespearean-templates.asciidoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
== Shakespearean Templates

Yesod uses the Shakespearean family of template languages as its standard
approach to HTML, CSS and Javascript creation. This language family shares some
approach to HTML, CSS and JavaScript creation. This language family shares some
common syntax, as well as overarching principles:

* As little interference to the underlying language as possible, while
Expand All @@ -28,7 +28,7 @@ Julius is for Javascript, and Cassius and Lucius are both for CSS. Hamlet and
Cassius are both whitespace-sensitive formats, using indentation to denote
nesting. By contrast, Lucius is a superset of CSS, keeping CSS's braces for
denoting nesting. Julius is a simple passthrough language for producing
Javascript; the only added feature is variable interpolation.
JavaScript; the only added feature is variable interpolation.

NOTE: Cassius is in fact just an alternate syntax for Lucius. They both use the
same processing engine underneath, but Cassius files have indentation converted
Expand Down Expand Up @@ -84,7 +84,7 @@ section.blog
background-image: url(@{MyBackgroundR})
----

==== Julius (Javascript)
==== Julius (JavaScript)

String interpolation works slightly differently in Julius. This is important
from a security standpoint — all interpolated values are valid JSON by default
Expand Down Expand Up @@ -121,7 +121,7 @@ name. It might look like this:
<p>Hello, my name is #{name}
----


NOTE: +#{...}+ is how we do variable interpolation in Shakespeare.

What should happen to +name+, and what should its datatype be? A naive approach
Expand Down Expand Up @@ -189,11 +189,11 @@ _http://example.com/display/time_ displays the current time. And let's say we
want to link from the homepage to the time. I can think of three different ways
of constructing the URL:

. As a relative link: _../display/time_
. As a relative link: _../display/time_

. As an absolute link, without a domain: _/display/time_
. As an absolute link, without a domain: _/display/time_

. As an absolute link, with a domain: _http://example.com/display/time_
. As an absolute link, with a domain: _http://example.com/display/time_

There are problems with each approach: the first will break if either URL
changes. Also, it's not suitable for all use cases; RSS and Atom feeds, for
Expand Down Expand Up @@ -230,7 +230,7 @@ renderMyRoute :: MyRoute -> Text
renderMyRoute Home = "http://example.com/profile/home"
renderMyRoute Time = "http://example.com/display/time"
----

[NOTE]
====
URL rendering functions are actually a bit more complicated than this. They
Expand Down Expand Up @@ -273,7 +273,7 @@ this would translate roughly into the Haskell code:

All Shakespearean languages share the same interpolation syntax, and are able
to utilize type-safe URLs. They differ in the syntax specific for their target
language (HTML, CSS, or Javascript). Let's explore each language in turn.
language (HTML, CSS, or JavaScript). Let's explore each language in turn.

==== Hamlet Syntax

Expand Down Expand Up @@ -635,7 +635,7 @@ $doctype 5
<p>All done.
----


NOTE: There is an older and still supported syntax: three exclamation points
(+!!!+). You may still see this in code out there. We have no plans to remove
support for this, but in general find the +$doctype+ approach easier to read.
Expand All @@ -653,7 +653,7 @@ in a few more features.
* You can declare variables in your templates.

* A set of CSS properties can be created as a mixin, and reused in multiple
declarations.
declarations.

Starting with the second point: let's say you want to have some special styling
for some tags within your +article+. In plain ol' CSS, you'd have to write:
Expand Down Expand Up @@ -743,12 +743,12 @@ simple example:
==== Julius Syntax

Julius is the simplest of the languages discussed here. In fact, some might
even say it's really just Javascript. Julius allows the three forms of
even say it's really just JavaScript. Julius allows the three forms of
interpolation we've mentioned so far, and otherwise applies no transformations
to your content.

NOTE: If you use Julius with the scaffolded Yesod site, you may notice that
your Javascript is automatically minified. This is not a feature of Julius;
your JavaScript is automatically minified. This is not a feature of Julius;
instead, Yesod uses the hjsmin package to minify Julius output.

=== Calling Shakespeare
Expand Down Expand Up @@ -873,7 +873,7 @@ There are a few changes:

* We use a different set of functions, prefixed with an "s". So the quasiquoter
is +shamlet+ and the external file function is +shamletFile+. How we
pronounce those is still up for debate.
pronounce this is still up for debate.

* No URL interpolation is allowed. Doing so will result in a compile-time
error.
Expand Down Expand Up @@ -920,7 +920,7 @@ $doctype 5
<p>_{Apples count}
----



This kind of a template now needs some way to turn those values into HTML. So
just like type-safe URLs, we pass in a render function. To represent this, we
Expand Down Expand Up @@ -981,7 +981,7 @@ main = putStrLn $ renderHtml

=== Other Shakespeare

In addition to HTML, CSS and Javascript helpers, there is also some more
In addition to HTML, CSS and JavaScript helpers, there is also some more
general-purpose Shakespeare available. shakespeare-text provides a simple way
to create interpolated strings, much like people are accustomed to in scripting
languages like Ruby and Python. This package's utility is definitely not
Expand Down
38 changes: 18 additions & 20 deletions book/asciidoc/widgets.asciidoc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
== Widgets

One of the challenges in web development is that we have to coordinate three
different client-side technologies: HTML, CSS and Javascript. Worse still, we
different client-side technologies: HTML, CSS and JavaScript. Worse still, we
have to place these components in different locations on the page: CSS in a
style tag in the head, Javascript in a script tag before the closing body tag, and HTML in the
body. And never mind if you want to put your CSS and Javascript in separate
style tag in the head, JavaScript in a script tag before the closing body tag, and HTML in the
body. And never mind if you want to put your CSS and JavaScript in separate
files!

In practice, this works out fairly nicely when building a single page, because
we can separate our structure (HTML), style (CSS) and logic (Javascript). But
we can separate our structure (HTML), style (CSS) and logic (JavaScript). But
when we want to build modular pieces of code that can be easily composed, it
can be a headache to coordinate all three pieces separately. Widgets are
Yesod's solution to the problem. They also help with the issue of including
Expand Down Expand Up @@ -118,7 +118,7 @@ page. In particular:
* External stylesheets
* External Javascript
* CSS declarations
* Javascript code
* JavaScript code
* Arbitrary +<head>+ content
* Arbitrary +<body>+ content

Expand Down Expand Up @@ -148,7 +148,7 @@ style code appear in a separate file. The scaffolded site provides this for you
automatically.

But what if you want to add some +<meta>+ tags, which need to appear in
the head? Or if you want some Javascript to appear in the body instead of the
the head? Or if you want some JavaScript to appear in the body instead of the
head? For these purposes, Yesod provides two additional type classes:
+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.

Expand Down Expand Up @@ -207,7 +207,7 @@ referring to files hosted on a CDN, like Google's jQuery.
=== Combining Widgets

The whole idea of widgets is to increase composability. You can take these
individual pieces of HTML, CSS and Javascript, combine them together into
individual pieces of HTML, CSS and JavaScript, combine them together into
something more complicated, and then combine these larger entities into
complete pages. This all works naturally through the +Monad+ instance of
+Widget+, meaning you can use do-notation to compose pieces together.
Expand Down Expand Up @@ -322,26 +322,24 @@ answer is that each widget is a value of type +Widget+. But if you look through
the Yesod libraries, you'll find no definition of the +Widget+ type. What
gives?

Yesod defines a very similar type: +data WidgetT site m a+. This data type is a
*monad transformer*. The last two arguments are the underlying monad and the
monadic value, respectively. The site parameter is the specific foundation
type for your individual application. Since this type varies for each and every
site, it's impossible for the libraries to define a single +Widget+ datatype
which would work for every application.
Yesod defines a very similar type: +data WidgetFor site a+. This data
type is a *monad transformer*. The last argument +a+ is the monadic
value. The site parameter is the specific foundation type for your
individual application. Since this type varies for each and every
site, it's impossible for the libraries to define a single +Widget+
datatype which would work for every application.

Instead, the +mkYesod+ Template Haskell function generates this type synonym
for you. Assuming your foundation data type is called +MyApp+, your +Widget+
synonym is defined as:

[source, haskell]
--------
type Widget = WidgetT MyApp IO ()
type Widget = WidgetFor MyApp ()
--------

We set the monadic value to be +()+, since a widget's value will ultimately be
thrown away. +IO+ is the standard base monad, and will be used in almost all
cases. The only exception is when writing a *subsite*. Subsites are a more
advanced topic, and will be covered later in their own chapter.
thrown away.

Once we know about our +Widget+ type synonym, it's easy to add signatures to
our previous code samples:
Expand Down Expand Up @@ -372,14 +370,14 @@ page =
----

When we start digging into handler functions some more, we'll encounter a
similar situation with the +HandlerT+ and +Handler+ types.
similar situation with the +HandlerFor+ and +Handler+ types.

=== Using Widgets

It's all well and good that we have these beautiful Widget datatypes, but how
exactly do we turn them into something the user can interact with? The most
commonly used function is +defaultLayout+, which essentially has the type
signature +Widget -> Handler Html+.
signature +WidgetFor -> HandlerFor Html+.

+defaultLayout+ is actually a typeclass method, which can be overridden for
each application. This is how Yesod apps are themed. So we're still left with
Expand Down Expand Up @@ -535,7 +533,7 @@ tricks which were previously employed.
=== Summary

The basic building block of each page is a widget. Individual snippets of HTML,
CSS, and Javascript can be turned into widgets via the polymorphic +toWidget+
CSS, and JavaScript can be turned into widgets via the polymorphic +toWidget+
function. Using do-notation, you can combine these individual widgets into
larger widgets, eventually containing all the content of your page.

Expand Down

0 comments on commit 0fd3c6f

Please sign in to comment.