diff --git a/_includes/components/aux_nav.html b/_includes/components/aux_nav.html new file mode 100644 index 0000000..f327da6 --- /dev/null +++ b/_includes/components/aux_nav.html @@ -0,0 +1,15 @@ + diff --git a/_includes/components/breadcrumbs.html b/_includes/components/breadcrumbs.html new file mode 100644 index 0000000..f1bc488 --- /dev/null +++ b/_includes/components/breadcrumbs.html @@ -0,0 +1,15 @@ +{% unless page.url == "/" %} + {% if page.parent %} + + {% endif %} +{% endunless %} diff --git a/_includes/components/children_nav.html b/_includes/components/children_nav.html new file mode 100644 index 0000000..e76f98d --- /dev/null +++ b/_includes/components/children_nav.html @@ -0,0 +1,9 @@ +
+{% include toc_heading_custom.html %} + diff --git a/_includes/components/footer.html b/_includes/components/footer.html new file mode 100644 index 0000000..01b2c23 --- /dev/null +++ b/_includes/components/footer.html @@ -0,0 +1,34 @@ +{% capture footer_custom %} + {%- include footer_custom.html -%} +{% endcapture %} +{% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %} +
+ +{% endif %} diff --git a/_includes/components/header.html b/_includes/components/header.html new file mode 100644 index 0000000..f9c3386 --- /dev/null +++ b/_includes/components/header.html @@ -0,0 +1,11 @@ +
+ {% if site.search_enabled != false %} + {% include components/search_header.html %} + {% else %} +
+ {% endif %} + {% include header_custom.html %} + {% if site.aux_links %} + {% include components/aux_nav.html %} + {% endif %} +
diff --git a/_includes/components/mermaid.html b/_includes/components/mermaid.html new file mode 100644 index 0000000..d6923e0 --- /dev/null +++ b/_includes/components/mermaid.html @@ -0,0 +1,5 @@ + diff --git a/_includes/components/search_footer.html b/_includes/components/search_footer.html new file mode 100644 index 0000000..fb4fe51 --- /dev/null +++ b/_includes/components/search_footer.html @@ -0,0 +1,7 @@ +{% if site.search.button %} + + + +{% endif %} + +
diff --git a/_includes/components/search_header.html b/_includes/components/search_header.html new file mode 100644 index 0000000..98425d5 --- /dev/null +++ b/_includes/components/search_header.html @@ -0,0 +1,9 @@ +{% capture search_placeholder %}{% include search_placeholder_custom.html %}{% endcapture %} + + diff --git a/_includes/components/sidebar.html b/_includes/components/sidebar.html new file mode 100644 index 0000000..c9c1bb8 --- /dev/null +++ b/_includes/components/sidebar.html @@ -0,0 +1,69 @@ + diff --git a/_includes/icons/code_copy.html b/_includes/icons/code_copy.html index 02f5068..0538a23 100644 --- a/_includes/icons/code_copy.html +++ b/_includes/icons/code_copy.html @@ -12,4 +12,4 @@ - \ No newline at end of file + diff --git a/_includes/icons/document.html b/_includes/icons/document.html new file mode 100644 index 0000000..c09e8a5 --- /dev/null +++ b/_includes/icons/document.html @@ -0,0 +1,6 @@ + + Document + + + + diff --git a/_includes/icons/expand.html b/_includes/icons/expand.html new file mode 100644 index 0000000..79921a5 --- /dev/null +++ b/_includes/icons/expand.html @@ -0,0 +1,6 @@ + + Expand + + + + diff --git a/_includes/icons/icons.html b/_includes/icons/icons.html new file mode 100644 index 0000000..007a495 --- /dev/null +++ b/_includes/icons/icons.html @@ -0,0 +1,13 @@ + + {% include icons/link.html %} + {% include icons/menu.html %} + {% include icons/expand.html %} + {% include icons/external_link.html %} + {% if site.search_enabled != false %} + {% include icons/document.html %} + {% include icons/search.html %} + {% endif %} + {% if site.enable_copy_code_button != false %} + {% include icons/code_copy.html %} + {% endif %} + diff --git a/_includes/icons/link.html b/_includes/icons/link.html new file mode 100644 index 0000000..de24be7 --- /dev/null +++ b/_includes/icons/link.html @@ -0,0 +1,6 @@ + + Link + + + + diff --git a/_includes/icons/menu.html b/_includes/icons/menu.html new file mode 100644 index 0000000..d256575 --- /dev/null +++ b/_includes/icons/menu.html @@ -0,0 +1,6 @@ + + Menu + + + + diff --git a/_includes/icons/search.html b/_includes/icons/search.html new file mode 100644 index 0000000..8f72c6a --- /dev/null +++ b/_includes/icons/search.html @@ -0,0 +1,6 @@ + + Search + + + + diff --git a/_layouts/default.html b/_layouts/default.html index 61ebc06..3bc0e0a 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -8,161 +8,12 @@ layout: table_wrappers {% include head.html %} Skip to main content - - - Link - - - - - - Search - - - - - - Menu - - - - - - Expand - - - - - - Document - - - - - {% include icons/external_link.html %} - {% include icons/code_copy.html %} - - - + {% include icons/icons.html %} + {% include components/sidebar.html %}
-
- {% if site.search_enabled != false %} - - {% capture search_placeholder %}{% include search_placeholder_custom.html %}{% endcapture %} - - - {% else %} -
- {% endif %} - {% include header_custom.html %} - {% if site.aux_links %} - - {% endif %} -
+ {% include components/header.html %}
- {% unless page.url == "/" %} - {% if page.parent %} - - {% endif %} - {% endunless %} + {% include components/breadcrumbs.html %}
{% if site.heading_anchors != false %} {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %} @@ -171,72 +22,20 @@ layout: table_wrappers {% endif %} {% if page.has_children == true and page.has_toc != false %} -
- {% include toc_heading_custom.html %} -
    - {% for child in toc_list %} -
  • - {{ child.title }}{% if child.summary %} - {{ child.summary }}{% endif %} -
  • - {% endfor %} -
