Tutorial cleanup (#16)

* rewrite intro and swap with installation

* more content tweaks

* cleanup jorge-post in tutorial

* cleanup jorge build tutorial
This commit is contained in:
Facundo Olano 2024-02-27 10:38:02 -03:00 committed by GitHub
parent a07d4af5c2
commit e1280f07d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 57 additions and 54 deletions

View file

@ -47,6 +47,10 @@ li {
line-height: 1.6; line-height: 1.6;
} }
.layout-post li p {
margin: 0.5rem 0;
}
li:not(:last-child) { li:not(:last-child) {
padding-bottom: .75rem; padding-bottom: .75rem;
} }

View file

@ -3,7 +3,7 @@ title: Installation
layout: post layout: post
lang: en lang: en
tags: [tutorial] tags: [tutorial]
index: 0 index: 1
--- ---
#+OPTIONS: toc:nil num:nil #+OPTIONS: toc:nil num:nil
#+LANGUAGE: en #+LANGUAGE: en
@ -16,7 +16,7 @@ $ chmod +x jorge
$ mv jorge /usr/local/bin $ mv jorge /usr/local/bin
#+end_src #+end_src
Alternatively, if you have Go available in your system, you can install with: Alternatively, if you have Go available in your system, you can install it with:
#+begin_src bash #+begin_src bash
$ go install github.com/facundoolano/jorge@latest $ go install github.com/facundoolano/jorge@latest
@ -51,4 +51,4 @@ Run "jorge <command> --help" for more information on a command.
#+HTML: <br> #+HTML: <br>
#+ATTR_HTML: :align right #+ATTR_HTML: :align right
Next: [[file:introduction][Introduction]]. Next: [[file:jorge-init][start a website]].

View file

