Giter VIP home page Giter VIP logo

quickblog's Introduction

Quickblog

The blog code powering my blog.

See API.md on how to use this.

Compatible with babashka and Clojure.

Includes hot-reload. See it in action here.

Blogs using quickblog

Instances of quickblog can be seen here:

Articles about quickblog

Feel free to PR yours.

Quickstart

Babashka

quickblog is meant to be used as a library from your Babashka project. The easiest way to use it is to add a task to your project's bb.edn.

This example assumes a basic bb.edn like this:

{:deps {io.github.borkdude/quickblog
        #_"You use the newest SHA here:"
        {:git/sha "389833f393e04d4176ef3eaa5047fa307a5ff2e8"}}
 :tasks
 {:requires ([quickblog.cli :as cli])
  :init (def opts {:blog-title "REPL adventures"
                   :blog-description "A blog about blogging quickly"})
  quickblog {:doc "Start blogging quickly! Run `bb quickblog help` for details."
             :task (cli/dispatch opts)}}}

To create a new blog post:

$ bb quickblog new --file "test.md" --title "Test"

To start an HTTP server and re-render on changes to files:

$ bb quickblog watch

Clojure

Quickblog can be used in Clojure with the exact same API as the bb tasks. Default options can be configured in :exec-args.

:quickblog
{:deps {io.github.borkdude/quickblog
        #_"You use the newest SHA here:"
        {:git/sha "389833f393e04d4176ef3eaa5047fa307a5ff2e8"}
        org.babashka/cli {:mvn/version "0.3.35"}}
 :main-opts ["-m" "babashka.cli.exec" "quickblog.cli" "run"]
 :exec-args {:blog-title "REPL adventures"
             :blog-description "A blog about blogging quickly"}}

After configuring this, you can call:

$ clj -M:quickblog new --file "test.md" --title "Test"

To watch:

$ clj -M:quickblog watch

etc.

Features

Markdown

Posts are written in Markdown and processed by markdown-clj, which implements the MultiMarkdown flavour of Markdown.

Metadata

Post metadata is specified in the post file using MultiMarkdown's metadata tags. quickblog expects three pieces of metadata in each post:

  • Title - the title of the post
  • Date - the date when the post will be published (used for sorting posts, so ISO 8601 datetimes are recommended)
  • Tags - a comma-separated list of tags

quickblog new requires the title to be specified and provides sensible defaults for Date and Tags.

You can add any metadata fields to posts that you want. See the Social sharing section below for some useful suggestions.

Note: metadata may not include newlines!

favicon

NOTE: when enabling or disabling a favicon, you must do a full re-render of your site by running bb quickblog clean and then your bb quickblog render command.

To enable a favicon, add :favicon true to your quickblog opts (or use --favicon true on the command line). quickblog will render the contents of templates/favicon.html and insert them in the head of your pages.

You will also need to create the favicon assets themselves. The easiest way is to use a favicon generator such as RealFaviconGenerator, which will let you upload an image and then gives you a ZIP file containing all of the assets, which you should unzip into your :assets-dir (which defaults to assets).

You can read an example of how to prepare a favicon here: https://jmglov.net/blog/2022-07-05-hacking-blog-favicon.html

quickblog's default template expects the favicon files to be named as follows:

  • android-chrome-192x192.png
  • android-chrome-512x512.png
  • apple-touch-icon.png
  • browserconfig.xml
  • favicon-16x16.png
  • favicon-32x32.png
  • favicon.ico
  • mstile-150x150.png
  • safari-pinned-tab.svg
  • site.webmanifest

If any of these files are not present in your :assets-dir, a quickblog default will be copied there from resources/quickblog/assets.

Social sharing

Social media sites such as Facebook, Twitter, LinkedIn, etc. display neat little preview cards when you share a link. These cards are populated from certain <meta> tags (as described in "How to add a social media share card to any website", by Michelle Mannering) and typically contain a title, description / summary, and preview image.

