diff --git a/CHANGELOG.md b/CHANGELOG.md index b60d0b64..f78befe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,7 +94,7 @@ - Fix typo preventing benchmarking ([#1235](https://github.com/django-components/django-components/pull/1235)) -## 🚨📢 v0.140.0 +## v0.140.0 🚨📢 ⚠️ Major release ⚠️ - Please test thoroughly before / after upgrading. @@ -118,7 +118,7 @@ Summary: - Component caching can now consider slots (opt-in) - And lot more... -#### 🚨📢 BREAKING CHANGES +#### BREAKING CHANGES 🚨📢 **Middleware** @@ -564,7 +564,7 @@ Summary: render_dependencies(content, strategy="document") ``` -#### 🚨📢 Deprecation +#### Deprecation 🚨📢 **Component API** @@ -1573,9 +1573,9 @@ Summary: - `Component.get_context_data()` can now omit a return statement or return `None`. -## 🚨📢 v0.136 +## v0.136 🚨📢 -#### 🚨📢 BREAKING CHANGES +#### BREAKING CHANGES 🚨📢 - Component input validation was moved to a separate extension [`djc-ext-pydantic`](https://github.com/django-components/djc-ext-pydantic). @@ -2090,13 +2090,15 @@ If you see any broken links or other issues, please report them in [#922](https: - Prevent rendering Component tags during fill discovery stage to fix a case when a component inside the default slot tried to access provided data too early. -## 🚨📢 v0.110 +## v0.110 🚨📢 + +_25 Nov 2024_ ⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See [#791](https://github.com/django-components/django-components/issues/791) and [#789](https://github.com/django-components/django-components/issues/789) and [#818](https://github.com/django-components/django-components/issues/818). ### General -#### 🚨📢 BREAKING CHANGES +#### BREAKING CHANGES 🚨📢 - Installation changes: @@ -2173,7 +2175,7 @@ importing them. ### Tags -#### 🚨📢 BREAKING CHANGES +#### BREAKING CHANGES 🚨📢 - `{% component_dependencies %}` tag was removed. Instead, use `{% component_js_dependencies %}` and `{% component_css_dependencies %}` @@ -2414,7 +2416,9 @@ importing them. {% endcomponent %} ``` -## 🚨📢 v0.100 +## v0.100 🚨📢 + +_11 Sep 2024_ #### BREAKING CHANGES @@ -2438,6 +2442,8 @@ importing them. ## v0.97 +_6 Sep 2024_ + #### Fix - Fixed template caching. You can now also manually create cached templates with [`cached_template()`](https://github.com/django-components/django-components#template_cache_size---tune-the-template-cache) @@ -2453,15 +2459,19 @@ importing them. ## v0.96 +_4 Sep 2024_ + #### Feat -- Run-time type validation for Python 3.11+ - If the `Component` class is typed, e.g. `Component[Args, Kwargs, ...]`, the args, kwargs, slots, and data are validated against the given types. (See [Runtime input validation with types](https://github.com/django-components/django-components#runtime-input-validation-with-types)) +- Run-time type validation for Python >=3.11 - If the `Component` class is typed, e.g. `Component[Args, Kwargs, ...]`, the args, kwargs, slots, and data are validated against the given types. (See [Runtime input validation with types](https://github.com/django-components/django-components#runtime-input-validation-with-types)) - Render hooks - Set `on_render_before` and `on_render_after` methods on `Component` to intercept or modify the template or context before rendering, or the rendered result afterwards. (See [Component hooks](https://github.com/django-components/django-components#component-hooks)) - `component_vars.is_filled` context variable can be accessed from within `on_render_before` and `on_render_after` hooks as `self.is_filled.my_slot` -## 0.95 +## v0.95 + +_29 Aug 2024_ #### Feat @@ -2473,6 +2483,8 @@ importing them. ## v0.94 +_28 Aug 2024_ + #### Feat - django_components now automatically configures Django to support multi-line tags. (See [Multi-line tags](https://github.com/django-components/django-components#multi-line-tags)) @@ -2481,6 +2493,8 @@ importing them. ## v0.93 +_27 Aug 2024_ + #### Feat - Spread operator `...dict` inside template tags. (See [Spread operator](https://github.com/django-components/django-components#spread-operator)) @@ -2491,7 +2505,9 @@ importing them. - Component library authors can now configure `CONTEXT_BEHAVIOR` and `TAG_FORMATTER` settings independently from user settings. -## 🚨📢 v0.92 +## v0.92 🚨📢 + +_22 Aug 2024_ #### BREAKING CHANGES @@ -2505,6 +2521,8 @@ importing them. ## v0.90 +_18 Aug 2024_ + #### Feat - All tags (`component`, `slot`, `fill`, ...) now support "self-closing" or "inline" form, where you can omit the closing tag: @@ -2532,7 +2550,7 @@ importing them. {% endcomponent %} ``` - While `django_components.shorthand_component_formatter` allows you to write components like so: + While `django_components.component_shorthand_formatter` allows you to write components like so: ```django {% button href="..." disabled %} @@ -2540,7 +2558,9 @@ importing them. {% endbutton %} ``` -## 🚨📢 v0.85 +## v0.85 🚨📢 + +_29 Jul 2024_ #### BREAKING CHANGES @@ -2557,7 +2577,9 @@ importing them. - Previously, autodiscovery handled relative files in `STATICFILES_DIRS`. To align with Django, `STATICFILES_DIRS` now must be full paths ([Django docs](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STATICFILES_DIRS)). -## 🚨📢 v0.81 +## v0.81 🚨📢 + +_12 Jun 2024_ #### BREAKING CHANGES @@ -2571,17 +2593,23 @@ importing them. ## v0.80 +_1 Jun 2024_ + #### Feat - Vue-like provide/inject with the `{% provide %}` tag and `inject()` method. -## 🚨📢 v0.79 +## v0.79 🚨📢 + +_1 Jun 2024_ #### BREAKING CHANGES - Default value for the `COMPONENTS.context_behavior` setting was changes from `"isolated"` to `"django"`. If you did not set this value explicitly before, this may be a breaking change. See the rationale for change [here](https://github.com/django-components/django-components/issues/498). -## 🚨📢 v0.77 +## v0.77 🚨📢 + +_23 May 2024_ #### BREAKING @@ -2604,13 +2632,17 @@ importing them. ## v0.74 +_12 May 2024_ + #### Feat - `{% html_attrs %}` tag for formatting data as HTML attributes - `prefix:key=val` construct for passing dicts to components -## 🚨📢 v0.70 +## v0.70 🚨📢 + +_1 May 2024_ #### BREAKING CHANGES @@ -2620,11 +2652,15 @@ importing them. ## v0.67 +_17 Apr 2024_ + #### Refactor - Changed the default way how context variables are resolved in slots. See the [documentation](https://github.com/django-components/django-components/tree/0.67#isolate-components-slots) for more details. -## 🚨📢 v0.50 +## v0.50 🚨📢 + +_26 Feb 2024_ #### BREAKING CHANGES @@ -2636,23 +2672,31 @@ importing them. ## v0.34 +_27 Jan 2024_ + #### Feat - Components as views, which allows you to handle requests and render responses from within a component. See the [documentation](https://github.com/django-components/django-components#use-components-as-views) for more details. ## v0.28 +_18 May 2023_ + #### Feat - 'implicit' slot filling and the `default` option for `slot` tags. ## v0.27 +_11 Apr 2023_ + #### Feat - A second installable app `django_components.safer_staticfiles`. It provides the same behavior as `django.contrib.staticfiles` but with extra security guarantees (more info below in [Security Notes](https://github.com/django-components/django-components#security-notes)). -## 🚨📢 v0.26 +## v0.26 🚨📢 + +_14 Mar 2023_ #### BREAKING CHANGES @@ -2662,6 +2706,8 @@ importing them. ## v0.22 +_26 Jul 2022_ + #### Feat - All files inside components subdirectores are autoimported to simplify setup. @@ -2670,6 +2716,8 @@ importing them. ## v0.17 +_10 Sep 2021_ + #### BREAKING CHANGES - Renamed `Component.context` and `Component.template` to `get_context_data` and `get_template_name`. The old methods still work, but emit a deprecation warning. diff --git a/docs/.nav.yml b/docs/.nav.yml index 3816ed34..743d884d 100644 --- a/docs/.nav.yml +++ b/docs/.nav.yml @@ -4,7 +4,11 @@ nav: - overview - Getting Started: getting_started - - concepts - - guides - - API Documentation: reference - - Release Notes: release_notes.md + - "Documentation: Concepts": concepts + - "Documentation: API Reference": reference + - "Documentation: Guides": guides + - "Documentation: Upgrading": upgrading + - plugins + - examples + - community + - Release Notes: releases diff --git a/docs/community/.nav.yml b/docs/community/.nav.yml new file mode 100644 index 00000000..54b7fa2a --- /dev/null +++ b/docs/community/.nav.yml @@ -0,0 +1,7 @@ +# `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav +nav: + - Questions & Help: help.md + - Contributing: contributing.md + - Development: development.md + - Code of Conduct: code_of_conduct.md + - Dev Guides: devguides diff --git a/docs/overview/code_of_conduct.md b/docs/community/code_of_conduct.md similarity index 100% rename from docs/overview/code_of_conduct.md rename to docs/community/code_of_conduct.md diff --git a/docs/overview/contributing.md b/docs/community/contributing.md similarity index 94% rename from docs/overview/contributing.md rename to docs/community/contributing.md index 2aebbc0f..996724d4 100644 --- a/docs/overview/contributing.md +++ b/docs/community/contributing.md @@ -11,12 +11,12 @@ you out with the rest! For feature requests or suggestions, please open either a discussion or an issue. -## Getting involved +### Getting involved django_components is still under active development, and there's much to build, so come aboard! -## Sponsoring +### Sponsoring Another way you can get involved is by [donating](https://github.com/django-components/django-components) to the development of django_components. diff --git a/docs/overview/development.md b/docs/community/development.md similarity index 97% rename from docs/overview/development.md rename to docs/community/development.md index 76195e62..833b5839 100644 --- a/docs/overview/development.md +++ b/docs/community/development.md @@ -189,4 +189,4 @@ python scripts/validate_links.py --rewrite ## Development guides -Head over to [Dev guides](../guides/devguides/dependency_mgmt.md) for a deep dive into how django_components' features are implemented. +Head over to [Dev guides](./devguides/dependency_mgmt.md) for a deep dive into how django_components' features are implemented. diff --git a/docs/guides/devguides/.nav.yml b/docs/community/devguides/.nav.yml similarity index 100% rename from docs/guides/devguides/.nav.yml rename to docs/community/devguides/.nav.yml diff --git a/docs/guides/devguides/dependency_mgmt.md b/docs/community/devguides/dependency_mgmt.md similarity index 100% rename from docs/guides/devguides/dependency_mgmt.md rename to docs/community/devguides/dependency_mgmt.md diff --git a/docs/guides/devguides/slot_rendering.md b/docs/community/devguides/slot_rendering.md similarity index 100% rename from docs/guides/devguides/slot_rendering.md rename to docs/community/devguides/slot_rendering.md diff --git a/docs/guides/devguides/slots_and_blocks.md b/docs/community/devguides/slots_and_blocks.md similarity index 100% rename from docs/guides/devguides/slots_and_blocks.md rename to docs/community/devguides/slots_and_blocks.md diff --git a/docs/community/help.md b/docs/community/help.md new file mode 100644 index 00000000..4711a97b --- /dev/null +++ b/docs/community/help.md @@ -0,0 +1,3 @@ +The best place to ask questions is in our [Github Discussion board](https://github.com/django-components/django-components/discussions). + +Please, before opening a new discussion, [check if similar discussion wasn't opened already](https://github.com/django-components/django-components/discussions?discussions_q=). diff --git a/docs/concepts/advanced/component_libraries.md b/docs/concepts/advanced/component_libraries.md index 44aa4577..07f0a40f 100644 --- a/docs/concepts/advanced/component_libraries.md +++ b/docs/concepts/advanced/component_libraries.md @@ -1,6 +1,6 @@ You can publish and share your components for others to use. Below you will find the steps to do so. -For live examples, see the [Community examples](../../overview/community.md#community-examples). +For live examples, see the [Examples](../../examples/index.md). ## Writing component libraries diff --git a/docs/concepts/advanced/html_fragments.md b/docs/concepts/advanced/html_fragments.md index 3ac8ea4b..33822c8d 100644 --- a/docs/concepts/advanced/html_fragments.md +++ b/docs/concepts/advanced/html_fragments.md @@ -91,7 +91,7 @@ MyTable.render( ## Live examples -For live interactive examples, [start our demo project](../../overview/development.md#developing-against-live-django-app) +For live interactive examples, [start our demo project](../../community/development.md#developing-against-live-django-app) (`sampleproject`). Then navigate to these URLs: diff --git a/docs/examples/.nav.yml b/docs/examples/.nav.yml new file mode 100644 index 00000000..1514751a --- /dev/null +++ b/docs/examples/.nav.yml @@ -0,0 +1,3 @@ +# `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav +nav: + - Examples: overview.md diff --git a/docs/examples/overview.md b/docs/examples/overview.md new file mode 100644 index 00000000..a7ded4fa --- /dev/null +++ b/docs/examples/overview.md @@ -0,0 +1,14 @@ +`django-components` makes it easy to share components between projects +([See how to package components](../concepts/advanced/component_libraries.md)). + +Here you will find public examples of components and component libraries. + +If you have components that would be useful to others, open a pull request to add them to this collection. + +### Icons + +- [djc-heroicons](https://pypi.org/project/djc-heroicons/) - Icons from HeroIcons.com for django-components. + +### HTMX + +- [`django-htmx-components`](https://github.com/iwanalabs/django-htmx-components) - A set of components for use with [htmx](https://htmx.org/). diff --git a/docs/getting_started/.nav.yml b/docs/getting_started/.nav.yml index 7d19afe1..6f1850c0 100644 --- a/docs/getting_started/.nav.yml +++ b/docs/getting_started/.nav.yml @@ -1,5 +1,6 @@ # `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav nav: + - Installation: installation.md - Create your first component: your_first_component.md - Adding JS and CSS: adding_js_and_css.md - Components in templates: components_in_templates.md diff --git a/docs/overview/installation.md b/docs/getting_started/installation.md similarity index 100% rename from docs/overview/installation.md rename to docs/getting_started/installation.md diff --git a/docs/guides/.nav.yml b/docs/guides/.nav.yml index 7b371a29..76c85e96 100644 --- a/docs/guides/.nav.yml +++ b/docs/guides/.nav.yml @@ -2,4 +2,3 @@ nav: - setup - other - - Dev Guides: devguides diff --git a/docs/overrides/partials/nav-item.html b/docs/overrides/partials/nav-item.html new file mode 100644 index 00000000..879af64a --- /dev/null +++ b/docs/overrides/partials/nav-item.html @@ -0,0 +1,283 @@ +{# This overrides the nav-item partial from mkdocs-material v9.6.17 #} +{# https://github.com/squidfunk/mkdocs-material/blob/c89a66bf39bb7f472e925753367ff8e464e0d683/src/templates/partials/nav-item.html #} +{# Majority of the file is the original, so our changes are highlighted #} +{# with `OUR CHANGES START` and `OUR CHANGES END` #} + + +{% macro render_status(nav_item, type) %} + {% set class = "md-status md-status--" ~ type %} + + + {% if config.extra.status and config.extra.status[type] %} + + + + + {% else %} + + {% endif %} +{% endmacro %} + + +{% macro render_content(nav_item, ref) %} + {% set ref = ref or nav_item %} + + + {% if nav_item.meta and nav_item.meta.icon %} + {% include ".icons/" ~ nav_item.meta.icon ~ ".svg" %} + {% endif %} + + + {# Insert line break between group name and title #} + {# E.g. `Documentation: API Reference` -> `Documentation:
API Reference` #} + {% if ": " in ref.title %} + {% set parts = ref.title.split(": ", 1) %} + {% set title = parts[0] ~ ":
" | safe ~ parts[1] %} + {% else %} + {% set title = ref.title %} + {% endif %} + + + + + {{ title }} + + + {% if nav_item.meta and nav_item.meta.subtitle %} +
+ {{ nav_item.meta.subtitle }} + {% endif %} +
+ + + {% if nav_item.meta and nav_item.meta.status %} + {{ render_status(nav_item, nav_item.meta.status) }} + {% endif %} +{% endmacro %} + + +{% macro render_pruned(nav_item, ref) %} + {% set ref = ref or nav_item %} + {% set first = nav_item.children | first %} + + + {% if first and first.children %} + {{ render_pruned(first, ref) }} + + + {% else %} + + {{ render_content(ref) }} + + + {% if nav_item.children | length > 0 %} + + {% endif %} + + {% endif %} +{% endmacro %} + + +{% macro render(nav_item, path, level, parent) %} + + + {% set class = "md-nav__item" %} + {% if nav_item.active %} + {% set class = class ~ " md-nav__item--active" %} + {% endif %} + + + {% if nav_item.pages %} + {% if page in nav_item.pages %} + {% set nav_item = page %} + {% endif %} + {% endif %} + + + {% if nav_item.children %} + + + {% set _ = namespace(index = none) %} + {% if "navigation.indexes" in features %} + {% for item in nav_item.children %} + {% if item.is_index and _.index is none %} + {% set _.index = item %} + {% endif %} + {% endfor %} + {% endif %} + {% set index = _.index %} + + + {% if "navigation.tabs" in features %} + + + {% if level == 1 and nav_item.active %} + {% set class = class ~ " md-nav__item--section" %} + {% set is_section = true %} + {% endif %} + + + {% if "navigation.sections" in features %} + + + {% if level == 2 and parent.active %} + {% set class = class ~ " md-nav__item--section" %} + {% set is_section = true %} + {% endif %} + {% endif %} + + + {% elif "navigation.sections" in features %} + + + {% if level == 1 %} + {% set class = class ~ " md-nav__item--section" %} + {% set is_section = true %} + {% endif %} + {% endif %} + + + {% if "navigation.prune" in features %} + + + {% if not is_section and not nav_item.active %} + {% set class = class ~ " md-nav__item--pruned" %} + {% set is_pruned = true %} + {% endif %} + {% endif %} + + +
  • + {% if not is_pruned %} + {% set checked = "checked" if nav_item.active %} + + + {% if "navigation.expand" in features and not checked %} + {% set indeterminate = "md-toggle--indeterminate" %} + {% endif %} + + + + + + {% if not index %} + {% set tabindex = "0" if not is_section %} + + + + {% else %} + {% set class = "md-nav__link--active" if index == page %} + + {% endif %} + + + + + + {% else %} + {{ render_pruned(nav_item) }} + {% endif %} +
  • + + + {% elif nav_item == page %} +
  • + {% set toc = page.toc %} + + + + + + {% set first = toc | first %} + {% if first and first.level == 1 %} + {% set toc = first.children %} + {% endif %} + + + {% if toc %} + + {% endif %} + + {{ render_content(nav_item) }} + + + + {% if toc %} + {% include "partials/toc.html" %} + {% endif %} +
  • + + + {% else %} +
  • + + {{ render_content(nav_item) }} + +
  • + {% endif %} +{% endmacro %} diff --git a/docs/overrides/partials/tabs.html b/docs/overrides/partials/tabs.html new file mode 100644 index 00000000..88a775ed --- /dev/null +++ b/docs/overrides/partials/tabs.html @@ -0,0 +1,213 @@ +{# This overrides the tabs partial from mkdocs-material v9.6.17 #} +{# https://github.com/squidfunk/mkdocs-material/blob/c89a66bf39bb7f472e925753367ff8e464e0d683/src/templates/partials/tabs.html #} + +{#- This macro populates the `grouped_dict`. It doesn't render any HTML. -#} +{% macro group_tabs(nav, grouped_dict) %} + {% for nav_item in nav %} + {#- If tab title contains a colon, split it into group and title. -#} + {% if ': ' in nav_item.title %} + {% set parts = nav_item.title.split(': ', 1) %} + {% set group_name = parts[0] %} + {% set title = parts[1] %} + {% set is_group = True %} + {% else %} + {% set group_name = nav_item.title %} + {% set title = nav_item.title %} + {% set is_group = False %} + {% endif %} + + {% if group_name not in grouped_dict %} + {% set group = {"title": group_name, "url": "", "active": False, "is_group": is_group, "items": []} %} + {% set _ = grouped_dict.update({group_name: group}) %} + {% else %} + {% set group = grouped_dict[group_name] %} + {% endif %} + + {# Make copies of the nav items, so we can modify the titles #} + {% if is_group %} + {% set item_copy = {"title": title, "url": nav_item.url, "active": nav_item.active, "children": nav_item.children} %} + {% set _ = group["items"].append(item_copy) %} + {% else %} + {% set _ = group["items"].append(nav_item) %} + {% endif %} + + {% if nav_item.__class__.__name__ == "Page" and nav_item.active %} + {% set _ = group.update({"active": True}) %} + {% endif %} + {% endfor %} +{% endmacro %} + +{# Taken from mkdocs-material v9.6.17 #} +{# https://github.com/squidfunk/mkdocs-material/blob/c89a66bf39bb7f472e925753367ff8e464e0d683/src/templates/partials/tabs-item.html#L67 #} +{% macro render_group_tab(group) %} + + {% set class = "md-tabs__item" %} + {% if group.active %} + {% set class = class ~ " md-tabs__item--active" %} + {% endif %} + +
  • + + {{ group.title }} + +
  • +{% endmacro %} + +{# Define the dictionary that will hold the grouped tabs #} +{# And then call the macro to populate the dictionary. This call produces no output. #} +{% set grouped_nav = {} %} +{{ group_tabs(nav, grouped_nav) }} + +{# -------------- ACTUAL RENDER STARTS HERE -------------- #} + +{% import "partials/tabs-item.html" as item with context %} + + + + + + + diff --git a/docs/overview/.nav.yml b/docs/overview/.nav.yml index 549671a4..7b961fa4 100644 --- a/docs/overview/.nav.yml +++ b/docs/overview/.nav.yml @@ -2,12 +2,6 @@ nav: - Welcome to Django Components: welcome.md - Compatibility: compatibility.md - - Installation: installation.md - Security notes 🚨: security_notes.md - - Migrating: migrating.md - - Community: community.md - - Contributing: contributing.md - - Development: development.md - Performance: performance.md - - Code of Conduct: code_of_conduct.md - License: license.md diff --git a/docs/overview/community.md b/docs/overview/community.md deleted file mode 100644 index 38a28394..00000000 --- a/docs/overview/community.md +++ /dev/null @@ -1,15 +0,0 @@ -## Community questions - -The best place to ask questions is in our [Github Discussion board](https://github.com/django-components/django-components/discussions). - -Please, before opening a new discussion, [check if similar discussion wasn't opened already](https://github.com/django-components/django-components/discussions?discussions_q=). - -## Community examples - -One of our goals with `django-components` is to make it easy to share components between projects -([see how to package components](../concepts/advanced/component_libraries.md)). -If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below. - -- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/). - -- [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/). diff --git a/docs/overview/performance.md b/docs/overview/performance.md index 90e463d7..187ba95f 100644 --- a/docs/overview/performance.md +++ b/docs/overview/performance.md @@ -1,3 +1,14 @@ We track the performance of `django-components` using [ASV](https://asv.readthedocs.io/en/stable/). See the [benchmarks dashboard](../../benchmarks). + +Our aim is to be at least as fast as Django templates. + +As of `0.130`, `django-components` is ~4x slower than Django templates. + +| | Render time| +|----------|----------------------| +| django | 68.9±0.6ms | +| django-components | 259±4ms | + +See the [full performance breakdown](https://django-components.github.io/django-components/latest/benchmarks/) for more information. diff --git a/docs/overview/welcome.md b/docs/overview/welcome.md index d703b048..a6bcf25a 100644 --- a/docs/overview/welcome.md +++ b/docs/overview/welcome.md @@ -515,31 +515,3 @@ def test_my_table(): {% calendar date="2024-11-06" %} {% endcalendar %} ``` - -## Performance - -Our aim is to be at least as fast as Django templates. - -As of `0.130`, `django-components` is ~4x slower than Django templates. - -| | Render time| -|----------|----------------------| -| django | 68.9±0.6ms | -| django-components | 259±4ms | - -See the [full performance breakdown](https://django-components.github.io/django-components/latest/benchmarks/) for more information. - -## Release notes - -Read the [Release Notes](../release_notes.md) -to see the latest features and fixes. - -## Community examples - -One of our goals with `django-components` is to make it easy to share components between projects. Head over to the [Community examples](./community.md#community-examples) to see some examples. - -## Contributing and development - -Get involved or sponsor this project - [See here](./contributing.md) - -Running django-components locally for development - [See here](./development.md) diff --git a/docs/plugins/.nav.yml b/docs/plugins/.nav.yml new file mode 100644 index 00000000..8d8b0191 --- /dev/null +++ b/docs/plugins/.nav.yml @@ -0,0 +1,3 @@ +# `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav +nav: + - index: index.md diff --git a/docs/plugins/index.md b/docs/plugins/index.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/reference/urls.md b/docs/reference/urls.md index ad750cde..1511a219 100644 --- a/docs/reference/urls.md +++ b/docs/reference/urls.md @@ -4,7 +4,7 @@ Below are all the URL patterns that will be added by adding `django_components.urls`. -See [Installation](../overview/installation.md#adding-support-for-js-and-css) +See [Installation](../getting_started/installation.md#adding-support-for-js-and-css) on how to add these URLs to your Django project. Django components already prefixes all URLs with `components/`. So when you are diff --git a/docs/release_notes.md b/docs/release_notes.md deleted file mode 100644 index 786b75d5..00000000 --- a/docs/release_notes.md +++ /dev/null @@ -1 +0,0 @@ ---8<-- "CHANGELOG.md" diff --git a/docs/scripts/gen_release_notes.py b/docs/scripts/gen_release_notes.py new file mode 100644 index 00000000..70c4804c --- /dev/null +++ b/docs/scripts/gen_release_notes.py @@ -0,0 +1,109 @@ +import pathlib +import re +from datetime import datetime + +import mkdocs_gen_files +from mkdocs_gen_files import Nav + +# Project root, relative to this script +ROOT = pathlib.Path(__file__).parent.parent.parent + + +def generate_release_notes(): + """ + Reads CHANGELOG.md, splits it into per-version pages, + and generates an index page with links to all versions. + """ + changelog_path = ROOT / "CHANGELOG.md" + releases_dir = pathlib.Path("releases") + + # Create the output directory if it doesn't exist + (ROOT / "docs" / releases_dir).mkdir(parents=True, exist_ok=True) + + with open(changelog_path, "r", encoding="utf-8") as f: + changelog_content = f.read() + + # Split the changelog by version headers (e.g., "## vX.Y.Z") + # The regex uses a positive lookahead (?=...) to keep the delimiter in the split part. + versions_raw = re.split(r"(?=^##\s+)", changelog_content, flags=re.MULTILINE) + + # The navigation object for the release notes section + release_nav = Nav() + + # The first item is the main title '# Release notes\n\n', so we skip it. + for version_chunk in versions_raw[1:]: + # The first line is the version header, e.g., "## v0.142.0" + header_line, body = version_chunk.strip().split("\n", 1) + + # Individual releases may contain the date of release, e.g. + # ```md + # ## 🚨📢 v0.100 + # _11 Sep 2024_ + # ``` + # + # We want to extract the date, and move it from the body to the title. + date_str = None + + # Check for date in format '_DD Mon YYYY_', e.g. "_11 Sep 2024_" + date_match = re.search(r"_(\d{1,2}\s+\w{3}\s+\d{4})_", body) + if date_match: + date_str = date_match.group(1) + body = body.replace(date_str, "").strip() + + # Extract the full title from the header, e.g., "🚨📢 v0.140.0" + version_title_full = header_line.replace("##", "").strip() + + # Get a clean version string for the filename, e.g., "v0.140.0", + # By removing any emojis, whitespace, and other non-alphanumeric characters. + version_string_clean, _ = re.subn(r"[^a-zA-Z0-9.-_]", "", version_title_full) + if not version_string_clean.startswith("v"): + version_string_clean = "v" + version_string_clean + + # Prepare title for navigation, e.g. "v0.140.0 (2024-09-11)" + nav_title = version_title_full + if date_str: + parsed_date = datetime.strptime(date_str, "%d %b %Y") + formatted_date = parsed_date.strftime("%Y-%m-%d") + nav_title += f" ({formatted_date})" + + # Generate file name like `v0.140.0.md` + filename = f"{version_string_clean}.md" + page_path = releases_dir / filename + + # Create the content for the individual release page + # We use the full title from the changelog for the page's H1 + page_content = f"# {nav_title}\n\n{body}" + + # Write the individual release page file + with mkdocs_gen_files.open(page_path.as_posix(), "w", encoding="utf-8") as f: + f.write(page_content) + + # Add this page to our navigation structure + release_nav[nav_title] = page_path.as_posix() + + # Generate the index page that lists all releases + index_path = releases_dir / "index.md" + with mkdocs_gen_files.open(index_path.as_posix(), "w", encoding="utf-8") as f: + f.write("# Release Notes\n\n") + f.write("Here you can find the release notes for all versions of Django-Components.\n\n") + + # Manually build the list with correct relative links + for nav_item in release_nav.items(): + if nav_item.title and nav_item.filename: + # nav_item.filename is like 'releases/v0.123.md'. We need just 'v0.123.md'. + relative_filename = pathlib.Path(nav_item.filename).name + f.write(f"* [{nav_item.title}]({relative_filename})\n") + + # Generate the .nav.yml file for ordering in the sidebar + nav_yml_path = releases_dir / ".nav.yml" + with mkdocs_gen_files.open(nav_yml_path.as_posix(), "w", encoding="utf-8") as f: + f.write("nav:\n") + f.write(" - index.md\n") + for nav_item in release_nav.items(): + if nav_item.filename: + relative_filename = pathlib.Path(nav_item.filename).name + f.write(f" - {relative_filename}\n") + + +# Run the script +generate_release_notes() diff --git a/docs/templates/reference_urls.md b/docs/templates/reference_urls.md index 05c1915a..f299aeaa 100644 --- a/docs/templates/reference_urls.md +++ b/docs/templates/reference_urls.md @@ -2,7 +2,7 @@ Below are all the URL patterns that will be added by adding `django_components.urls`. -See [Installation](../overview/installation.md#adding-support-for-js-and-css) +See [Installation](../getting_started/installation.md#adding-support-for-js-and-css) on how to add these URLs to your Django project. Django components already prefixes all URLs with `components/`. So when you are diff --git a/docs/upgrading/.nav.yml b/docs/upgrading/.nav.yml new file mode 100644 index 00000000..bf887b78 --- /dev/null +++ b/docs/upgrading/.nav.yml @@ -0,0 +1,3 @@ +# `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav +nav: + - Upgrading in pre-v1.0: v0.md \ No newline at end of file diff --git a/docs/overview/migrating.md b/docs/upgrading/v0.md similarity index 97% rename from docs/overview/migrating.md rename to docs/upgrading/v0.md index 63579b56..f56304ac 100644 --- a/docs/overview/migrating.md +++ b/docs/upgrading/v0.md @@ -6,8 +6,6 @@ We try to minimize the number of breaking changes, but sometimes it's unavoidabl When upgrading, please read the [Release notes](../../release_notes). -## Migrating in pre-v1.0 - If you're on older pre-v1.0 versions of django-components, we recommend doing step-wise upgrades in the following order: diff --git a/mkdocs.yml b/mkdocs.yml index 41b1a0a7..6258fff3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,8 +26,7 @@ validation: theme: name: "material" - # Uncomment to extend / override files from the theme - # custom_dir: docs/overrides + custom_dir: docs/overrides features: - content.action.edit - content.action.view @@ -124,6 +123,7 @@ plugins: scripts: - docs/scripts/setup.py - docs/scripts/reference.py + - docs/scripts/gen_release_notes.py - awesome-nav - git-revision-date-localized: enabled: !ENV [CI, false] diff --git a/scripts/supported_versions.py b/scripts/supported_versions.py index 3f366a36..f1971ef3 100644 --- a/scripts/supported_versions.py +++ b/scripts/supported_versions.py @@ -270,7 +270,7 @@ def main(): print() print() - print("Add this to docs/overview/development.md:\n") + print("Add this to docs/community/development.md:\n") pyenv = build_pyenv(python_to_django) print(pyenv) print()