+ {% include components/children_nav.html toc_list=toc_list %} {% endif %} - {% capture footer_custom %} - {%- include footer_custom.html -%} - {% endcapture %} - {% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %} -
-
- {% if site.back_to_top %} -

{{ site.back_to_top_text }}

- {% endif %} - - {{ footer_custom }} - - {% if site.last_edit_timestamp or site.gh_edit_link %} -
- {% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %} -

- Page last modified: {{ page.last_modified_date | date: site.last_edit_time_format }}. -

- {% endif %} - {% if - site.gh_edit_link and - site.gh_edit_link_text and - site.gh_edit_repository and - site.gh_edit_branch and - site.gh_edit_view_mode - %} -

- {{ site.gh_edit_link_text }} -

- {% endif %} -
- {% endif %} -
- {% endif %} + {% include components/footer.html %}
- {% if site.search_enabled != false %} - {% if site.search.button %} - - - - {% endif %} - -
+ {% include components/search_footer.html %} {% endif %}
{% if site.mermaid %} - + {% include components/mermaid.html %} {% endif %} diff --git a/_layouts/minimal.html b/_layouts/minimal.html new file mode 100644 index 0000000..5cbac78 --- /dev/null +++ b/_layouts/minimal.html @@ -0,0 +1,60 @@ +--- +layout: table_wrappers +--- + + + + +{% include head.html %} + + Skip to main content + {% include icons/icons.html %} + {% comment %} + This is a bandaid fix to properly render breadcrumbs; as of now, there is some variable leakage between the sidebar component (which computes parents, grandparents) and the breadcrumbs component. We plan to remove this in a future release to deduplicate code. + + For more context, see https://github.com/just-the-docs/just-the-docs/pull/1058#discussion_r1057014053 + {% endcomment %} + {% capture nav %} + {% assign pages_top_size = site.html_pages + | where_exp:"item", "item.title != nil" + | where_exp:"item", "item.parent == nil" + | where_exp:"item", "item.nav_exclude != true" + | size %} + {% if pages_top_size > 0 %} + {% include nav.html pages=site.html_pages key=nil %} + {% endif %} + {% if site.just_the_docs.collections %} + {% assign collections_size = site.just_the_docs.collections | size %} + {% for collection_entry in site.just_the_docs.collections %} + {% assign collection_key = collection_entry[0] %} + {% assign collection_value = collection_entry[1] %} + {% assign collection = site[collection_key] %} + {% if collection_value.nav_exclude != true %} + {% include nav.html pages=collection key=collection_key %} + {% endif %} + {% endfor %} + {% endif %} + {% endcapture %} +
+ {% include components/breadcrumbs.html %} +
+ {% if site.heading_anchors != false %} + {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %} + {% else %} + {{ content }} + {% endif %} + + {% if page.has_children == true and page.has_toc != false %} + {% include components/children_nav.html toc_list=toc_list %} + {% endif %} + + {% include components/footer.html %} + +
+
+ + {% if site.mermaid %} + {% include components/mermaid.html %} + {% endif %} + + diff --git a/assets/js/just-the-docs.js b/assets/js/just-the-docs.js index 8aabf32..f243f07 100644 --- a/assets/js/just-the-docs.js +++ b/assets/js/just-the-docs.js @@ -74,7 +74,7 @@ function initSearch() { request.onload = function(){ if (request.status >= 200 && request.status < 400) { var docs = JSON.parse(request.responseText); - + lunr.tokenizer.separator = {{ site.search.tokenizer_separator | default: site.search_tokenizer_separator | default: "/[\s\-/]+/" }} var index = lunr(function(){ @@ -217,6 +217,7 @@ function searchLoaded(index, docs) { resultTitle.classList.add('search-result-title'); resultLink.appendChild(resultTitle); + // note: the SVG svg-doc is only loaded as a Jekyll include if site.search_enabled is true; see _includes/icons/icons.html var resultDoc = document.createElement('div'); resultDoc.classList.add('search-result-doc'); resultDoc.innerHTML = ''; @@ -488,6 +489,7 @@ jtd.onReady(function(){ var codeBlocks = document.querySelectorAll('div.highlighter-rouge, div.listingblock, figure.highlight'); + // note: the SVG svg-copied and svg-copy is only loaded as a Jekyll include if site.enable_copy_code_button is true; see _includes/icons/icons.html var svgCopied = ''; var svgCopy = ''; diff --git a/docs/customization.md b/docs/customization.md index 67070ae..fe42892 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -212,3 +212,158 @@ Chercher notre site {% endraw %} would make the placeholder text "Chercher notre site". [Liquid code](https://jekyllrb.com/docs/liquid/) (including [Jekyll variables](https://jekyllrb.com/docs/variables/)) is also supported. + +## Custom layouts and includes +{: .d-inline-block } + +New (v0.4.0) +{: .label .label-green } + +Advanced +{: .label .label-yellow } + +Just the Docs uses Jekyll's powerful [layouts](https://jekyllrb.com/docs/layouts/) and [includes](https://jekyllrb.com/docs/includes/) features to generate and compose various elements of the site. Jekyll users and developers can extend or replace existing layouts and includes to customize the entire site layout. + +### Default layout and includable components + +The `default` layout is inherited by most of the "out-of-the-box" pages provided by Just the Docs. It composes various re-usable components of the site, including the sidebar, navbar, footer, breadcrumbs, and various imports. Most users who create new pages or layouts will inherit from `default`. + +Here is a simplified code example of what it looks like: + +{% raw %} + +```liquid + + +{% include head.html %} + + {% include icons/icons.html %} + {% include components/sidebar.html %} + {% include components/header.html %} + {% include components/breadcrumbs.html %} + + {% if site.heading_anchors != false %} + {% include vendor/anchor_headings.html html=content ... %} + {% else %} + {{ content }} + {% endif %} + + {% if page.has_children == true and page.has_toc != false %} + {% include components/children_nav.html %} + {% endif %} + + {% include components/footer.html %} + + {% if site.search_enabled != false %} + {% include components/search_footer.html %} + {% endif %} + + {% if site.mermaid %} + {% include components/mermaid.html %} + {% endif %} + + +``` + +{% endraw %} + +#### Component summary +{: .no_toc } + +{: .warning } +Defining a new `_includes` with the same name as any of these components will significantly change the existing layout. Please proceed with caution when adjusting them. + +To briefly summarize each component: + +- `_includes/head.html` is the entire `` tag for the site; this imports stylesheets, various JavaScript files (ex: analytics, mermaid, search, and Just the Docs code), and SEO / meta information. +- `_includes/icons/icons.html` imports all SVG icons that are used throughout the site. Some, such as those relating to search or code snippet copying, are only loaded when those features are enabled. +- `_includes/components/sidebar.html` renders the sidebar, containing the site header, navigation links, external links, collections, and nav footer. +- `_includes/components/header.html` renders the navigation header, containing the search bar, custom header, and aux links +- `_includes/components/breadcrumbs.html` renders the breadcrumbs feature +- `vendor/anchor_headings.html` is a local copy of Vladimir Jimenez's [jekyll-anchor-headings](https://github.com/allejo/jekyll-anchor-headings) snippet +- `_includes/components/children_nav.html` renders a list of nav links to child pages on parent pages +- `_includes/components/footer.html` renders the bottom-of-page footer +- `_includes/components/search_footer.html` renders DOM elements that are necessary for the search bar to work +- `_includes/components/mermaid.html` initializes mermaid if the feature is enabled + +Each of these components can be overridden individually using the same process described in the [Override includes](#override-includes) section. In particular, the granularity of components should allow users to replace certain components (such as the sidebar) without having to adjust the rest of the code. + +Future versions may subdivide components further; we guarantee that we will only place them in folders (ex `components/`, `icons/`, or a new `js/`) to avoid top-level namespace collisions. + +### Alternative layouts and example (`minimal`) + +Users can develop custom layouts that compose, omit, or add components differently. We provide one first-class example titled `minimal`, inspired by Kevin Lin's work in [just-the-class](https://github.com/kevinlin1/just-the-class). This `minimal` layout does not render the sidebar, header, or search. To see an example, visit the [minimal layout test]({{site.baseurl}}/docs/minimal-test/) page. + +Here is a simplified code example of what it looks like: + +{% raw %} + +```liquid + + +{% include head.html %} + + {% include icons/icons.html %} + {% comment %} Bandaid fix for breadcrumbs here! {% endcomment %} + {% include components/breadcrumbs.html %} + + {% if site.heading_anchors != false %} + {% include vendor/anchor_headings.html html=content ... %} + {% else %} + {{ content }} + {% endif %} + + {% if page.has_children == true and page.has_toc != false %} + {% include components/children_nav.html %} + {% endif %} + + {% include components/footer.html %} + + {% if site.mermaid %} + {% include components/mermaid.html %} + {% endif %} + + +``` + +{% endraw %} + +This layout is packaged in Just the Docs. Users can indicate this alternative layout in page front matter: + +{% raw %} + +``` +--- +layout: minimal +title: Minimal layout test +--- +``` + +{% endraw %} + +Similarly, users and developers can create other alternative layouts using Just the Docs' reusable includable components. + +### Default layout and inheritance chain + +Under the hood, + +- `default` and `minimal` inherit from the `table_wrappers` layout, which wraps all HTML `` tags with a `div .table-wrapper` +- `table_wrappers` inherits from `vendor/compress`, which is a local copy of Anatol Broder's [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) Jekyll plugin + +Note that as of now, `minimal` and `default` have no inheritance relationship. + +### Overridden default Jekyll layouts + +By default, Jekyll (and its default theme `minima`) provide the `about`, `home`, `page`, and `post` layouts. In Just the Docs, we override all of these layouts with the `default` layout. Each of those layouts is simply: + +{% raw %} + +``` +--- +layout: default +--- + +{{ content }} +``` + +{% endraw %} diff --git a/docs/minimal-test.md b/docs/minimal-test.md new file mode 100644 index 0000000..aa754d3 --- /dev/null +++ b/docs/minimal-test.md @@ -0,0 +1,9 @@ +--- +layout: minimal +title: Minimal layout test +nav_exclude: true +--- + +[Return to main website]({{site.baseurl}}/). + +This page demonstrates the packaged `minimal` layout, which does not render the sidebar or header. It can be used for standalone pages. It is also an example of using the new modular site components to define custom layouts; see ["Custom layouts and includes" in the customization docs]({{site.baseurl}}/docs/customization/#custom-layouts-and-includes) for more information.