quickblog's base template adds meta tags for the page title for all pages and descriptions for the following pages:

  • Index: {{blog-description}}
  • Archive: Archive - {{blog-description}}
  • Tags: Tags - {{blog-description}}
  • Tag pages: Posts tagged "{{tag}}" - {{blog-description}}

If you specify a :blog-image URL option, a preview image will be added to the index, archive, tags, and tag pages. The URL should point to an image; for best results, the image should be 1200x630 and maximum 5MB in size. It may either be an absolute URL or a URL relative to :blog-root.

For post pages, meta tags will be populated from Title, Description, Image, Image-Alt, and Twitter-Handle metadata in the document.

If not specified, Twitter-Handle defaults to the :twitter-handle option to quickblog. The idea is that the :twitter-handle option is the Twitter handle of the person owning the blog, who is likely also the author of most posts on the blog. If there's a guest post, however, the guest blogger can add their Twitter handle instead.

For example, a post could look like this:

Title: Sharing is caring
Date: 2022-08-16
Tags: demo
Image: assets/2022-08-16-sharing-preview.png
Image-Alt: A leather-bound notebook lies open on a writing desk
Twitter-Handle: quickblog
Description: quickblog now creates nifty social media sharing cards / previews. Read all about how this works and how you can maximise engagement with your posts!

You may have already heard the good news: quickblog is more social than ever!
...

The value of the Image field is either an absolute URL or a URL relative to :blog-root. As noted above, images should be 1200x630 and maximum 5MB in size for best results.

Image-Alt provides alt text for the preview image, which is extremely important for making pages accessible to people using screen readers. I highly recommend reading resources like "Write good Alt Text to describe images" to learn more.

Resources for understanding and testing social sharing:

Linking to previous and next posts

If you set the :link-prev-next-posts option to true, quickblog adds prev and next metadata to each post (where prev is the previous post and next is the next post in date order, oldest to newest). You can make use of these by adding something similar to this to your post.html template:

{% if any prev next %}
  <div class="post-prev-next">
{% if prev %}
    <div><a href="{{prev.file|replace:.md:.html}}">{{prev.title}}</a></div>
{% endif %}
{% if next %}
    <div><a href="{{next.file|replace:.md:.html}}">{{next.title}}</a></div>
{% endif %}
  </div>
{% endif %}

Templates

quickblog uses the following templates in site generation:

  • base.html - All pages. Page body is provided by the {{body}} variable.
  • post.html - Post bodies.
  • style.css - Styles for all pages.
  • favicon.html - If :favicon true, used to include favicon in the <head> of all pages.
  • tags.html - Tag overview page.
  • post-links.html - Used to render lists of blog posts in the archive and each page corresponding to a single tag.
  • index.html - Index page. Posts containing the marker comment <!-- end-of-preview --> are included on the index page up until the first occurrence of that comment.

quickblog looks for these templates in your :templates-dir, and if it doesn't find them, will copy a default template into that directory. It is recommended to keep :templates-dir under revision control so that you can modify the templates to suit your needs and preferences.

The default templates are occasionally modified to support new features. When this happens, you won't be able to use the new feature without making the same modifications to your local templates. The easiest way to do this is to run bb quickblog refresh-templates.

New posts

In addition to the HTML templates above, you can also use a template for generating new posts. Assuming you have a template new-post.md that looks like this:

