{"id":13691963,"url":"https://github.com/andrewpillar/jrnl","last_synced_at":"2025-09-25T13:45:09.054Z","repository":{"id":57548663,"uuid":"144759878","full_name":"andrewpillar/jrnl","owner":"andrewpillar","description":"A simple static site generator","archived":false,"fork":false,"pushed_at":"2022-02-26T13:16:08.000Z","size":351,"stargazers_count":27,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-12T17:47:59.443Z","etag":null,"topics":["blogging","go","static-site-generator"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrewpillar.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-14T18:49:37.000Z","updated_at":"2024-03-07T14:34:59.000Z","dependencies_parsed_at":"2022-08-28T11:30:21.095Z","dependency_job_id":null,"html_url":"https://github.com/andrewpillar/jrnl","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fjrnl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fjrnl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fjrnl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fjrnl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewpillar","download_url":"https://codeload.github.com/andrewpillar/jrnl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228567027,"owners_count":17937986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blogging","go","static-site-generator"],"created_at":"2024-08-02T17:00:52.088Z","updated_at":"2025-09-25T13:45:08.692Z","avatar_url":"https://github.com/andrewpillar.png","language":"Go","funding_links":[],"categories":["成品项目","Finished Items"],"sub_categories":["静态网站生成器","Static Site Generator"],"readme":"# jrnl\n\njrnl is a simple static site generator. It takes posts and pages written in\nMarkdown, transforms them to HTML, and copies those HTML files over to a\nremote. Unlike most other static site generators jrnl does not serve the\ncontent it generates.\n\n* [Quick start](#quick-start)\n* [Initializing jrnl](#initializing-jrnl)\n* [Directory structure](#directory-structure)\n* [Pages and posts](#pages-and-posts)\n* [Categories](#categories)\n* [Front matter](#front-matter)\n* [Layouts](#layouts)\n* [Indexing](#indexing)\n* [Themes](#themes)\n* [Remote](#remote)\n* [Publishing](#publishing)\n* [Atom and RSS feeds](#atom-and-rss-feeds)\n\n## Quick start\n\nFirst clone the repository and run the `make.sh` script to build jrnl.\n\n    $ git clone https://github.com/andrewpillar/jrnl\n    $ cd jrnl \u0026\u0026 ./make.sh\n\nThis will produced a `jrnl` binary in the `bin` directory. Copy this file into\nyour `$PATH`,\n\n    $ cp bin/jrnl ~/go/bin\n\nOnce installed you can create a new jrnl by running `jrnl init`.\n\n    $ jrnl init my-blog\n\nthis will initialize everything you need within the `my-blog` directory. If you\ndo not pass an argument to this command then the jrnl will be initialized in the\ncurrent directory.\n\nWe can now change into the new directory and start creating posts with the\n`jrnl post` command.\n\n    $ jrnl post \"Introducing jrnl\"\n\nthis will cause jrnl to drop you into a text editor, as specified via `$EDITOR`\nfor editing the newly created post. You will notice at the top of the post is a\nblock of YAML with a handful of attributes. This is called front matter, and\ncontains meta-data about the post. For now let's set the `layout` attribute to\n`post`, and write up the post's content.\n\n    ---\n    title: Introducing jrnl\n    layout: post\n    createdAt: 2001-01-02T15:04\n    updatedAt: 2001-01-02T15:04\n    ---\n    jrnl is a simple static site generator.\n\nNow that we have written up our post the next thing we need to do is created\na layout for our post. Above we specified the layout for our post via the\n`layout` property in the front matter. Now we need to create that layout file\nfor jrnl to use during publishing. All layout files in jrnl are stored in the\n`_layouts` directory. So let's create a layout file, here's what one could look\nlike:\n\n    \u003c!DOCTYPE HTML\u003e\n    \u003chtml lang=\"en\"\u003e\n        \u003chead\u003e\n            \u003cmeta charset=\"utf-8\"\u003e\n            \u003ctitle\u003e{{.Site.Title}}\u003c/title\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e\n            \u003ch1\u003e{{.Post.Title}}\u003c/h1\u003e\n            \u003cdiv\u003e{{.Post.Body}}\u003c/div\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n\nNothing too specield here, just some basic HTML. Layout files in jrnl utilize\nGo's [text/template](https://golang.org/pkg/text/template) library for\ntemplating. As you can see we are placing the post's title and body into the\nHTML.\n\nSo we have a post and a layout file. Next let's set a title for our jrnl. We\ncan do this by running `jrnl config` and by specifying the `site.title` key.\n\n    $ jrnl config site.title \"My Blog\"\n\nNow, before we can publish our jrnl we need to set a remot. A remote can either\nbe a local filesystem path, or a remote SCP URL for copying the HTML files to.\nTo keep things simple lets just use a local filesystem path for now.\n\n    $ jrnl config site.remote /tmp/blog-remote\n    $ jrnl publish\n\nIf we peform an `ls` on the `/tmp/blog-remote` path we specified, we should see\nthe directory populated with some files generated from jrnl.\n\n    $ ls /tmp/blog-remote\n    2006 assets\n\nAnd there is our site. Not much right now, just and empty `assets` directory and\na path pointing to our published post which we can now view in a browser.\n\n    $ firefox 2006/01/02/introducing-jrnl/index.html\n\n## Initializing jrnl\n\njrnl can be initialized by running `jrnl init`. If this command is provided an\nargument then jrnl will be initialized in the given directory. Otherwise jrnl is\ninitialized in the current directory.\n\n    $ jrnl init my-blog\n\n## Directory structure\n\nA jrnl is structured like so,\n\n    ├── _data\n    ├── _layouts\n    ├── _pages\n    ├── _posts\n    ├── _site\n    |   └── assets\n    ├── _themes\n    └── jrnl.toml\n\n* `_data` - Stores binary data about the pages and posts.\n* `_layouts` - Stores templates used for generating pages and posts.\n* `_pages` - Stores the Markdown files for the pages.\n* `_posts` - Stores the Markdown files for the posts.\n* `_site` - Stores the final generated HTML files.\n* `_site/assets` - Stores the static assets for the site, such as CSS, JS, and\nany images.\n* `_themes` - Stores the jrnl themes.\n* `jrnl.toml` - The configuration file for jrnl.\n\n## Pages and posts\n\njrnl has two types of content, pages and posts. A page is a simple content\ntype, it is made up of a title, a layout, and a body. Pages are created with\nthe `jrnl page` comman. This takes the title of the page to be created as its\nonly argument.\n\n    $ jrnl page About\n\nPosts are similar to pages in how they are created. The main different is that\nposts can be categorized, and contain meta-data about when that post was\ncreated, and updated.\n\n    $ jrnl post \"Introducing jrnl\"\n\nWhenever a page or post is created, or edited jrnl will open up the source\nMarkdown f ile in the editor that you have set via the `$EDITOR` environment\nvariable. Upon creation of a new page or post the source Markdown file will be\npre-populated with some [front matter](#front-matter) whcih will store some\nmeta-data about the page or post.\n\nAll of the posts and pages that have been created can be viewed with the\n`jrnl ls` command.\n\n    $ jrnl ls\n    about\n    introducing-jrnl\n\nThese IDs can be passed to `jrnl edit` or `jrnl rm` for modification or removal\nrespectively.\n\n## Categories\n\njrnl allows for posts to be stored in categories, and sub-categories. To add a\npost to a category simply pass the `-c` flag to the `jrnl post` command,\n\n    $ jrnl post -c \"TV Shows / The Leftovers\" \"Penguin One, Us Zero\"\n\nthis will store the Markdown file in a sub-directory beneath the `_posts`\ndirectory.\n\n    ├── _posts\n    |   └── tv-shows\n    |       └── the-leftovers\n    |           └── penguin-one-us-zero.md\n\nUnder the hood categories are nothing more than additional directories to store\nposts in.\n\n## Front matter\n\nFront matter is a block of YAML that sits at the top of each page or post in the\nMarkdown source file. It contains meta-data about the pieve of content being\nmodified. The front matter can vary between pages and posts in regards to what\nit strores, but both types of content will have a `title` and `layout` property.\n\n* `title` (both) - The title of the page or post.\n* `layout` (both) - The layout of the page or post.\n* `createdAt` (post) - The time the post was created.\n* `updatedAt` (post) - The time the post was updated.\n\n## Layouts\n\nLayouts are text files that define how a page or post will look once published.\njrnl uses Go's [text/template](https://golang.org/pkg/text/template) library for\ntemplating. When jrnl has been initialized the `_layouts` directory will be\nempty, it will be up to you to create the necessary layout files. Below is an\nexample layout file for a post:\n\n    \u003c!DOCTYPE HTML\u003e\n    \u003chtml lang=\"en\"\u003e\n        \u003chead\u003e\n            \u003cmeta charset=\"utf-8\"\u003e\n            \u003ctitle\u003e{{.Site.Title}}\u003c/title\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e{{.Post.Body}}\u003c/body\u003e\n    \u003c/html\u003e\n\nAll layout files will have access to the `.Site` value. This value allows for\nretrieving the title, authorship, categories, and pages in the jrnl.\n\n    \u003cul\u003e\n        {{range $i, $p := .Site.Pages}}\n            \u003cli\u003e\u003ca href=\"{{$p.Href}}\"\u003e{{$p.Title}}\u003c/a\u003e\u003c/li\u003e\n        {{end}}\n    \u003c/ul\u003e\n    \n    \u003cul\u003e\n        {{range $i, $c := .Site.Categories}}\n            \u003cli\u003e\u003ca href=\"{{$c.Href}}\"\u003e{{$c.Name}}\u003c/a\u003e\u003c/li\u003e\n        {{end}}\n    \u003c/ul\u003e\n\nThe layout used by a page will be passed the `.Page` value, and the layout used\nby a post will be passed the `.Post` value.\n\nYou will also have access to the `partial` function within a layout file. This\nallows you to create re-usable parts of a layout. The partial function takes\nthe name of the layout file to include followed by the data to passthrough.\n\n    {{partial \"categories\" .Site.Categories}}\n\n## Indexing\n\njrnl can generate an `index.html` file at the root of the `_site` directory\nthat will list all of the posts created. One can also be created for each\ncategory that will list each of the category's posts.\n\nTo have these index files created, simply specify an index layout file to use\nin the `_layouts` directory. Use `index` for the `_site/index.html` file, and\n`category-index` for a category specific `index.html` file.\n\n## Themes\n\nThemes in jrnl are just a tarball of the `_layouts` directory, and the\n`_site/assets` directory. The current theme being used is stored in the\n`jrnl.toml` configuration file. You can check to see if a theme is in use by\nrunning `jrnl theme`.\n\n    $ jrnl theme\n\nCreating or saving a theme is done with `jrnl theme save`. If no argument is\ngiven then it will overwrite the current theme in use, otherwise it will create\na new theme with the given name.\n\nThemes can be set by running the `jrnl theme use` command, and passing it the\nname of the theme you wish to use.\n\nAll available themes can be listed with `jrnl theme ls`, and themes can be\ndeleted with `jrnl theme rm`.\n\n## Remote\n\nEach jrnl has a remote. A remote is where the contents of the `_site` directory\nis copied to. This can either be a location on disk, or an SCP URL. The remote\ncan be set via `jrnl config site.remote` and is stored in the `jrnl.toml` file.\n\n    $ jrnl config site.remote me@andrewpillar.com:/var/www/andrewpillar.com\n\n## Publishing\n\nTo publish a jrnl simply run `jrnl publish`. This will transform all of the\nmodified Markdown pages and posts into HTML, and generate the necessary\n`index.html` files before copying them to the remote.\n\n    $ jrnl publish\n\nDrafts can be published by setting the `-d` flag. This will only produce the\nHTML files instead of copying them over.\n\nEach page and post that is published will be written to the `_data/hash` file.\nThis is used to determine which pages and posts should be copied to the remote\nbased on whether they have been modified.\n\n## Atom and RSS feeds\n\nAtom and RSS feeds can be generated by passing the `-a` and `-r` flags to the\n`jrnl publish` command. Each of these flags will take a path to the file where\nyou would like the feed to be written,\n\n    $ jrnl publish -a _site/atom.xml -r _site/rss.xml\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewpillar%2Fjrnl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewpillar%2Fjrnl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewpillar%2Fjrnl/lists"}