Markbind: Clarify the requirements of layouts

Created on 2 Aug 2020  ยท  18Comments  ยท  Source: MarkBind/markbind

Currently, layouts (header, footer, page (expressive) layouts, navigation) cannot:

  • [ ] use include features (<panel src="..."> & <include>) (with the exception of expressive layouts)
  • [ ] use <variable> / <import> correctly (variables are not erased, imports do not work with live reload)
  • [ ] use plugin elements correctly (as preRender is not executed for layouts)
  • โ”

Is this by design?

If not, a very large refactor may be due to fix the processing order

question

All 18 comments

Further requirements:

layouts are not _independent_ of the page content

  • [ ] layout headings are indexed together with the page.
  • [ ] layout footnotes may leak into the page. (e.g. you can define a footnote in the footer accidentally and have it override the one in the page) (or vice versa)

layout generation should be completely independent to achieve all of the above:

  • during site generation, we only ever generate a layout once, and subject it to the processes of page generation (allowing includes / plugins / etc), then chuck it into the page
  • rather than chucking it into the page midway (which breaks features listed above), and generating it together with the page everytime (which causes side effects listed above)
  • [ ] relative links sometimes also don't work depending on where the page is located and the link points too.

@damithc @marvinchin any idea if these were intentional design choices? (specifically the second comment and the use of <include>s) The rest should be bugs

It's common to take the _path of least resistance_ during the first implementation of a feature as the first version doesn't need to support all bells and whistles. Could be the case here too.

@crphang any thoughts?

It's common to take the path of least resistance during the first implementation of a feature as the first version doesn't need to support all bells and whistles.

any thoughts on the feature reductions though? namely anything that makes use of:

  • layout headings being indexed with the page
  • footnotes - layouts leaking - define footnotes in layouts then use it in the page

    • this looks useful, but can be done via <include>

Sorry missed the ping ๐Ÿ˜…

I believe certain layouts such as footer, header, pagenav were designed to be simple at that point since it takes up fixed portion of the page. Expressive layouts on the other hand was designed to support all functionalities that a normal page could since it takes up the core portion of a markbind generated page.

It's common to take the path of least resistance during the first implementation of a feature as the first version doesn't need to support all bells and whistles.

any thoughts on the feature reductions though? namely anything that makes use of:

  • layout headings being indexed with the page
  • footnotes - layouts leaking - define footnotes in layouts then use it in the page

    • this looks useful, but can be done via <include>

Could you elaborate more? For reducing features, there might be a risk of backward compatibility. If that is necessary, might have to release it as part of a major version update and consider the product as a whole.

Could you elaborate more? For reducing features, there might be a risk of backward compatibility. If that is necessary, might have to release it as part of a major version update and consider the product as a whole.

yes definitely, I'm not sure if these are actually intended (hence risk of backward compatibility) or accidental (no risk) though

  1. layout headings being indexed with the page

e.g.

page.md
# my heading

{{ MAIN_CONTENT_BODY }}

then some_page.md, which uses page.md as the page layout, the my heading search result shows up under it.
this goes for all pages which also use it

  1. footnotes
page.md

[^1]: lorem ipsum

{{ MAIN_CONTENT_BODY }}
some_page.md

I can use the footnote in page.md like so [^1]

this looks useful, but can be done via <include src="a file that contains only footnote definitions">
Hence expressive layouts (or any other layout) should be used to append top and bottom _view_ content to the page only, and not actually affect the generation of the page

actually, if I recall there was a comment about migrating entirely to expressive layouts, deprecating headers/site-navs/footers.
we should probably go with that instead. (v3 probably, adding a deprecation path first)

still we need to sort out the desired behaviour, should:

  • expressive layouts headings be indexed with the page?
  • footnotes in expressive layouts affect those in the page?

@damithc @crphang

Although the second seems convenient, my preference is to keep this independent of the page, because it can become difficult to predict / keep track of the expected behaviour for an author
Content reuse (in this case footnote definitions) can also still be achieved via <include> / {% include %}

Indexing headings with the page seems redundant and causes a lot of repeated search results

actually, if I recall there was a comment about migrating entirely to expressive layouts, deprecating headers/site-navs/footers.
we should probably go with that instead. (v3 probably, adding a deprecation path first)

still we need to sort out the desired behaviour, should:

  • expressive layouts headings be indexed with the page?
  • footnotes in expressive layouts affect those in the page?

@damithc @crphang

Although the second seems convenient, my preference is to keep this independent of the page, because it can become difficult to predict / keep track of the expected behaviour for an author
Content reuse (in this case footnote definitions) can also still be achieved via <include> / {% include %}

Indexing headings with the page seems redundant and causes a lot of repeated search results

@ang-zeyu I'll leave you make the decision, after considering @crphang's inputs, if any.

@ang-zeyu I'm not too sure how expressive layouts can support site-nav and page-nav without making page.md too bulky. Could you share that if we are pursuing that direction?