Title: {{title}}
Date: {{date}}
Tags: {{tags|join:\",\"}}
Image: {% if image %}{{image}}{% else %}{{assets-dir}}/{{file|replace:.md:}}-preview.png{% endif %}
Image-Alt: {{image-alt|default:FIXME}}
Discuss: {{discuss|default:FIXME}}
{% if preview %}Preview: true\n{% endif %}
Write a blog post here!

you can generate a new post like this:

$ bb quickblog new --file "test.md" --title "Test" --preview --template-file new-post.md

And the resulting posts/test.md will look like this:

Title: Test
Date: 2024-01-19
Tags: clojure
Image: assets/test-preview.png
Image-Alt: FIXME
Discuss: FIXME
Preview: true

Write a blog post here!

It is not recommended to keep your new post template in your templates-dir, as any changes to the new post template will cause all of your existing posts to be re-rendered, which is probably not what you want!

Breaking changes

posts.edn removed

quickblog now keeps metadata for each blog post in the post file itself. It used to use a posts.edn file for this purpose. If you are upgrading from a version that used posts.edn, you should run bb quickblog migrate and then remove the posts.edn file.

Improvements

Feel free to send PRs for improvements.

My wishlist:

  • There might be a few things hardcoded that still need to be made configurable.
  • Upstream improvements to markdown-clj

quickblog's People

Contributors

anderseknert avatar berkeleytrue avatar borkdude avatar elken avatar formsandlines avatar jmglov avatar kiramclean avatar ljpengelen avatar matkurianski avatar rads avatar unwarysage avatar xicubed avatar zoren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

quickblog's Issues

Add social media sharing preview

At the moment, sharing a quickblog URL on Facebook, Twitter, LinkedIn, etc results in just the URL. It would be nice if the link was rendered as a "sharing card" with a title, post summary, and preview image. The feature could work like this:

Social sharing

Social media sites such as Facebook, Twitter, LinkedIn, etc. display neat little
preview cards when you share a link. These cards are populated from certain
<meta> tags (as described in "How to add a social media share card to any
website
",
by Michelle Mannering) and typically contain a title, description / summary, and
preview image.

By default, quickblog adds tags for the page title for all pages and
descriptions for the following pages:

  • Index: {{blog-description}}
  • Archive: Archive - {{blog-description}}
  • Tags: Tags - {{blog-description}}
  • Tag pages: Posts tagged "{{tag}}" - {{blog-description}}

If you specify a :blog-image URL option, a preview image will be added to the
index, archive, tags, and tag pages. The URL should point to an image that is
1200x630 and maximum 5MB in size. It may either be an absolute URL or a URL
relative to :blog-root.

For post pages, meta tags will be populated from Description and Image
metadata in the document. For example, a post could look like this:

Title: Sharing is caring
Date: 2022-08-16
Tags: demo
Description: quickblog now creates nifty social media sharing cards / previews. Read all about how this works and how you can maximise engagement with your posts!
Image: assets/2022-08-16-sharing-preview.png

You may have already heard the good news: quickblog is more social than ever!
...

The value of the Image field is either an absolute URL or a URL relative to
:blog-root. As noted above, images should be 1200x630 and maximum 5MB in size
for best results.

Resources for understanding and testing social sharing:

NPE from `bb quickblog watch` on new blog

Steps to reproduce:

  1. Create a new directory such as qb-test
  2. Add a bb.edn with the following contents:
    {:deps {io.github.borkdude/quickblog
            #_"You use the newest SHA here:"
            {:git/sha "8f5898ee911101a96295f59bb5ffc7517757bc8f"}}
     :tasks
     {:requires ([quickblog.cli :as cli])
      :init (def opts {:blog-title "REPL adventures"
                       :blog-description "A blog about blogging quickly"})
      quickblog {:doc "Start blogging quickly! Run `bb quickblog help` for details."
                 :task (cli/dispatch opts)}}}
  3. Run bb quickblog new --file test1.md --title "This is a test for echo..."
  4. Run bb quickblog watch

You'll see an exception like the following:

#error {
 :cause "java.lang.Integer cannot be cast to clojure.lang.Associative"
 :via
 [{:type java.lang.ClassCastException
   :message "java.lang.Integer cannot be cast to clojure.lang.Associative"
   :at [clojure.lang.RT assoc "RT.java" 827]}]
 :trace
 [[clojure.lang.RT assoc "RT.java" 827]
  [clojure.core$assoc__5481 invokeStatic "core.clj" 193]
  [clojure.core$update invokeStatic "core.clj" 6231]
  [clojure.core$update invoke "core.clj" 6223]
  [sci.lang.Var invoke "lang.cljc" 184]
  [sci.impl.analyzer$return_call$reify__4845 eval "analyzer.cljc" 1350]
  [sci.impl.analyzer$return_binding_call$reify__4716 eval "analyzer.cljc" 1268]
  [sci.impl.fns$fun$arity_1__3549 invoke "fns.cljc" 106]
  [babashka.pods.impl$processor invokeStatic "impl.clj" 234]
  [babashka.pods.sci$load_pod$fn__27089 invoke "sci.clj" 122]
  [sci.impl.vars$binding_conveyor_fn$fn__425 invoke "vars.cljc" 133]
  [clojure.core$binding_conveyor_fn$fn__5823 invoke "core.clj" 2047]
  [clojure.lang.AFn call "AFn.java" 18]
  [java.util.concurrent.FutureTask run "FutureTask.java" 264]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1128]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 628]
  [java.lang.Thread run "Thread.java" 829]
  [com.oracle.svm.core.thread.PlatformThreads threadStartRoutine "PlatformThreads.java" 775]
  [com.oracle.svm.core.posix.thread.PosixPlatformThreads pthreadStartRoutine "PosixPlatformThreads.java" 203]]}

