srid / neuron

Future-proof note-taking and publishing based on Zettelkasten (superseded by Emanote: https://github.com/srid/emanote)
https://neuron.zettel.page
GNU Affero General Public License v3.0
1.51k stars 149 forks source link

Improve experience of head customization #579

Closed flyinggrizzly closed 3 years ago

flyinggrizzly commented 3 years ago

I currently run small CSS and JS additions to my Neuron sites, which means I'm maintaining a custom head.html file. The changes I make are small (changing video embed behavior in containing elements to be something sane and responsive), but including these few lines of CSS means I then have to replicate all of Neuron's default head behavior, like site meta elements, the syntax, chart, and math styles and scripts, and the inclusion of a link to the sitefeed.

So far I've been fine including the Mermaid, syntax, and math JS plugins manually along with my own includes, but I recently enabled the sitefeed plugin and forgot to manually include the <link /> element to get my feed to show up automatically as well (and I wouldn't care to say how long it took me to realize it was my fault this wasn't working at first because I forgot to add the link 😅).

If it were possible to have a head.html hook point to add user additions, rather than wholesale replacement, it would make this much easier, and streamline maintenance (for site maintainers, not neuron).

Given that the head.html behavior has been around for so long, perhaps this is a different config/behavior? Maybe the presence of a head_additions.html would cause its contents to be appended to the <head> and it is users' responsibility to not create conflicts, or to instead use the head.html to just replace the head if they need to do that?

A head_additions approach would make it much easier to include small style fixes (like ensuring video embeds behave in their responsive containers) than it currently is with needing to replace and replicate the entire head.

srid commented 3 years ago

Only mathjax and syntaxhighlighting are excluded (and it enables you to provide your own alternatives) if there is a head.html. Everything else, including site metadata, breadcrumbs and feed links, are included regardless of there being a head.html.

flyinggrizzly commented 3 years ago

Hmm... maybe I'm goofing this somehow then.

This is the generated <head> when using a custom head.html with one JS link:

<!-- head.html contents -->
<link rel='stylesheet' href="/static/styles/styles.css" />

<!-- generated head -->

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <!--replace-start-0-->
    <!--replace-start-5-->
    <!--replace-start-8-->
    <title>Flying Grizzly Plamo</title>
    <!--replace-end-8-->
    <!--replace-end-5-->
    <!--replace-end-0-->
    <link href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.7/dist/semantic.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather|Libre+Franklin|Roboto+Mono&amp;display=swap"
        rel="stylesheet">
    <!--replace-start-1-->
    <!--replace-start-4-->
    <!--replace-start-7-->
</head>

The generated head if I move head.html over to _head.html is much bigger. Some of which are the syntax and math libs I guess, but importantly here the feed link is missing above, but present below

image

(using screenshot to avoid a giant HTML dump here).

srid commented 3 years ago

I can see that happening with https://www.srid.ca/microblog too, but Chrome's inspector is buggy. It is putting head elements inside <body>

image

On Chrome, despite this, the head elements are functional. For other browsers, I don't know. Regardless, this is a duplicate of #577.

flyinggrizzly commented 3 years ago

Oh weird, yea, I'm now seeing it at the top of the <body>. 👍 will go check out #577.

fieldstrength commented 3 years ago

I would also like the ability to have some way to add to <head> without manually keeping track of the other stuff in there (math and syntax are the parts I use and care about).

I'd be happy to implement it if an approach is agreed upon!

srid commented 3 years ago

@fieldstrength I'm not convinced of the value of this (i.e., head_additions.html UX additional complexity). Math and syntax highlighting can be provided by more than one library. Neuron provides "default" implementation for them (using mathjax and prism.js), which the current behaviour of head.html allows the users to change (to say katex and highlightjs).

That said, in the documentation we should perhaps explicitly include the default head HTML so users can copy paste it:

<script async="" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/themes/prism.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/plugins/autoloader/prism-autoloader.min.js"></script>
arkoort commented 3 years ago

In Firefox my head.html is placed before neuron's own font-family: ... !important, so neuron's fonts overwrite my, and in resulting HTML I see neuron's fonts.

srid commented 3 years ago

@arkoort Does the order matter? Can you point me to the CSS/HTML spec documentation that explains it? Try the following change:

diff --git a/src/Neuron/Frontend/Static/Html.hs b/src/Neuron/Frontend/Static/Html.hs
index 81a58251..3a2c9165 100644
--- a/src/Neuron/Frontend/Static/Html.hs
+++ b/src/Neuron/Frontend/Static/Html.hs
@@ -46,11 +46,11 @@ renderRoutePage routeCfg r val = do
       W.loadingWidget' val blank (const blank) $ \valDyn ->
         dyn_ $
           ffor valDyn $ \v -> do
-            renderHeadHtml $ R.siteDataHeadHtml (R.routeSiteData v r)
             renderManifest $ R.siteDataManifest (R.routeSiteData v r)
             renderStructuredData routeCfg r v
             elAttr "style" ("type" =: "text/css") $ do
               text $ R.siteDataBodyCss (R.routeSiteData v r)
+            renderHeadHtml $ R.siteDataHeadHtml (R.routeSiteData v r)
       pure ()
     el "body" $ do
       () <- case r of
arkoort commented 3 years ago

Sorry, I can't point to the standard. I can argue with two points:

  1. logic; if CSS contains both font-family: A !important and font-family: B !important, only one of them will have effect;
  2. practice; I copied index.html (which is rendered with your fonts, not mine) to i.html and moved my <link rel="stylesheet" type="text/css" href="static/font-families.css"> after your font-families. And this modified i.html displays my fonts.

I don't know, is it standard, or it's only firefox's feature. But I see my fonts in 1.9.10.0's output (and earlier) and I see your fonts in output of 1.9.17.0 and later, up to 1.9.24.1 (I have no versions between 10 and 17 in my nix store).

Sorry once more, it will be too complicated to install haskell compiler to my not very fast notebook, but I don't think this would give another result.


Update: But why you use !important in your CSS? If I understand right, it's me must use it to overwrite your settings. But if you use it too, no one can win.

srid commented 3 years ago

Try 1.9.25.0 @arkoort

arkoort commented 3 years ago

Great. Thank you. :) My fonts are visible now, and my !important overwrites yours.