I don't have strong opinions on the other suggestions ๐Ÿ‘

@ang-zeyu I'm not too sure how expressive layouts can support site-nav and page-nav without making page.md too bulky. Could you share that if we are pursuing that direction?

something like this https://www.11ty.dev/docs/layouts/

but without the non <body> details maybe (<html>, <head>, ... ), if we're aiming for simplicity

so we would also still have head.md unfortunately - but this can be combined further through a tag at a later stage (e.g. <head-top> / <head-bottom>)

is that an acceptable level of bulkiness? ๐Ÿ˜ฎ

may be nice to include this in v3.0 as a breaking change to layouts since it can dramatically simplify things. (but more migration work needed)

@damithc @crphang any thoughts?

Options:

  1. preserve the old layout system for now

    • all good ๐Ÿ‘


  1. Fully replicate https://www.11ty.dev/docs/layouts/

    • the site-nav would be component-fied (e.g. <mb-site-nav>)
    • pros:

      • really simple to implement / maintain

      • greatest flexibility

    • cons:

      • user will have to be concerned with more technical details (e.g. <meta> tags, <title>, ...), but maybe not so much an issue if we include a proper baseline layout inside the template sites (markbind init)

  2. Somewhere in between โ”

    • the site-nav would be component-fied as well (e.g. <mb-site-nav>)
    • Layouts will only be able to edit anything in the <body> tag
    • <head> tag will be auto populated
    • this means head.md will be preserved, or something similar (<head-top> / <head-bottom> tag?)
    • pros:

      • less detailed, technical layout

    • cons:

      • โ”

  3. โ”

I'm OK if usability costs are outweighed by other gains. You can use CS2103 site as a benchmark as that's the most complicated MarkBind site we have (also used in 5 other modules).

I'm OK if usability costs are outweighed by other gains. You can use CS2103 site as a benchmark as that's the most complicated MarkBind site we have (also used in 5 other modules).

It should be more user-friendly eitherway, since the current system requires keeping track of multiple layout files. (imo)
Going forward (either option 2 or 3), we would just have a flat layouts directory:

_markbind
  layouts
    admin
    book
    schedule

you'll also be able to use <include />s, etc. in these layout files so there's no restriction on where / how to maintain separate header / sitenav / topnav files if preferred.

Any opinions on option 2 / 3 though? ๐Ÿ˜ฎ

2 would be

<html>
  <head>
  ...
  </head>
  <body>
  ... {{ MAIN_CONTENT_BODY }} somewhere
  </body>
</html>

3 could be

<head-top>
  <link ... />
</head-top>
<head-bottom>
  <link .../>
</head>

... <body> content with {{ MAIN_CONTENT_BODY }} somewhere ...

For option 2, what would be the baseline <head> content?

hmm good point, just realised it would be a little difficult to insert to go with option 2 since we have baked in essential assets (octicons, highlightJs, ...) vs something like https://www.11ty.dev/docs/layouts/ which dosen't

    {{ headFileTopContent }}
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="generator" content="{{ markBindVersion }}">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ title }}</title>

    // essentials
    <link rel="stylesheet" href="{{ asset.bootstrap }}">
    <link rel="stylesheet" href="{{ asset.bootstrapVueCss }}">
    <link rel="stylesheet" href="{{ asset.fontAwesome }}">
    <link rel="stylesheet" href="{{ asset.glyphicons }}">
    <link rel="stylesheet" href="{{ asset.octicons }}">
    <link rel="stylesheet" href="{{ asset.highlight }}">
    {%- if not dev -%}<link rel="stylesheet" href="{{ asset.markBindCss }}">{%- endif -%}
    <script src="{{ asset.polyfillJs }}"></script>
    <script src="{{ asset.vue }}"></script>
    <script src="{{ asset.markBindJs }}"></script>
    <script src="{{ asset.jQuery }}"></script>
    {%- if asset.pluginLinks -%}
    {%- for link in asset.pluginLinks -%}
        {{ link }}
    {%- endfor -%}
    {%- endif -%}
    {%- if faviconUrl -%} <link rel="icon" href="{{ faviconUrl }}"> {%- endif -%}
    // till here

    <link rel="stylesheet" href="{{ asset.layoutStyle }}">
    {{- headFileBottomContent -}}

should we go with (3) then? There's the issue of custom scripts (inserted after our own scripts after the <body> tag) if we were to go with option 3 I forgot to mention though.

For that we could include some sort of <script-bottom> tag similar to <head-bottom>. What do you think?

Sure, can give option 3 a try. You might gain further insights as you implement/test it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Xenonym picture Xenonym  ยท  3Comments

yamgent picture yamgent  ยท  5Comments

ang-zeyu picture ang-zeyu  ยท  6Comments

yamgent picture yamgent  ยท  6Comments

jamos-tay picture jamos-tay  ยท  4Comments