Hyperlinks
Table of Contents
1. Intro
As you may have seen in the getting started document, it's possible to declare multiple routes for a single website. Since each route is able to define it's own output URL path dynamically, hardcoding link URLs won't get you very far.
In order to link to a document generated by a weblorg-route, we
provide url_for
. It can be used either in templates as a filter
or in Org-Mode files as a link handler. Let's look at an example
route:
(weblorg-route :name "posts" :input-pattern "posts/*.org" :template "post.html" :output "output/posts/{{ slug }}.html" :url "/posts/{{ slug }}.html")
2. Links on templates
If one wants to link to a post with the slug full-moon
from any
template in the website, url_for
can be used as follows to
achieve that:
<a href="{{ url_for("posts", slug="full-moon") }}">A Bright Night</a>
The first parameter for url_for
is the name of the route one is
pointing to, it is required and not passing it will cause the
export of that template to fail with wrong-number-of-arguments
.
After the name of the route, url_for
takes all the variables
expected by the :url
parameter of the route as keyword arguments.
The example above only requires slug
, and not providing it to
url_for
would cause an error exporting the template.
3. Links in Org-Mode files
If the goal is to link to that post from another Org-Mode file,
url_for
can also be used as an Org-Mode link. Weblorg allows
that by temporarily adding a hyperlink type for it:
[[url_for:posts,slug=full-moon][A Bright Night]]
Both the template and the Org-Mode versions of url_for
have
exactly the same outcome:
http://localhost:8000/posts/full-moon.html
.
4. Image URLs in Org-Mode files
The hyperlink type url_for
always renders the <a>
HTML tag. If
the resource referenced is an image and the tag <img>
is
preferred, please use url_for_img
. Both take exactly the same
parameters. e.g.:
[[url_for:static,file=sundown.png][orange]] [[url_for_img:static,file=sundown.png][orange]]
Here's how they are rendered differently by weblorg:
<a href="static/sundown.png">orange</a> <img src="static/sundown.png" alt="orange">
Notice that url_for_img
only exists as an Org-Mode hyperlink
type.
5. Base URL
All the links of a route are prefixed with a base URL defined
within the route's :site
property. Although weblorg supports
multiple site
instances, when a route is created without
explicitly receiving one, it uses a default one.
The default URL for the site that's implicitly created for routes
is controlled by the variable weblorg-default-url
. It's default
value is http://localhost:8000
but it can be set before calling
weblorg-export
.
6. Convenient switch for the Base URL
During the development of a website, it's common to use a local address and then switch to different one before rendering the final version. Since that can happen a few times throughout the life of a website, the snippet below can be used to make it easy to switch:
;; defaults to http://localhost:8000 (if (string= (getenv "ENV") "prod") (setq weblorg-default-url "https://emacs.love/weblorg"))
And then set the environment variable ENV
to override the default
when needed:
ENV=prod emacs --script publish.el
7. Empty Routes
If one wants to link to content that isn't generated by weblorg,
they can still use url_for
by creating a route that doesn't match
with any files (thus doesn't create any output) but provide the
desired :url
field.
Let's say we have a directory slides
within our static website
with some presentations we want to link from a blog post. We would
need to add something like this to the publish.el
script:
(weblorg-route :name "slides" :url "/slides/{{ presentation }}")
And then url_for
could be used to generate links for those
resources as well:
[[url_for:slides,presentation=tie-shoelaces-with-one-hand][Skills]]
8. Anchors
url_for
treats the keyword parameter anchor
as a special case.
Instead of using it as a variable for rendering the template
expression within :url
, it appends the value of the parameter
after the pound sign (#
) to the end of the generated URL. E.g.:
[[url_for:posts,slug=long-story,anchor=half-way][Long Story]]
That will be rendered to something like this:
<a href="http://localhost:8000/posts/long-story.html#half-way">Long Story</a>