@ -3,21 +3,20 @@ title: Introduction
layout: post layout: post
lang: en lang: en
tags: [tutorial] tags: [tutorial]
index: 1 index: 0
--- ---
#+OPTIONS: toc:nil num:nil #+OPTIONS: toc:nil num:nil
#+LANGUAGE: en #+LANGUAGE: en
jorge is a personal static site generator, inspired by Jekyll. In this context, I[fn:1] use personal as "small and opinionated". In practical terms, this means that jorge implements the subset of features from Jekyll that I find most useful and that I defaulted to Jekyll's design decisions except in the specific cases where I had strong differing preferences. jorge is a personal static site generator, inspired by [[https://jekyllrb.com/][Jekyll]]. In this context, I[fn:1] use personal as "small and opinionated". In practical terms, this means that jorge implements the subset of features that I find most useful in a static site generator, and that I defaulted to Jekyll's design except in the specific cases where I had strong differing preferences.
jorge started as a Golang learning project, aimed at streamlining my blogging workflow. It adds native org-mode syntax support and, at least for my website, it turned out to be much faster than Jekyll. jorge should /almost/ work as a drop-in replacement for Jekyll: the directory structure is a bit different but most of the content should render with few changes. Additionally, I tried to add support to generate a fully functional (albeit minimalist and kind of ugly) website from scratch. jorge started as a Go learning project, aimed at streamlining my blogging workflow. It adds native org-mode syntax support and doesn't require plugins for common features like RSS feeds, syntax highlighting, and minifiying. It works both as an /almost/ drop-in replacement for Jekyll and to quickly setup fully functional (albeit minimalist and kind of ugly) websites from scratch.
This tutorial covers the basics of using jorge, from starting a site to deploying it. I tried to keep it accessible, but you may need to consult with Jekyll or Hugo documentation if you never used a static site generator, want to get the finer-grained details of template syntax, etc.
This tutorial covers the basics of using jorge, from starting a site to deploying it. I tried to keep it accessible, but you may need to consult with [[https://jekyllrb.com/docs/][Jekyll]] or [[https://gohugo.io/documentation/][Hugo]] documentation if you never used a static site generator, want to get the finer-grained details of template syntax, etc.
#+HTML: <br> #+HTML: <br>
#+ATTR_HTML: :align right #+ATTR_HTML: :align right
Next: [[file:jorge-init][start a website]]. Next: [[file:installation][install jorge]].
*** Notes *** Notes

View file

@ -9,7 +9,7 @@ index: 5
#+OPTIONS: toc:nil num:nil #+OPTIONS: toc:nil num:nil
#+LANGUAGE: en #+LANGUAGE: en
So far you've seen how to [[file:jorge-init][start a project]], [[file:jorge-serve][serve it locally]] and [[file:jorge-post][add some content]] to it. The last part of job is to prepare your site for the public, and ~jorge build~ will help with that: So far you've seen how to [[file:jorge-init][start a project]], [[file:jorge-serve][serve it locally]] and [[file:jorge-post][add some content]] to it. The last step is to prepare your site for the public, and ~jorge build~ will help you with that:
#+begin_src console #+begin_src console
$ jorge build $ jorge build
@ -24,33 +24,32 @@ wrote target/feed.xml
wrote target/blog/index.html wrote target/blog/index.html
#+end_src #+end_src
Just like ~jorge serve~ did before, ~jorge build~ walks your ~src/~ files and renders them into ~target/~, but with a few differences: Just like ~jorge serve~ did before, ~jorge build~ scans your ~src/~ directory and renders its files into ~target/~, but with a few differences:
- Static files are copied over to ~target/~ instead of just linked. - Static files are copied over to ~target/~ instead of just linked.
- The ~url~ from your ~config.yml~ is used as the root when rendering absolute urls (instead of the ~http://localhost:4001~ used when serving locally). - The ~url~ from your ~config.yml~ is used as the root when rendering absolute urls (instead of the ~http://localhost:4001~ used when serving locally).
- The HTML, XML, CSS and JavaScript files are minified. - The HTML, XML, CSS and JavaScript files are minified.
Once you have your static site rendered, it's just a matter to putting it out in the internet. There are many ways to publish a static site, and covering them is out of the scope of this tutorial[fn:1]. I suggest going through the [[https://jekyllrb.com/docs/deployment/][Jekyll]] and [[https://gohugo.io/hosting-and-deployment/][Hugo]] docs for inspiration. After running ~jorge build~, the contents of the ~target/~ directory will be ready for a web server. There are many ways to publish a static site to the internet, and covering them all is out of the scope of this tutorial[fn:1]. I suggest going through the [[https://jekyllrb.com/docs/deployment/][Jekyll]] and [[https://gohugo.io/hosting-and-deployment/][Hugo]] docs for inspiration.
But for the sake of completenss, this is how this site is deployed: I have a VPS box running Debian Linux and with the [[https://www.nginx.com/][nginx]] server installed on it. I added this configuration to ~/etc/nginx/sites-enabled/jorge~: But for the sake of completeness, this is how this site is deployed: I have a VPS box running Debian Linux and with the [[https://www.nginx.com/][nginx]] server installed on it. I added this configuration to ~/etc/nginx/sites-enabled/jorge~:
#+begin_src nginx #+begin_src nginx
server { server {
charset utf-8; charset utf-8;
root /var/www/jorge; root /var/www/jorge;
server_name jorge.olano.dev; server_name jorge.olano.dev;
location / { location / {
# First attempt to serve request as file, then as directory. Otherwise respond 404. # First attempt to serve request as file,
try_files $uri $uri.html $uri/ =404; # then as directory. Otherwise respond 404.
} try_files $uri $uri.html $uri/ =404;
} }
}
#+end_src #+end_src
I instructed my DNS provider to point ~jorge.olano.dev~ to the box and I ran [[https://certbot.eff.org/instructions?ws=nginx&os=debianbuster][certbot]] to generate certificates for that subdomain. I instructed my DNS server to point ~jorge.olano.dev~ to the IP of the box and I ran [[https://certbot.eff.org/instructions?ws=nginx&os=debianbuster][certbot]] to generate certificates for that subdomain. I then created the ~/var/www/jorge~ directory in the server, and deployed from my laptop using ~rsync~:
I then created the ~/var/www/jorge~ directory in the server, and deployed from my laptop using ~rsync~:
#+begin_src console #+begin_src console
$ jorge build $ jorge build

View file

@ -15,7 +15,7 @@ Once jorge is [[file:installation][installed]], you can start a new site with th
$ jorge init myblog $ jorge init myblog
> site name: My Blog > site name: My Blog
> site url: https://myblog.example.com > site url: https://myblog.example.com
> author: Jorge Blog > author: Jorge Luis Blogger
added myblog/config.yml added myblog/config.yml
added myblog/README.md added myblog/README.md
added myblog/.gitignore added myblog/.gitignore
@ -33,13 +33,13 @@ added myblog/src/feed.xml
added myblog/src/index.html added myblog/src/index.html
#+end_src #+end_src
The command will first prompt for some information necessary to fill some content in the default project files: The command first prompts for some information to fill the default project files:
- The site name will be used for the HTML title of the pages. - The site name will be used for the HTML title of the pages.
- The URL will be used when rendering absolute URLs for links, for instance in the default atom feed. - The URL will be used when rendering absolute URLs for links, for instance in the default Atom feed.
- The author is used in the site's HTML metadata and the atom feed. - The author is used in the site's HTML metadata and the Atom feed.
You can change those values anytime by editing the ~config.yml~ file, so it doesn't really matter if you're not sure what to put in there. You can change those values later by editing the ~config.yml~ file, so don't worry if you haven't decided on a name or domain yet.
Let's look at the files created by init: Let's look at the files created by init:
| ~config.yml~ | a YAML file with configuration keys. Some affect how jorge works, and all will be available as variables for rendering templates. | | ~config.yml~ | a YAML file with configuration keys. Some affect how jorge works, and all will be available as variables for rendering templates. |
@ -47,16 +47,17 @@ Let's look at the files created by init:
| ~.gitignore~ | the git ignore patterns, initialized to ignore jorge generated files. Both this and the readme are added under the assumption that you'll check your project code into a git repository. | | | ~.gitignore~ | the git ignore patterns, initialized to ignore jorge generated files. Both this and the readme are added under the assumption that you'll check your project code into a git repository. | |
| ~src/~ | the root of your website. Anything you put in here will, in some way or another, be included in your public site. The source directory is the most important part of a jorge project; in fact, it's the only thing required to build your site. | | | ~src/~ | the root of your website. Anything you put in here will, in some way or another, be included in your public site. The source directory is the most important part of a jorge project; in fact, it's the only thing required to build your site. | |
| ~src/index.html~ | an HTML template for your website root. | | | ~src/index.html~ | an HTML template for your website root. | |
| ~src/feed.xml~ | a template for an atom feed of the website's most recent posts. | | | ~src/feed.xml~ | a template for an Atom feed of the website's most recent posts. | |
| ~src/assets/css/main.css~ | the default CSS styles. | | | ~src/assets/css/main.css~ | the default CSS styles for the site. | |
| ~src/blog/hello-org.org~ | an example blog post using org-mode syntax. | | | ~src/blog/hello-org.org~ | an example blog post using org-mode syntax. | |
| ~src/blog/goodbye-markdown.md~ | an example blog post using markdown syntax. | | | ~src/blog/goodbye-markdown.md~ | an example blog post using markdown syntax. | |
| ~src/blog/index.html~ | an HTML template for the full blog archive. | | | ~src/blog/index.html~ | an HTML template for the full blog archive. | |
| ~src/blog/tags.html~ | an HTML template for the blog archive organized by tags. | | | ~src/blog/tags.html~ | an HTML template for the blog archive, organized by tags. | |
| ~layouts/*.html~ | HTML templates that can be used by other templates to "fill the blanks" of a default HTML structure. For example, ~base.html~ defines the default layout for the entire website, while ~posts.html~ extends it to determine the layout specific to blog posts. | | | ~layouts/*.html~ | HTML templates that can be used by other templates to "fill the blanks" of a default HTML structure. For example, ~base.html~ defines the default layout for the entire website, while ~posts.html~ extends it to determine the layout specific to blog posts. | |
| ~includes/*.html~ | HTML template fragments that can be injected into other templates, to reduce duplication. | | | ~includes/*.html~ | HTML template fragments that can be injected into other templates, to reduce duplication. | |
Note how jorge assumes that index files are to be served as URL directories (~src/blog/index.html~ will be served at ~/blog/)~ and that the HTML extensions will be omitted (~src/blog/tags.html~ will be served at ~/blog/tags~). Note how jorge assumes that the ~.html~ file extension will be omitted when serving your site (eg. ~src/blog/tags.html~ will be served at ~/blog/tags~)
and that index files represent URL directories (~src/blog/index.html~ will be served as ~/blog/)~.
If you prefer to build your site from scratch, you can skip running ~jorge init~ altogether; the rest of the commands only expect a ~src/~ directory to work with. If you prefer to build your site from scratch, you can skip running ~jorge init~ altogether; the rest of the commands only expect a ~src/~ directory to work with.

View file

@ -11,31 +11,31 @@ index: 4
** Posts and pages ** Posts and pages
When jorge walks your ~src/~ directory, building a website to ~target/~ for serving locally or publishing in production, it distinguishes between 3 types of files: When jorge builds a website out of the contents of your ~src/~ directory, it distinguishes between 3 types of files:
1. Static files: any file that's not a template. These are files that don't contain a front matter header (that don't start with a ~---~ line). 1. Static files: any file that's not a template. These are files that don't contain a front matter header (that don't start with a ~---~ line).
2. Template files, which can be further divided into: 2. Template files, which can be further divided into:
a. Posts: templates that include a ~date~ field in their front matter, and thus can be sorted chronologically. a. Posts: templates that include a ~date~ field in their front matter, and thus can be sorted chronologically.
b. Pages: any other template file. b. Pages: any other template file.
As you can see, the difference between posts and pages is very subtle. The reason why jorge distinguishes posts is that you may want to leverage the chronological nature of posts for things like building a blog archive page or publishing the most recent posts to an RSS feeds[fn:1]. In practical terms, this difference only affects how posts and pages are exposed to templates as liquid variables: As you can see, the difference between posts and pages is subtle. Posts receive special treatment so their chronological nature can be used for things like building a blog archive page or publishing the most recent posts to RSS feeds[fn:1]. In practical terms, this difference only affects how posts and pages are exposed as template variables:
1. Pages are listed without a particular order in the ~site.pages~ variable[fn:2]. 1. Pages are listed without a particular order in the ~site.pages~ variable[fn:2].
2. Posts are listed in reverse chronological order (most recent first) in the ~site.posts~ variable. 2. Posts are listed in reverse chronological order (most recent first) in the ~site.posts~ variable.
3. Additionally, posts that declare ~tags~ in their front matter, are included in the ~site.tags~ map. 3. If they that declare ~tags~ in their front matter, posts are additionally included in the ~site.tags~ map.
4. Each post contains an ~excerpt~ property with a summary of its contents. If ~excerpt~ is included as a key in the front matter, its value will be used; otherwise (assuming it renders to HTML), the post's first paragraph will be used. Excerpts are useful for post previews in the blog archive, in social media links, and in RSS feeds. 4. Posts expose an ~excerpt~ property with a summary of their contents. If ~excerpt~ is defined as a key in the post front matter, its value will be used; if not, the first paragraph of the post content will be used instead. Excerpts are useful for previewing posts in the blog archive, in social media links, and in RSS feeds.
** jorge post ** jorge post
Each website has its own layout so it's hard to predict what you may need to do with a page template. But blogs are different: once the site structure is in place, you more or less repeat the same boilerplate every time you need to add a new blog post. For this reason, jorge provides the ~jorge post~ command to initialize blog post template files. Let's try it out. Each website has its own layout so it's hard to predict what you may need to do with a page template. But blogs are different: once the site layout is in place, you more or less repeat the same steps every time you write a new post. For this reason, jorge provides the ~jorge post~ command to initialize blog post template files.
From the root directory of your project run ~jorge post "My own blog post"~: Let's try it out:
#+begin_src console #+begin_src console
$ jorge post "My own blog post" $ jorge post "My own blog post"
added src/blog/my-own-blog-post.org added src/blog/my-own-blog-post.org
#+end_src #+end_src
If you open the new file with your editor, you should see something like this: If you open this new file in your editor, you should see something like this:
#+begin_src org #+begin_src org
--- ---
@ -51,31 +51,31 @@ tags: []
Let's look at what the command did for us: Let's look at what the command did for us:
{% raw %} {% raw %}
| ~src/blog/my-own-blog-post.org~ | The added file includes a URL-friendly version of the post tile (a "slug"), such that the post will be served at ~/blog/my-own-blog-post~ | | ~src/blog/my-own-blog-post.org~ | The filename, a URL-friendly version of the post title (a "slug"), such that the post will be served at ~/blog/my-own-blog-post~ |
| ~title: My own blog post~ | The title we passed to jorge. This will be available to templates as ~{{page.title}}~ and will be used by the post layout to render the header of the page. | | ~title: My own blog post~ | The title we passed to jorge. This will be available to templates as ~{{page.title}}~ and will be used by the default post layout to render the header of the page. |
| ~date: 2024-02-23 11:45:30~ | The date this post was created, will affect the position it shows up in in ~{{site.posts}}~ | | ~date: 2024-02-23 11:45:30~ | The date this post was created. It will affect the position it shows up in in ~{{site.posts}}~ |
| ~layout: post~ | The rendered HTML of this template will be embedded as the ~{{contents}}~ of the layout defined in ~layouts/post.html~. | | ~layout: post~ | The rendered HTML of this template will be embedded as the ~{{contents}}~ of the layout defined in ~layouts/post.html~. |
| ~lang: en~ | The language code for the post. This is used by some of the default templates, for instance, to determine how to hyphenate the post content. | | ~lang: en~ | The language code for the post. This is used by some of the default templates, for instance, to determine how to hyphenate the post content. |
| ~tags: []~ | The post tags, initially empty. the words added to this list will affect which keys of the ~{{site.tags}}~ map this post will be included in. | ~tags: []~ | The post tags, initially empty. The keywords in this list will determine which keys of the ~{{site.tags}}~ map this post will be associated with.
| ~#+OPTIONS: toc:nil num:nil~, ~#+LANGUAGE: en~ | Some default org mode options, to skip the table of contents and define the post language. | | ~#+OPTIONS: toc:nil num:nil~, ~#+LANGUAGE: en~ | Some default org mode options, to skip the table of contents and define the post language. |
{% endraw %} {% endraw %}
With ~jorge serve~ running, you can start filling in some content on this new post and see it show up in the browser at http://localhost:4001/blog/my-own-blog-post. With ~jorge serve~ running, you can start filling in some content on this new post and see it show up in the browser at http://localhost:4001/blog/my-own-blog-post.
** Customizing the post format ** Customizing the post format
As you may have noticed, the ~jorge post~ command makes a lot of assumptions: where to put it, how to name it, and what format to use. You can control some of these decisions by setting the ~post_format~ configuration key. The default is: As you may have noticed, the ~jorge post~ command makes a lot of assumptions about the post: where to put it, how to name it, and what format to use. You can control some of these decisions by redefining the ~post_format~ configuration key. The default is:
#+begin_src yaml #+begin_src yaml
post_format: "blog/:title.org" post_format: "blog/:title.org"
#+end_src #+end_src
Let's say that you want to put posts in the root folder, include the date in them, and use the markdown format by default. Add this key to your ~config.yml~: Let's say that you want to put posts in the root folder, use the date as part of the url, and use markdown instead of org syntax. In that case you'd add this to your ~config.yml~:
#+begin_src yaml #+begin_src yaml
post_format: ":year-:month-:day-:title.md" post_format: ":year-:month-:day-:title.md"
#+end_src #+end_src
The, if you add a new post: Thus, next time you add a post:
#+begin_src console #+begin_src console
$ jorge post "Another kind of post" $ jorge post "Another kind of post"
added src/2024-02-23-another-kind-of-post.md added src/2024-02-23-another-kind-of-post.md

View file

@ -9,7 +9,7 @@ index: 3
#+OPTIONS: toc:nil num:nil #+OPTIONS: toc:nil num:nil
#+LANGUAGE: en #+LANGUAGE: en
Now that you have some [[file:jorge-init][default files]] in place, let's see how the website looks. Run ~jorge serve~ on the website directory: Now that you have some [[file:jorge-init][default files]] in place, let's see how the website looks. Run ~jorge serve~ on the project directory:
#+begin_src console #+begin_src console
$ cd myblog $ cd myblog
@ -26,10 +26,10 @@ serving at http://localhost:4001
#+end_src #+end_src
As you can see, jorge reads the files located in your ~src/~ directory and replicates them (with a few changes) at the ~target/~ one. As you can see, jorge reads the files located in your ~src/~ directory and replicates them (with a few changes) at the ~target/~ one.
If you open your browser at http://localhost:4001 you'll see the website we just created. Open your browser at http://localhost:4001 you'll see the website you just created.
If you open ~src/index.html~ in your editor, you should see something roughly matching what you see on the browser: Now open ~src/index.html~ in your editor. You should see something roughly matching what the browser displayed:
#+begin_src html #+begin_src html
{% raw %} {% raw %}
@ -44,9 +44,9 @@ layout: default
{% endraw %} {% endraw %}
#+end_src #+end_src
This file is a [[https://shopify.github.io/][liquid template]] for an HTML file. jorge treats any file inside ~src/~ that begins with this ~---~ header as a template, regardless of its format. This means that: This file is a [[https://shopify.github.io/][liquid template]] for an HTML file. jorge treats any file inside ~src/~ that begins with ~---~ as a template, regardless of its extension. This means that:
1. The header (called front matter by site generators like [[https://jekyllrb.com/docs/front-matter/][Jekyll]] and [[https://gohugo.io/content-management/front-matter/][Hugo]]) will be parsed as YAML and interpreted as post metadata. 1. The contents of the ~---~ header (called front matter by site generators like [[https://jekyllrb.com/docs/front-matter/][Jekyll]] and [[https://gohugo.io/content-management/front-matter/][Hugo]]) will be parsed as YAML and interpreted as page metadata.
2. The rest of the file contents will be rendered according to the liquid template syntax. 2. The rest of the file contents will be rendered according to the liquid template syntax.
3. If it's an org-mode or markdown file, its contents will be converted to their corresponding HTML in the target. 3. If it's an org-mode or markdown file, its contents will be converted to their corresponding HTML in the target.
@ -54,7 +54,7 @@ This file is a [[https://shopify.github.io/][liquid template]] for an HTML file.
In the example above, the ~layout: default~ instructs jorge to embed the index.html rendered output inside the layout defined at ~layouts/default.html~. And the liquid variables expressed by ~{{ site.config.name }}~ and ~{{ site.config.author }}~ will be replaced by the values found at ~config.yml~. In the example above, the ~layout: default~ instructs jorge to embed the index.html rendered output inside the layout defined at ~layouts/default.html~. And the liquid variables expressed by ~{{ site.config.name }}~ and ~{{ site.config.author }}~ will be replaced by the values found at ~config.yml~.
{% endraw %} {% endraw %}
If you change the markup in ~src/index.html~, you should see your browser tab refresh automatically to reflect those changes. Try, for instance, changing the title in the first header: If you update the code in ~src/index.html~, you should see your browser tab refresh automatically to show the changes. Try, for instance, changing the title in the first header:
#+begin_src html #+begin_src html
<h2><a href="#home" class="title" id="home">Home sweet home</a></h2> <h2><a href="#home" class="title" id="home">Home sweet home</a></h2>