Can't run a single test with bb test --only

I should be able to run a single test using --only, like so:

bb test --only quickblog.api-test/migrate

However, bb test ignores the --only arg and happily runs all the tests, thus making me sad:

$ bb test --only quickblog.api-test/migrate

Running tests in #{"test"}

Testing quickblog.api-test

Ran 5 tests containing 138 assertions.
0 failures, 0 errors.

I would expect a single test with 1 assertion to run, given quickblog.api-test/migrate:

(deftest migrate
  (with-dirs [posts-dir]
    (let [posts-edn (write-test-file posts-dir "posts.edn"
                                     {:file "test.md"
                                      :title "Test post"
                                      :date "2022-01-02"
                                      :tags #{"clojure"}})
          post-file (write-test-file posts-dir "test.md"
                                     "Write a blog post here!")
          to-lines #(-> % str/split-lines set)]
      (api/migrate {:posts-dir posts-dir
                    :posts-file posts-edn})
      (is (= (to-lines "Title: Test post\nDate: 2022-01-02\nTags: clojure\n\nWrite a blog post here!")
             (to-lines (slurp post-file)))))))

Support using a template for `quickblog new`

When creating a new post, I would like to have it look something like this:

Title: Test
Date: 2024-01-19
Tags: clojure
Image: assets/test-preview.png
Image-Alt: FIXME
Discuss: FIXME
Preview: true

Write a blog post here!

Instead of the boring quickblog default:

Title: Test
Date: 2024-01-19
Tags: clojure

Write a blog post here!

If I could but say something like this:

bb quickblog new --file "test.md" --title "Test" --preview --template-file new-post.md

assuming I have a new-post.md template that looks like this:

Title: {{title}}
Date: {{date}}
Tags: {{tags|join:\",\"}}
Image: {% if image %}{{image}}{% else %}{{assets-dir}}/{{file|replace:.md:}}-preview.png{% endif %}
Image-Alt: {{image-alt|default:FIXME}}
Discuss: {{discuss|default:FIXME}}
{% if preview %}Preview: true\n{% endif %}
Write a blog post here!

I would truly be the happiest of men!

Post with missing pre-template.html file in cache not detected as stale

When attempting to force re-render of a single post by deleting the corresponding pre-template.html file from the cache, the post is not correctly detected as stale, resulting in a file error when trying to load the post from the cache:

: jmglov.net; rm .cache/2022-06-15-summertime.md.pre-template.html                                                                      
                                                                                                                                        
: jmglov.net; bb quickblog render                                                                                                       
Reading post from cache: 2022-06-15-summertime.md                                                                                       
----- Error --------------------------------------------------------------------                                                        
Type:     java.io.FileNotFoundException                                                                                                 
Message:  .cache/2022-06-15-summertime.md.pre-template.html (No such file or directory)                                                 
Location: /home/jmglov/Documents/code/clojure/quickblog/src/quickblog/internal.clj:162:7                                                
                                                                                                                                        
----- Context ------------------------------------------------------------------                                                        
158: (defn read-cached-post [{:keys [cache-dir]} file]                                                                                  
159:   (let [cached-file (fs/file cache-dir (cache-file file))]                                                                         
160:     (delay                                                                                                                         
161:       (println "Reading post from cache:" (str file))                                                                              
162:       (slurp cached-file))))                                                                                                       
           ^--- .cache/2022-06-15-summertime.md.pre-template.html (No such file or directory)                                           
163:                                                                                                                                    
164: (defn load-post [{:keys [cache-dir default-metadata                                                                                
165:                          force-render rendering-system-files]                                                                      
166:                   :as opts}                                                                                                        
167:                  path]                                                                                                             

More control over index, tags, and archive

I'd like some more control over the content and styling of the index page, the archive, and the pages for tags.

I'm working on #60, which uses templates instead of Hiccup to create these pages.

Request: make discussion optional

It's pretty easy to remove the discussion parts on the index and post templates but would be nice to make it easy to just not use discussion if you don't want it.

Overiding command-specific opt doesn't work

For example, given a function with the following spec:

(defn process-file
  {:org.babashka/cli
   {:spec
    {:media-file
     {:desc "Media file to transribe"
      :ref "<file>"
      :require true}}}}
  [{:keys [media-file] :as opts}]
  media-file)

Calling cli/dispatch like so would result in process-file returning nil:

(cli/dispatch {:media-file "some-file.mp4"})

Cannot create a blog post without tags

When I try to create a new blog post using the example mentioned in the “Quickstart” section of the README bb quickblog new --file "test.md" --title "Test", I get an error Missing required argument --tags. When I just add --tags without an argument, it automatically creates a tag true which is added to my blog post.

I used quickblog with the SHA of the latest commit, which is d17149f9dc5ed6ec2d366759f4190ec78f6ca337.

Add `refresh-templates` task

When the default templates in resources/templates are modified, quickblog users need to manually copy them into their blog's templates directory. We should add a refresh-templates task that does this automatically.

This will require moving the default templates from resources/templates to resources/templates/default so they don't collide with templates/ on the user's resource path.

Document opts

There are a lot of config options, mostly optional with sensible defaults. I'd like to document them so that you can run bb help and get something like this:

quickblog can be configured by passing an options map to API functions:

:blog-title        title of the blog; default: "quickblog"
:blog-author       blog author's name; default: "Quick Blogger"
:blog-description  description of the blog; default: "A blog about blogging quickly"
:blog-root         link to the root of the blog; default: "https://github.com/borkdude/quickblog"
:about-link        [optional] link to an about the author page
:discuss-link      [optional] link to discussion forum for the blog
:twitter-handle    [optional] Twitter handle to link to
...

Bug: only modified posts added to Planet Clojure feed

spit-feeds makes a list of all of the modified posts that are tagged "clojure" or "clojurescript" and if it's not empty, writes the Planet Clojure feed. Unfortunately, it doesn't write all of the posts to the feed, only the modified ones. This results in unmodified Clojure posts disappearing from the feed.

Add tests

quickblog really needs some tests.

Search field

Support CSS for backtick(`) in markdown

It can keep/customize the style of backtick in markdown after rendering into HTML.

--> I found out the rendered HTML has a code tag by markdown-clj and the template CSS has also tags for easy changes.

Link to blog posts with `[[post-id]]` links

When linking to other posts on the blog, you need to write out the links like this:

[Title of Test 2](test2.html)

It would be more convenient to be able to simply write [[test2]] (like a MediaWiki link) and have it expand to:

[Title of Test 2](test2.html)

Allow omitting .html suffix from rendered page links

I prefer my links without it, so a configuration option like :page-suffix, where the default is ".html" to keep with current behavior, but where one may set a blank string to have it removed, would be a good addition.

Add `:heading-anchors true` to the markdown compilation

As noted here:

Specifying :heading-anchors will create anchors for the heading tags, eg:

(markdown/md-to-html-string "###foo bar BAz" :heading-anchors true)
<h3 id=\"foo&#95;bar&#95;baz\">foo bar BAz</h3>

Which allows for headings to be navigated to and, with some javascript, linked to (if desired this can also be added to the linked PR)

`bb quickblog new --tags` is broken

When specifying a list of tags using the --tags argument to bb quickblog new, you get a list of the characters in the tag strings:

: jmglov.net; bb quickblog new --title "Test post" --file test.md --tags 'foo,bar'

: jmglov.net; cat posts/test.md 
Title: Test post
Date: 2022-12-11
Tags: f,o,o,,,b,a,r

Write a blog post here!

Exception from `bb quickblog watch` on new blog

Steps to reproduce:

  1. Create a new directory such as qb-test
  2. Add a bb.edn with the following contents:
    {:deps {io.github.borkdude/quickblog
            #_"You use the newest SHA here:"
            {:git/sha "8f5898ee911101a96295f59bb5ffc7517757bc8f"}}
     :tasks
     {:requires ([quickblog.cli :as cli])
      :init (def opts {:blog-title "REPL adventures"
                       :blog-description "A blog about blogging quickly"})
      quickblog {:doc "Start blogging quickly! Run `bb quickblog help` for details."
                 :task (cli/dispatch opts)}}}
  3. Run bb quickblog watch

You'll see an exception like the following:

----- Error --------------------------------------------------------------------
Type:     java.lang.Exception
Message:  Visiting /home/jmglov/Documents/code/clojure/qb-test/posts failed

Enable use of metadata in templates

I want to add a number of posts to my blog that I wrote for a previous employer. To prevent search engines from classifying my blog as spam, I want to refer to the original versions of these posts using HTML link tags with the attribute rel=canonical.

As I see it, a straightforward way to achieve this would be adding something like Canonical-url: https://www.example.org/post/1234 to the metadata of relevant posts and using the value of this field in the 'base.html` template.

Instead of exposing just one specific field in the metadata, I created a PR that exposes all available fields: #55.

Move metadata to post files

Keeping the post metadata in posts.edn requires you to make changes in two places when adding a new post, and also makes caching slightly more complex. As MultiMarkdown (the markdown flavour implemented by markdown-clj) has support for including metadata at the beginning of a file, we can move the metadata to the posts files themselves and not require posts.edn anymore.

Replace workaround that copies metadata from `api/serve`

https://github.com/borkdude/quickblog/blob/main/src/quickblog/cli.clj contains the following comment:

;; api/serve returns immediately, so we'll wait on a promise
;; after calling it to prevent the process from exiting. In
;; order for the help text to work, we need to grab the metadata
;; from the api/serve var and attach it to our fn. This is
;; admittedly gross and I should be scolded severely for this
;; nonsense. Send a pull request along the scolding, if you
;; don't mind!

#57 proposes an alternative implementation of serve that doesn't require the copying of metadata from serve to the nameless function that blocks.

Literal <code> block drops white-space

Markdown input:

<pre>
<code>
(def newline-should-start
    :here)
</code>
</pre>

Expected output (should work the same as a markdown code-block literal):
"<pre><code>&#40;def newline-should-start\n :here&#41;</code></pre>"

Actual output:
"<pre> <code> (def newline-should-start :here) </code> </pre>"

Default style.css isn't copied into templates dir when it doesn't exist

If templates/style.css doesn't exist, it should be copied from resources/quickblog/templates/style.css; however this currently doesn't work:

Writing default resource: templates/style.css
----- Error --------------------------------------------------------------------
Type:     java.lang.ClassCastException
Message:  java.io.File cannot be cast to java.lang.String

I have a fix for this and will open a PR directly.

feat: add "language-xxx" to <pre><code> elements for prism syntax highlighting.

Prism forces you to use the correct element for marking up code: <code>. On its own for inline code, or inside a <pre> for blocks of code. In addition, the language is defined through the way recommended in the HTML5 draft: through a language-xxxx class.

Prism requires "laguage-xxx" class in both code and pre blocks.

I've already opened an issue in yogthos/markdown-clj#199 to add an option to add classes to pre tags.

Default tag `clojure` added automatically without ability to change or have no tags at all

In the latest commit, while the --tags option for quickblog new is not required anymore, the default tag clojure is still added automatically. I would prefer to be able to specify a different default tag or none at all, if desired.

@borkdude suggested introducing a :default-tags option, which I think is a good idea. I guess setting this to an empty vector could get rid of the Tags: … field in .md files entirely or just leave it empty.

Render after watch includes `live.js` reloader

If I do:

bb quickblog watch

make some changes in a post and then close the watcher it renders as expected with a live.js script tag.
If I then do:

bb quickblog render

the generated HTML includes live.js, I would have expected it not to.
Doing bb quickblog clean before render works around this problem.

Support favicon

quickblog templates should include a favicon (the little image that appears in the browser tab title). This could be achieved by adding a variable to templates/base.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{{title}}</title>
    ...
    {% if favicon %}
    {{favicon | safe}}
    {% endif %}
  </head>

When the user includes a :favicon-template key in the quickblog opts, quickblog will set the value of the :favicon variable to the result of rendering the template.

quickblog should also ship with a default templates/favicon.html:

    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="manifest" href="/site.webmanifest">
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
    <meta name="msapplication-TileColor" content="#da532c">
    <meta name="theme-color" content="#ffffff">

Instructions on adding the favicon assets should be added to the README.

Standard markdown syntax for tables can lead to empty tables in HTML

I noticed that markdown like the following will be translated to an empty table:

| Header A | Header B |
| -------- | -------- |
| 1        | 2        |

The HTML tags are present in the output, but the content isn't:

<table><thead><tr></tr></thead><tbody><tr></tr><tr></tr></tbody></table>

This has to do with what's happening in pre-process-md:

(defn pre-process-markdown [markdown]
  (-> markdown
      (str/replace #"--" (fn [_] "$$NDASH$$"))
      (str/replace #"\[[^\]]+\n"
                   (fn [match]
                     (str/replace match "\n" "$$RET$$")))))

If I use the following markup, the table ends up in the output just fine:

| Header A | Header B |
| - | - |
| 1        | 2        |

I'm happy to look into this, but I'm not sure what the intention of pre-process-markdown is.

Preview post added to index

Posts with

Preview: true

in their metadata are not meant to be published, and therefore should be omitted from the following places:

  • index.html
  • archive.html
  • tags/*.html
  • RSS feeds (atom.xml and planetclojure.xml)

Preview posts are added to index.html.

Repro steps

bb quickblog new --file test-preview.md --title 'preview test'
vim posts/test-preview.md  # add Preview: true
bb quickblog render                                    
grep -rn test-preview public/ | cut -d ':' -f 1 | sort | uniq
# =>
# public/index.html
# public/test-preview.html

Add dedicated template for contents of index

Currently, post.html is used to render the posts on the index page.

If we move the index content to a dedicated template users could eg:

  • add some static content before the list
  • render the post lists with some sort of spacer in between for improved separation
  • display a shortened version of the post on the index page (eg body | remove-tags | abbreviate:100)

Multiple posts on same date have arbitrary order.

I ran into a situation where I had several blog posts on one day, with titles like "Foo, Part 1" and "Foo, Part 2".

They appeared in jumbled order, and so I made this issue and accompanying PR to create an ordering of posts, sorting by date (descending), post title, and then file name.

As the last is definitely unique, this should ensure there's an unambiguous ordering of posts in a blog.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.