7.0.0 Beta
See original GitHub issueExactly one year has passed since we switched to RxJS in v5 (#1465). This gave us the opportunity to make all parts of the theme observable to third-party JavaScript and eased maintenance because we can now rely on a well-tested library for all the plumbing. However, as I wasn’t very experienced with RxJS, I made some rather bad design decisions, which made theme extension and adding of features cumbersome. For this reason, I decided to overhaul the architecture and move it to a simpler and more maintainable approach. This is what v7 is all about. After we get v7 out the door, we can iterate on new features even faster. Also, the code is much more readable and idiomatic now.
When the next funding goal is hit, the new features will be released as part of v7. This is expected to happen in the next 1-2 weeks. If you run across any issues, please open a new issue and prefix it with [v7]! Thanks for taking the time to test!
Installation
pip install mkdocs-material==7.0.0b2
Migration
If you use Material for MkDocs without overrides, you can switch to v7 without any further ado.
Configuration
None.
Templates
The following adjustments need to be made to the partials:
Show template diff
diff --git a/src/base.html b/src/base.html
index e566d9de..abd4c92e 100644
--- a/src/base.html
+++ b/src/base.html
@@ -259,7 +259,7 @@
{% endif %}
<div
class="md-sidebar md-sidebar--primary"
- data-md-component="navigation"
+ data-md-component="sidebar" data-md-type="navigation"
{{ hidden }}
>
<div class="md-sidebar__scrollwrap">
@@ -277,7 +277,7 @@
{% endif %}
<div
class="md-sidebar md-sidebar--secondary"
- data-md-component="toc"
+ data-md-component="sidebar" data-md-type="toc"
{{ hidden }}
>
<div class="md-sidebar__scrollwrap">
@@ -290,7 +290,7 @@
{% endblock %}
<!-- Article -->
- <div class="md-content">
+ <div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<!-- Content -->
@@ -344,13 +344,22 @@
{% endblock %}
</div>
- <!-- Theme-related JavaScript -->
- {% block scripts %}
- <script src="{{ 'assets/javascripts/vendor.js' | url }}"></script>
- <script src="{{ 'assets/javascripts/bundle.js' | url }}"></script>
+ <!-- Dialog -->
+ <div class="md-dialog" data-md-component="dialog">
+ <div class="md-dialog__inner md-typeset"></div>
+ </div>
+
+ <!-- Theme-related configuration -->
+ {% block config %}
+ {%- set app = {
+ "base": base_url,
+ "features": features,
+ "translations": {},
+ "search": "assets/javascripts/worker/search.js" | url,
+ } -%}
<!-- Translations -->
- {%- set translations = {} -%}
+ {%- set translations = app.translations -%}
{%- for key in [
"clipboard.copy",
"clipboard.copied",
@@ -368,23 +377,17 @@
] -%}
{%- set _ = translations.update({ key: lang.t(key) }) -%}
{%- endfor -%}
- <script id="__lang" type="application/json">
- {{- translations | tojson -}}
- </script>
- <!-- Application configuration -->
- {% block config %}{% endblock %}
-
- <!-- Application initialization -->
- <script>
- app = initialize({
- base: "{{ base_url }}",
- features: {{ features or [] | tojson }},
- search: Object.assign({
- worker: "{{ 'assets/javascripts/worker/search.js' | url }}"
- }, typeof search !== "undefined" && search)
- })
+ <!-- Configuration -->
+ <script id="__config" type="application/json">
+ {{- app | tojson -}}
</script>
+ {% endblock %}
+
+ <!-- Theme-related JavaScript -->
+ {% block scripts %}
+ <script src="{{ 'assets/javascripts/vendor.js' | url }}"></script>
+ <script src="{{ 'assets/javascripts/bundle.js' | url }}"></script>
<!-- Custom JavaScript -->
{% for path in config["extra_javascript"] %}
diff --git a/src/partials/search.html b/src/partials/search.html
index 7061acea..d5b4f9a6 100644
--- a/src/partials/search.html
+++ b/src/partials/search.html
@@ -49,7 +49,6 @@
type="reset"
class="md-search__icon md-icon"
aria-label="{{ lang.t('search.reset') }}"
- data-md-component="search-reset"
tabindex="-1"
>
{% include ".icons/material/close.svg" %}
diff --git a/src/partials/source.html b/src/partials/source.html
index 89f3b740..34b0374b 100644
--- a/src/partials/source.html
+++ b/src/partials/source.html
@@ -27,6 +27,7 @@
href="{{ config.repo_url }}"
title="{{ lang.t('source.link.title') }}"
class="md-source"
+ data-md-component="source"
>
<div class="md-source__icon md-icon">
{% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %}
diff --git a/src/partials/toc.html b/src/partials/toc.html
index 7de17013..41902c47 100644
--- a/src/partials/toc.html
+++ b/src/partials/toc.html
@@ -42,7 +42,7 @@
<span class="md-nav__icon md-icon"></span>
{{ lang.t("toc.title") }}
</label>
- <ul class="md-nav__list" data-md-scrollfix>
+ <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
{% for toc_item in toc %}
{% include "partials/toc-item.html" %}
{% endfor %}
JavaScript
The following adjustments need to be made to custom JavaScript:
Configuration
As can be seen in the template diff, configuration of the JavaScript is now done as part of a script
tag with the type application/json
. Search customization (transform
+ index
) must be renamed and extend the config block:
Before:
{% block config %}
<script>
var search = {
index: ...
transform: function(query) {
return query
}
}
</script>
{% endblock %}
Now:
{% block config %}
{{ super() }}
<script>
var __search = {
index: ...
transform: function(query) {
return query
}
}
</script>
{% endblock %}
Flattened exports
The application will now export all observables into the window
scope (and not the app
variable as it was before):
Before:
app.document$.subscribe(function() {
var tables = document.querySelectorAll("article table")
tables.forEach(function(table) {
new Tablesort(table)
})
})
Now:
document$.subscribe(function() {
var tables = document.querySelectorAll("article table")
tables.forEach(function(table) {
new Tablesort(table)
})
})
The following observables are exported:
document$
: Document changes (instant loading)location$
: Location changes (instant loading)target$
: Target changes, i.e. anchor link clickskeyboard$
: Keyboard eventsviewport$
: Viewport events (offset + size)tablet$
: Tablet breakpointscreen$
: Tablet breakpointprint$
: Print modecomponent$
: Component events (merged into a single stream)
Deprecations
The DOMContentSwitch
event is deprecated, as it is non-standard and was a bad idea overall. Use the document$
observable, to achieve the same thing.
Before:
document.addEventListener("DOMContentSwitch" () => {
/* ... do something on instant loading ... */
})
Now:
document$.subscribe(() => {
/* ... do something on initial page load and instant loading ... */
})
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:10 (10 by maintainers)
Top GitHub Comments
@nmanumr thanks, that’s awesome to hear! It can be hard to structure reactive projects when you’re not using the idioms of an existing framework like React or Vue, but since we’re doing progressive enhancement, we have to do some things differently. I’m very happy how things turned out switching to RxJS a year ago and with the recent refactoring, the project is now in much better shape. Feel free to steal anything you like, it’s Open Source after all 😊
Hmm true, that’s also what I did for Material v4. But the code really isn’t that complicated and avoids a breaking change for 99.9% of the current user base. Maybe I’ll switch when a release candidate of v7 is out of the door.