diff --git a/dev/404.html b/dev/404.html index 6ac2a6f6..724d02b9 100644 --- a/dev/404.html +++ b/dev/404.html @@ -1 +1 @@ - Django-Components

404 - Not found

\ No newline at end of file + Django-Components

404 - Not found

\ No newline at end of file diff --git a/dev/concepts/advanced/component_caching/index.html b/dev/concepts/advanced/component_caching/index.html index fc273de3..c6ac7a1f 100644 --- a/dev/concepts/advanced/component_caching/index.html +++ b/dev/concepts/advanced/component_caching/index.html @@ -1,4 +1,4 @@ - Component caching - Django-Components
Skip to content

Component caching

Component caching allows you to store the rendered output of a component. Next time the component is rendered with the same input, the cached output is returned instead of re-rendering the component.

This is particularly useful for components that are expensive to render or do not change frequently.

Info

Component caching uses Django's cache framework, so you can use any cache backend that is supported by Django.

Enabling cachingยค

Caching is disabled by default.

To enable caching for a component, set Component.Cache.enabled to True:

from django_components import Component
+ Component caching - Django-Components      

Component caching

Component caching allows you to store the rendered output of a component. Next time the component is rendered with the same input, the cached output is returned instead of re-rendering the component.

This is particularly useful for components that are expensive to render or do not change frequently.

Info

Component caching uses Django's cache framework, so you can use any cache backend that is supported by Django.

Enabling cachingยค

Caching is disabled by default.

To enable caching for a component, set Component.Cache.enabled to True:

from django_components import Component
 
 class MyComponent(Component):
     class Cache:
diff --git a/dev/concepts/advanced/component_context_scope/index.html b/dev/concepts/advanced/component_context_scope/index.html
index 7afcebd5..c5041d86 100644
--- a/dev/concepts/advanced/component_context_scope/index.html
+++ b/dev/concepts/advanced/component_context_scope/index.html
@@ -1,4 +1,4 @@
- Component context and scope - Django-Components      

Component context and scope

By default, context variables are passed down the template as in regular Django - deeper scopes can access the variables from the outer scopes. So if you have several nested forloops, then inside the deep-most loop you can access variables defined by all previous loops.

With this in mind, the {% component %} tag behaves similarly to {% include %} tag - inside the component tag, you can access all variables that were defined outside of it.

And just like with {% include %}, if you don't want a specific component template to have access to the parent context, add only to the {% component %} tag:

{% component "calendar" date="2015-06-19" only / %}
+ Component context and scope - Django-Components      

Component context and scope

By default, context variables are passed down the template as in regular Django - deeper scopes can access the variables from the outer scopes. So if you have several nested forloops, then inside the deep-most loop you can access variables defined by all previous loops.

With this in mind, the {% component %} tag behaves similarly to {% include %} tag - inside the component tag, you can access all variables that were defined outside of it.

And just like with {% include %}, if you don't want a specific component template to have access to the parent context, add only to the {% component %} tag:

{% component "calendar" date="2015-06-19" only / %}
 

NOTE: {% csrf_token %} tags need access to the top-level context, and they will not function properly if they are rendered in a component that is called with the only modifier.

If you find yourself using the only modifier often, you can set the context_behavior option to "isolated", which automatically applies the only modifier. This is useful if you want to make sure that components don't accidentally access the outer context.

Components can also access the outer context in their context methods like get_template_data by accessing the property self.outer_context.

Example of Accessing Outer Contextยค

<div>
   {% component "calender" / %}
 </div>
diff --git a/dev/concepts/advanced/component_libraries/index.html b/dev/concepts/advanced/component_libraries/index.html
index fe43dc78..d9c37658 100644
--- a/dev/concepts/advanced/component_libraries/index.html
+++ b/dev/concepts/advanced/component_libraries/index.html
@@ -1,4 +1,4 @@
- Component libraries - Django-Components      

Component libraries

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.

Writing component librariesยค

  1. Create a Django project with a similar structure:

    project/
    + Component libraries - Django-Components      

    Component libraries

    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.

    Writing component librariesยค

    1. Create a Django project with a similar structure:

      project/
         |--  myapp/
           |--  __init__.py
           |--  apps.py
      diff --git a/dev/concepts/advanced/component_registry/index.html b/dev/concepts/advanced/component_registry/index.html
      index e6c874cf..7a251bc8 100644
      --- a/dev/concepts/advanced/component_registry/index.html
      +++ b/dev/concepts/advanced/component_registry/index.html
      @@ -1,4 +1,4 @@
      - Registering components - Django-Components      

      Registering components

      In previous examples you could repeatedly see us using @register() to "register" the components. In this section we dive deeper into what it actually means and how you can manage (add or remove) components.

      As a reminder, we may have a component like this:

      from django_components import Component, register
      + Registering components - Django-Components      

      Registering components

      In previous examples you could repeatedly see us using @register() to "register" the components. In this section we dive deeper into what it actually means and how you can manage (add or remove) components.

      As a reminder, we may have a component like this:

      from django_components import Component, register
       
       @register("calendar")
       class Calendar(Component):
      diff --git a/dev/concepts/advanced/extensions/index.html b/dev/concepts/advanced/extensions/index.html
      index a765da56..715210d6 100644
      --- a/dev/concepts/advanced/extensions/index.html
      +++ b/dev/concepts/advanced/extensions/index.html
      @@ -1,4 +1,4 @@
      - Extensions - Django-Components      

      Extensions

      New in version 0.131

      Django-components functionality can be extended with "extensions". Extensions allow for powerful customization and integrations. They can:

      • Tap into lifecycle events, such as when a component is created, deleted, registered, or unregistered.
      • Add new attributes and methods to the components under an extension-specific nested class.
      • Define custom commands that can be executed via the Django management command interface.

      Live examplesยค

      Install extensionsยค

      Extensions are configured in the Django settings under COMPONENTS.extensions.

      Extensions can be set by either as an import string or by passing in a class:

      # settings.py
      + Extensions - Django-Components      

      Extensions

      New in version 0.131

      Django-components functionality can be extended with "extensions". Extensions allow for powerful customization and integrations. They can:

      • Tap into lifecycle events, such as when a component is created, deleted, registered, or unregistered.
      • Add new attributes and methods to the components under an extension-specific nested class.
      • Define custom commands that can be executed via the Django management command interface.

      Live examplesยค

      Install extensionsยค

      Extensions are configured in the Django settings under COMPONENTS.extensions.

      Extensions can be set by either as an import string or by passing in a class:

      # settings.py
       
       class MyExtension(ComponentExtension):
           name = "my_extension"
      diff --git a/dev/concepts/advanced/hooks/index.html b/dev/concepts/advanced/hooks/index.html
      index 648a3612..c58ccf96 100644
      --- a/dev/concepts/advanced/hooks/index.html
      +++ b/dev/concepts/advanced/hooks/index.html
      @@ -1,4 +1,4 @@
      - Lifecycle hooks - Django-Components      

      Lifecycle hooks

      New in version 0.96

      Intercept the rendering lifecycle with Component hooks.

      Unlike the extension hooks, these are defined directly on the Component class.

      Available hooksยค

      on_render_beforeยค

      def on_render_before(
      + Lifecycle hooks - Django-Components      

      Lifecycle hooks

      New in version 0.96

      Intercept the rendering lifecycle with Component hooks.

      Unlike the extension hooks, these are defined directly on the Component class.

      Available hooksยค

      on_render_beforeยค

      def on_render_before(
           self: Component,
           context: Context,
           template: Optional[Template],
      diff --git a/dev/concepts/advanced/html_fragments/index.html b/dev/concepts/advanced/html_fragments/index.html
      index e00c72ed..64948a92 100644
      --- a/dev/concepts/advanced/html_fragments/index.html
      +++ b/dev/concepts/advanced/html_fragments/index.html
      @@ -1,4 +1,4 @@
      - HTML fragments - Django-Components      

      HTML fragments

      Django-components provides a seamless integration with HTML fragments with AJAX (HTML over the wire), whether you're using jQuery, HTMX, AlpineJS, vanilla JavaScript, or other.

      If the fragment component has any JS or CSS, django-components will:

      • Automatically load the associated JS and CSS
      • Ensure that JS is loaded and executed only once even if the fragment is inserted multiple times

      Info

      What are HTML fragments and "HTML over the wire"?

      It is one of the methods for updating the state in the browser UI upon user interaction.

      How it works is that:

      1. User makes an action - clicks a button or submits a form
      2. The action causes a request to be made from the client to the server.
      3. Server processes the request (e.g. form submission), and responds with HTML of some part of the UI (e.g. a new entry in a table).
      4. A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.

      Document and fragment strategiesยค

      Components support different "strategies" for rendering JS and CSS.

      Two of them are used to enable HTML fragments - "document" and "fragment".

      What's the difference?

      Document strategyยค

      Document strategy assumes that the rendered components will be embedded into the HTML of the initial page load. This means that:

      • The JS and CSS is embedded into the HTML as <script> and <style> tags (see Default JS / CSS locations)
      • Django-components injects a JS script for managing JS and CSS assets

      A component is rendered as a "document" when:

      Example:

      MyTable.render(
      + HTML fragments - Django-Components      

      HTML fragments

      Django-components provides a seamless integration with HTML fragments with AJAX (HTML over the wire), whether you're using jQuery, HTMX, AlpineJS, vanilla JavaScript, or other.

      If the fragment component has any JS or CSS, django-components will:

      • Automatically load the associated JS and CSS
      • Ensure that JS is loaded and executed only once even if the fragment is inserted multiple times

      Info

      What are HTML fragments and "HTML over the wire"?

      It is one of the methods for updating the state in the browser UI upon user interaction.

      How it works is that:

      1. User makes an action - clicks a button or submits a form
      2. The action causes a request to be made from the client to the server.
      3. Server processes the request (e.g. form submission), and responds with HTML of some part of the UI (e.g. a new entry in a table).
      4. A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.

      Document and fragment strategiesยค

      Components support different "strategies" for rendering JS and CSS.

      Two of them are used to enable HTML fragments - "document" and "fragment".

      What's the difference?

      Document strategyยค

      Document strategy assumes that the rendered components will be embedded into the HTML of the initial page load. This means that:

      • The JS and CSS is embedded into the HTML as <script> and <style> tags (see Default JS / CSS locations)
      • Django-components injects a JS script for managing JS and CSS assets

      A component is rendered as a "document" when:

      Example:

      MyTable.render(
           kwargs={...},
       )
       
      diff --git a/dev/concepts/advanced/provide_inject/index.html b/dev/concepts/advanced/provide_inject/index.html
      index 6c89417a..120f2155 100644
      --- a/dev/concepts/advanced/provide_inject/index.html
      +++ b/dev/concepts/advanced/provide_inject/index.html
      @@ -1,4 +1,4 @@
      - Prop drilling and provide / inject - Django-Components      

      Prop drilling and provide / inject

      New in version 0.80:

      django-components supports the provide / inject pattern, similarly to React's Context Providers or Vue's provide / inject.

      This is achieved with the combination of:

      What is "prop drilling"ยค

      Prop drilling refers to a scenario in UI development where you need to pass data through many layers of a component tree to reach the nested components that actually need the data.

      Normally, you'd use props to send data from a parent component to its children. However, this straightforward method becomes cumbersome and inefficient if the data has to travel through many levels or if several components scattered at different depths all need the same piece of information.

      This results in a situation where the intermediate components, which don't need the data for their own functioning, end up having to manage and pass along these props. This clutters the component tree and makes the code verbose and harder to manage.

      A neat solution to avoid prop drilling is using the "provide and inject" technique.

      With provide / inject, a parent component acts like a data hub for all its descendants. This setup allows any component, no matter how deeply nested it is, to access the required data directly from this centralized provider without having to messily pass props down the chain. This approach significantly cleans up the code and makes it easier to maintain.

      This feature is inspired by Vue's Provide / Inject and React's Context / useContext.

      As the name suggest, using provide / inject consists of 2 steps

      1. Providing data
      2. Injecting provided data

      For examples of advanced uses of provide / inject, see this discussion.

      Providing dataยค

      First we use the {% provide %} tag to define the data we want to "provide" (make available).

      {% provide "my_data" hello="hi" another=123 %}
      + Prop drilling and provide / inject - Django-Components      

      Prop drilling and provide / inject

      New in version 0.80:

      django-components supports the provide / inject pattern, similarly to React's Context Providers or Vue's provide / inject.

      This is achieved with the combination of:

      What is "prop drilling"ยค

      Prop drilling refers to a scenario in UI development where you need to pass data through many layers of a component tree to reach the nested components that actually need the data.

      Normally, you'd use props to send data from a parent component to its children. However, this straightforward method becomes cumbersome and inefficient if the data has to travel through many levels or if several components scattered at different depths all need the same piece of information.

      This results in a situation where the intermediate components, which don't need the data for their own functioning, end up having to manage and pass along these props. This clutters the component tree and makes the code verbose and harder to manage.

      A neat solution to avoid prop drilling is using the "provide and inject" technique.

      With provide / inject, a parent component acts like a data hub for all its descendants. This setup allows any component, no matter how deeply nested it is, to access the required data directly from this centralized provider without having to messily pass props down the chain. This approach significantly cleans up the code and makes it easier to maintain.

      This feature is inspired by Vue's Provide / Inject and React's Context / useContext.

      As the name suggest, using provide / inject consists of 2 steps

      1. Providing data
      2. Injecting provided data

      For examples of advanced uses of provide / inject, see this discussion.

      Providing dataยค

      First we use the {% provide %} tag to define the data we want to "provide" (make available).

      {% provide "my_data" hello="hi" another=123 %}
           {% component "child" / %}  <--- Can access "my_data"
       {% endprovide %}
       
      diff --git a/dev/concepts/advanced/rendering_js_css/index.html b/dev/concepts/advanced/rendering_js_css/index.html
      index 7e8c3f48..ca68ac6f 100644
      --- a/dev/concepts/advanced/rendering_js_css/index.html
      +++ b/dev/concepts/advanced/rendering_js_css/index.html
      @@ -1,4 +1,4 @@
      - Rendering JS / CSS - Django-Components      

      Rendering JS / CSS

      Introductionยค

      Components consist of 3 parts - HTML, JS and CSS.

      Handling of HTML is straightforward - it is rendered as is, and inserted where the {% component %} tag is.

      However, handling of JS and CSS is more complex:

      • JS and CSS is are inserted elsewhere in the HTML. As a best practice, JS is placed in the <body> HTML tag, and CSS in the <head>.
      • Multiple components may use the same JS and CSS files. We don't want to load the same files multiple times.
      • Fetching of JS and CSS may block the page, so the JS / CSS should be embedded in the HTML.
      • Components inserted as HTML fragments need different handling for JS and CSS.

      Default JS / CSS locationsยค

      If your components use JS and CSS then, by default, the JS and CSS will be automatically inserted into the HTML:

      • CSS styles will be inserted at the end of the <head>
      • JS scripts will be inserted at the end of the <body>

      If you want to place the dependencies elsewhere in the HTML, you can override the locations by inserting following Django template tags:

      So if you have a component with JS and CSS:

      from django_components import Component, types
      + Rendering JS / CSS - Django-Components      

      Rendering JS / CSS

      Introductionยค

      Components consist of 3 parts - HTML, JS and CSS.

      Handling of HTML is straightforward - it is rendered as is, and inserted where the {% component %} tag is.

      However, handling of JS and CSS is more complex:

      • JS and CSS is are inserted elsewhere in the HTML. As a best practice, JS is placed in the <body> HTML tag, and CSS in the <head>.
      • Multiple components may use the same JS and CSS files. We don't want to load the same files multiple times.
      • Fetching of JS and CSS may block the page, so the JS / CSS should be embedded in the HTML.
      • Components inserted as HTML fragments need different handling for JS and CSS.

      Default JS / CSS locationsยค

      If your components use JS and CSS then, by default, the JS and CSS will be automatically inserted into the HTML:

      • CSS styles will be inserted at the end of the <head>
      • JS scripts will be inserted at the end of the <body>

      If you want to place the dependencies elsewhere in the HTML, you can override the locations by inserting following Django template tags:

      So if you have a component with JS and CSS:

      from django_components import Component, types
       
       class MyButton(Component):
           template: types.django_html = """
      diff --git a/dev/concepts/advanced/tag_formatters/index.html b/dev/concepts/advanced/tag_formatters/index.html
      index a65221a9..ae472bbd 100644
      --- a/dev/concepts/advanced/tag_formatters/index.html
      +++ b/dev/concepts/advanced/tag_formatters/index.html
      @@ -1,4 +1,4 @@
      - Tag formatters - Django-Components      

      Tag formatters

      Customizing component tags with TagFormatterยค

      New in version 0.89

      By default, components are rendered using the pair of {% component %} / {% endcomponent %} template tags:

      {% component "button" href="..." disabled %}
      + Tag formatters - Django-Components      

      Tag formatters

      Customizing component tags with TagFormatterยค

      New in version 0.89

      By default, components are rendered using the pair of {% component %} / {% endcomponent %} template tags:

      {% component "button" href="..." disabled %}
       Click me!
       {% endcomponent %}
       
      diff --git a/dev/concepts/advanced/template_tags/index.html b/dev/concepts/advanced/template_tags/index.html
      index caaf8d69..ed02f2af 100644
      --- a/dev/concepts/advanced/template_tags/index.html
      +++ b/dev/concepts/advanced/template_tags/index.html
      @@ -1,4 +1,4 @@
      - Custom template tags - Django-Components      

      Custom template tags

      Template tags introduced by django-components, such as {% component %} and {% slot %}, offer additional features over the default Django template tags:

      django-components/django-components

      Custom template tags

      Template tags introduced by django-components, such as {% component %} and {% slot %}, offer additional features over the default Django template tags:

      You too can easily create custom template tags that use the above features.

      Defining template tags with @template_tagยค

      The simplest way to create a custom template tag is using the template_tag decorator. This decorator allows you to define a template tag by just writing a function that returns the rendered content.

      from django.template import Context, Library
      diff --git a/dev/concepts/advanced/testing/index.html b/dev/concepts/advanced/testing/index.html
      index 9a5fd552..79067eec 100644
      --- a/dev/concepts/advanced/testing/index.html
      +++ b/dev/concepts/advanced/testing/index.html
      @@ -1,4 +1,4 @@
      - Testing - Django-Components      

      Testing

      New in version 0.131

      The @djc_test decorator is a powerful tool for testing components created with django-components. It ensures that each test is properly isolated, preventing components registered in one test from affecting others.

      Usageยค

      The @djc_test decorator can be applied to functions, methods, or classes.

      When applied to a class, it decorates all methods starting with test_, and all nested classes starting with Test, recursively.

      Applying to a Functionยค

      To apply djc_test to a function, simply decorate the function as shown below:

      import django
      + Testing - Django-Components      

      Testing

      New in version 0.131

      The @djc_test decorator is a powerful tool for testing components created with django-components. It ensures that each test is properly isolated, preventing components registered in one test from affecting others.

      Usageยค

      The @djc_test decorator can be applied to functions, methods, or classes.

      When applied to a class, it decorates all methods starting with test_, and all nested classes starting with Test, recursively.

      Applying to a Functionยค

      To apply djc_test to a function, simply decorate the function as shown below:

      import django
       from django_components.testing import djc_test
       
       @djc_test
      diff --git a/dev/concepts/fundamentals/autodiscovery/index.html b/dev/concepts/fundamentals/autodiscovery/index.html
      index fa21a07d..2edaa14d 100644
      --- a/dev/concepts/fundamentals/autodiscovery/index.html
      +++ b/dev/concepts/fundamentals/autodiscovery/index.html
      @@ -1,4 +1,4 @@
      - Autodiscovery - Django-Components      

      Autodiscovery

      django-components automatically searches for files containing components in the COMPONENTS.dirs and COMPONENTS.app_dirs directories.

      Manually register componentsยค

      Every component that you want to use in the template with the {% component %} tag needs to be registered with the ComponentRegistry.

      We use the @register decorator for that:

      from django_components import Component, register
      + Autodiscovery - Django-Components      

      Autodiscovery

      django-components automatically searches for files containing components in the COMPONENTS.dirs and COMPONENTS.app_dirs directories.

      Manually register componentsยค

      Every component that you want to use in the template with the {% component %} tag needs to be registered with the ComponentRegistry.

      We use the @register decorator for that:

      from django_components import Component, register
       
       @register("calendar")
       class Calendar(Component):
      diff --git a/dev/concepts/fundamentals/component_defaults/index.html b/dev/concepts/fundamentals/component_defaults/index.html
      index e85b9631..50158b6f 100644
      --- a/dev/concepts/fundamentals/component_defaults/index.html
      +++ b/dev/concepts/fundamentals/component_defaults/index.html
      @@ -1,4 +1,4 @@
      - Component defaults - Django-Components      

      Component defaults

      When a component is being rendered, the component inputs are passed to various methods like get_template_data(), get_js_data(), or get_css_data().

      It can be cumbersome to specify default values for each input in each method.

      To make things easier, Components can specify their defaults. Defaults are used when no value is provided, or when the value is set to None for a particular input.

      Defining defaultsยค

      To define defaults for a component, you create a nested Defaults class within your Component class. Each attribute in the Defaults class represents a default value for a corresponding input.

      from django_components import Component, Default, register
      + Component defaults - Django-Components      

      Component defaults

      When a component is being rendered, the component inputs are passed to various methods like get_template_data(), get_js_data(), or get_css_data().

      It can be cumbersome to specify default values for each input in each method.

      To make things easier, Components can specify their defaults. Defaults are used when no value is provided, or when the value is set to None for a particular input.

      Defining defaultsยค

      To define defaults for a component, you create a nested Defaults class within your Component class. Each attribute in the Defaults class represents a default value for a corresponding input.

      from django_components import Component, Default, register
       
       @register("my_table")
       class MyTable(Component):
      diff --git a/dev/concepts/fundamentals/component_views_urls/index.html b/dev/concepts/fundamentals/component_views_urls/index.html
      index fa42d8dc..83197506 100644
      --- a/dev/concepts/fundamentals/component_views_urls/index.html
      +++ b/dev/concepts/fundamentals/component_views_urls/index.html
      @@ -1,4 +1,4 @@
      - Component views and URLs - Django-Components      

      Component views and URLs

      New in version 0.34

      Note: Since 0.92, Component is no longer a subclass of Django's View. Instead, the nested Component.View class is a subclass of Django's View.


      For web applications, it's common to define endpoints that serve HTML content (AKA views).

      django-components has a suite of features that help you write and manage views and their URLs:

      • For each component, you can define methods for handling HTTP requests (GET, POST, etc.) - get(), post(), etc.

      • Use Component.as_view() to be able to use your Components with Django's urlpatterns. This works the same way as View.as_view().

      • To avoid having to manually define the endpoints for each component, you can set the component to be "public" with Component.View.public = True. This will automatically create a URL for the component. To retrieve the component URL, use get_component_url().

      • In addition, Component has a render_to_response() method that renders the component template based on the provided input and returns an HttpResponse object.

      Define handlersยค

      Here's an example of a calendar component defined as a view. Simply define a View class with your custom get() method to handle GET requests:

      [project root]/components/calendar.py
      from django_components import Component, ComponentView, register
      + Component views and URLs - Django-Components      

      Component views and URLs

      New in version 0.34

      Note: Since 0.92, Component is no longer a subclass of Django's View. Instead, the nested Component.View class is a subclass of Django's View.


      For web applications, it's common to define endpoints that serve HTML content (AKA views).

      django-components has a suite of features that help you write and manage views and their URLs:

      • For each component, you can define methods for handling HTTP requests (GET, POST, etc.) - get(), post(), etc.

      • Use Component.as_view() to be able to use your Components with Django's urlpatterns. This works the same way as View.as_view().

      • To avoid having to manually define the endpoints for each component, you can set the component to be "public" with Component.View.public = True. This will automatically create a URL for the component. To retrieve the component URL, use get_component_url().

      • In addition, Component has a render_to_response() method that renders the component template based on the provided input and returns an HttpResponse object.

      Define handlersยค

      Here's an example of a calendar component defined as a view. Simply define a View class with your custom get() method to handle GET requests:

      [project root]/components/calendar.py
      from django_components import Component, ComponentView, register
       
       @register("calendar")
       class Calendar(Component):
      diff --git a/dev/concepts/fundamentals/html_attributes/index.html b/dev/concepts/fundamentals/html_attributes/index.html
      index 7aff3fe7..6fb5f630 100644
      --- a/dev/concepts/fundamentals/html_attributes/index.html
      +++ b/dev/concepts/fundamentals/html_attributes/index.html
      @@ -1,4 +1,4 @@
      - HTML attributes - Django-Components      

      HTML attributes

      New in version 0.74:

      You can use the {% html_attrs %} tag to render various data as key="value" HTML attributes.

      {% html_attrs %} tag is versatile, allowing you to define HTML attributes however you need:

      • Define attributes within the HTML template
      • Define attributes in Python code
      • Merge attributes from multiple sources
      • Boolean attributes
      • Append attributes
      • Remove attributes
      • Define default attributes

      From v0.135 onwards, {% html_attrs %} tag also supports merging style and class attributes the same way how Vue does.

      To get started, let's consider a simple example. If you have a template:

      <div class="{{ classes }}" data-id="{{ my_id }}">
      + HTML attributes - Django-Components      

      HTML attributes

      New in version 0.74:

      You can use the {% html_attrs %} tag to render various data as key="value" HTML attributes.

      {% html_attrs %} tag is versatile, allowing you to define HTML attributes however you need:

      • Define attributes within the HTML template
      • Define attributes in Python code
      • Merge attributes from multiple sources
      • Boolean attributes
      • Append attributes
      • Remove attributes
      • Define default attributes

      From v0.135 onwards, {% html_attrs %} tag also supports merging style and class attributes the same way how Vue does.

      To get started, let's consider a simple example. If you have a template:

      <div class="{{ classes }}" data-id="{{ my_id }}">
       </div>
       

      You can rewrite it with the {% html_attrs %} tag:

      <div {% html_attrs class=classes data-id=my_id %}>
       </div>
      diff --git a/dev/concepts/fundamentals/html_js_css_files/index.html b/dev/concepts/fundamentals/html_js_css_files/index.html
      index 25649385..21b25c4a 100644
      --- a/dev/concepts/fundamentals/html_js_css_files/index.html
      +++ b/dev/concepts/fundamentals/html_js_css_files/index.html
      @@ -1,4 +1,4 @@
      - HTML / JS / CSS files - Django-Components      

      HTML / JS / CSS files

      Overviewยค

      Each component can have single "primary" HTML, CSS and JS file associated with them.

      Each of these can be either defined inline, or in a separate file:

      @register("calendar")
      + HTML / JS / CSS files - Django-Components      

      HTML / JS / CSS files

      Overviewยค

      Each component can have single "primary" HTML, CSS and JS file associated with them.

      Each of these can be either defined inline, or in a separate file:

      @register("calendar")
       class Calendar(Component):
           template_file = "calendar.html"
           css_file = "calendar.css"
      diff --git a/dev/concepts/fundamentals/html_js_css_variables/index.html b/dev/concepts/fundamentals/html_js_css_variables/index.html
      index a4475e4d..981b83d6 100644
      --- a/dev/concepts/fundamentals/html_js_css_variables/index.html
      +++ b/dev/concepts/fundamentals/html_js_css_variables/index.html
      @@ -1,4 +1,4 @@
      - HTML / JS / CSS variables - Django-Components      

      HTML / JS / CSS variables

      When a component recieves input through {% component %} tag, or the Component.render() or Component.render_to_response() methods, you can define how the input is handled, and what variables will be available to the template, JavaScript and CSS.

      Overviewยค

      Django Components offers three key methods for passing variables to different parts of your component:

      These methods let you pre-process inputs before they're used in rendering.

      Each method handles the data independently - you can define different data for the template, JS, and CSS.

      class ProfileCard(Component):
      + HTML / JS / CSS variables - Django-Components      

      HTML / JS / CSS variables

      When a component recieves input through {% component %} tag, or the Component.render() or Component.render_to_response() methods, you can define how the input is handled, and what variables will be available to the template, JavaScript and CSS.

      Overviewยค

      Django Components offers three key methods for passing variables to different parts of your component:

      These methods let you pre-process inputs before they're used in rendering.

      Each method handles the data independently - you can define different data for the template, JS, and CSS.

      class ProfileCard(Component):
           class Kwargs(NamedTuple):
               user_id: int
               show_details: bool
      diff --git a/dev/concepts/fundamentals/http_request/index.html b/dev/concepts/fundamentals/http_request/index.html
      index f1bd19fc..d4dd1fa7 100644
      --- a/dev/concepts/fundamentals/http_request/index.html
      +++ b/dev/concepts/fundamentals/http_request/index.html
      @@ -1,4 +1,4 @@
      - HTTP Request - Django-Components      

      HTTP Request

      The most common use of django-components is to render HTML when the server receives a request. As such, there are a few features that are dependent on the request object.

      Passing the HttpRequest objectยค

      In regular Django templates, the request object is available only within the RequestContext.

      In Components, you can either use RequestContext, or pass the request object explicitly to Component.render() and Component.render_to_response().

      So the request object is available to components either when:

      • The component is rendered with RequestContext (Regular Django behavior)
      • The component is rendered with a regular Context (or none), but you set the request kwarg of Component.render().
      • The component is nested and the parent has access to the request object.
      # โœ… With request
      + HTTP Request - Django-Components      

      HTTP Request

      The most common use of django-components is to render HTML when the server receives a request. As such, there are a few features that are dependent on the request object.

      Passing the HttpRequest objectยค

      In regular Django templates, the request object is available only within the RequestContext.

      In Components, you can either use RequestContext, or pass the request object explicitly to Component.render() and Component.render_to_response().

      So the request object is available to components either when:

      • The component is rendered with RequestContext (Regular Django behavior)
      • The component is rendered with a regular Context (or none), but you set the request kwarg of Component.render().
      • The component is nested and the parent has access to the request object.
      # โœ… With request
       MyComponent.render(request=request)
       MyComponent.render(context=RequestContext(request, {}))
       
      diff --git a/dev/concepts/fundamentals/render_api/index.html b/dev/concepts/fundamentals/render_api/index.html
      index 89dc1a9a..cbbbc837 100644
      --- a/dev/concepts/fundamentals/render_api/index.html
      +++ b/dev/concepts/fundamentals/render_api/index.html
      @@ -1,4 +1,4 @@
      - Render API - Django-Components      

      Render API

      When a component is being rendered, whether with Component.render() or {% component %}, a component instance is populated with the current inputs and context. This allows you to access things like component inputs.

      We refer to these render-time-only methods and attributes as the "Render API".

      Render API is available inside these Component methods:

      Example:

      class Table(Component):
      + Render API - Django-Components      

      Render API

      When a component is being rendered, whether with Component.render() or {% component %}, a component instance is populated with the current inputs and context. This allows you to access things like component inputs.

      We refer to these render-time-only methods and attributes as the "Render API".

      Render API is available inside these Component methods:

      Example:

      class Table(Component):
           def on_render_before(self, context, template):
               # Access component's ID
               assert self.id == "c1A2b3c"
      diff --git a/dev/concepts/fundamentals/rendering_components/index.html b/dev/concepts/fundamentals/rendering_components/index.html
      index 8404728c..6ee8ecdd 100644
      --- a/dev/concepts/fundamentals/rendering_components/index.html
      +++ b/dev/concepts/fundamentals/rendering_components/index.html
      @@ -1,4 +1,4 @@
      - Rendering components - Django-Components      

      Rendering components

      Your components can be rendered either within your Django templates, or directly in Python code.

      Overviewยค

      Django Components provides three main methods to render components:

      {% component %} tagยค

      Use the {% component %} tag to render a component within your Django templates.

      The {% component %} tag takes:

      • Component's registered name as the first positional argument,
      • Followed by any number of positional and keyword arguments.
      {% load component_tags %}
      + Rendering components - Django-Components      

      Rendering components

      Your components can be rendered either within your Django templates, or directly in Python code.

      Overviewยค

      Django Components provides three main methods to render components:

      {% component %} tagยค

      Use the {% component %} tag to render a component within your Django templates.

      The {% component %} tag takes:

      • Component's registered name as the first positional argument,
      • Followed by any number of positional and keyword arguments.
      {% load component_tags %}
       <div>
         {% component "button" name="John" job="Developer" / %}
       </div>
      diff --git a/dev/concepts/fundamentals/secondary_js_css_files/index.html b/dev/concepts/fundamentals/secondary_js_css_files/index.html
      index 7b65e077..81b48281 100644
      --- a/dev/concepts/fundamentals/secondary_js_css_files/index.html
      +++ b/dev/concepts/fundamentals/secondary_js_css_files/index.html
      @@ -1,4 +1,4 @@
      - Secondary JS / CSS files - Django-Components      

      Secondary JS / CSS files

      Overviewยค

      Each component can define extra or "secondary" CSS / JS files using the nested Component.Media class, by setting Component.Media.js and Component.Media.css.

      The main HTML / JS / CSS files are limited to 1 per component. This is not the case for the secondary files, where components can have many of them.

      There is also no special behavior or post-processing for these secondary files, they are loaded as is.

      You can use these for third-party libraries, or for shared CSS / JS files.

      These must be set as paths, URLs, or custom objects.

      @register("calendar")
      + Secondary JS / CSS files - Django-Components      

      Secondary JS / CSS files

      Overviewยค

      Each component can define extra or "secondary" CSS / JS files using the nested Component.Media class, by setting Component.Media.js and Component.Media.css.

      The main HTML / JS / CSS files are limited to 1 per component. This is not the case for the secondary files, where components can have many of them.

      There is also no special behavior or post-processing for these secondary files, they are loaded as is.

      You can use these for third-party libraries, or for shared CSS / JS files.

      These must be set as paths, URLs, or custom objects.

      @register("calendar")
       class Calendar(Component):
           class Media:
               js = [
      diff --git a/dev/concepts/fundamentals/single_file_components/index.html b/dev/concepts/fundamentals/single_file_components/index.html
      index 5ca704ac..3e7d38d8 100644
      --- a/dev/concepts/fundamentals/single_file_components/index.html
      +++ b/dev/concepts/fundamentals/single_file_components/index.html
      @@ -1,4 +1,4 @@
      - Single-file components - Django-Components      

      Single-file components

      Components can be defined in a single file, inlining the HTML, JS and CSS within the Python code.

      Writing single file componentsยค

      To do this, you can use the template, js, and css class attributes instead of the template_file, js_file, and css_file.

      For example, here's the calendar component from the Getting started tutorial:

      calendar.py
      from django_components import Component
      + Single-file components - Django-Components      

      Single-file components

      Components can be defined in a single file, inlining the HTML, JS and CSS within the Python code.

      Writing single file componentsยค

      To do this, you can use the template, js, and css class attributes instead of the template_file, js_file, and css_file.

      For example, here's the calendar component from the Getting started tutorial:

      calendar.py
      from django_components import Component
       
       class Calendar(Component):
           template_file = "calendar.html"
      diff --git a/dev/concepts/fundamentals/slots/index.html b/dev/concepts/fundamentals/slots/index.html
      index 87a68c0e..2827d982 100644
      --- a/dev/concepts/fundamentals/slots/index.html
      +++ b/dev/concepts/fundamentals/slots/index.html
      @@ -1,4 +1,4 @@
      - Slots - Django-Components      

      Slots

      django-components has the most extensive slot system of all the popular Python templating engines.

      The slot system is based on Vue, and works across both Django templates and Python code.

      What are slots?ยค

      Components support something called 'slots'.

      When you write a component, you define its template. The template will always be the same each time you render the component.

      However, sometimes you may want to customize the component slightly to change the content of the component. This is where slots come in.

      Slots allow you to insert parts of HTML into the component. This makes components more reusable and composable.

      <div class="calendar-component">
      + Slots - Django-Components      

      Slots

      django-components has the most extensive slot system of all the popular Python templating engines.

      The slot system is based on Vue, and works across both Django templates and Python code.

      What are slots?ยค

      Components support something called 'slots'.

      When you write a component, you define its template. The template will always be the same each time you render the component.

      However, sometimes you may want to customize the component slightly to change the content of the component. This is where slots come in.

      Slots allow you to insert parts of HTML into the component. This makes components more reusable and composable.

      <div class="calendar-component">
           <div class="header">
               {# This is where the component will insert the content #}
               {% slot "header" / %}
      diff --git a/dev/concepts/fundamentals/subclassing_components/index.html b/dev/concepts/fundamentals/subclassing_components/index.html
      index 9d10da51..3c288b85 100644
      --- a/dev/concepts/fundamentals/subclassing_components/index.html
      +++ b/dev/concepts/fundamentals/subclassing_components/index.html
      @@ -1,4 +1,4 @@
      - Subclassing components - Django-Components      

      Subclassing components

      In larger projects, you might need to write multiple components with similar behavior. In such cases, you can extract shared behavior into a standalone component class to keep things DRY.

      When subclassing a component, there's a couple of things to keep in mind:

      Template, JS, and CSS inheritanceยค

      When it comes to the pairs:

      inheritance follows these rules:

      • If a child component class defines either member of a pair (e.g., either template or template_file), it takes precedence and the parent's definition is ignored completely.
      • For example, if a child component defines template_file, the parent's template or template_file will be ignored.
      • This applies independently to each pair - you can inherit the JS while overriding the template, for instance.

      For example:

      class BaseCard(Component):
      + Subclassing components - Django-Components      

      Subclassing components

      In larger projects, you might need to write multiple components with similar behavior. In such cases, you can extract shared behavior into a standalone component class to keep things DRY.

      When subclassing a component, there's a couple of things to keep in mind:

      Template, JS, and CSS inheritanceยค

      When it comes to the pairs:

      inheritance follows these rules:

      • If a child component class defines either member of a pair (e.g., either template or template_file), it takes precedence and the parent's definition is ignored completely.
      • For example, if a child component defines template_file, the parent's template or template_file will be ignored.
      • This applies independently to each pair - you can inherit the JS while overriding the template, for instance.

      For example:

      class BaseCard(Component):
           template = """
               <div class="card">
                   <div class="card-content">{{ content }}</div>
      diff --git a/dev/concepts/fundamentals/template_tag_syntax/index.html b/dev/concepts/fundamentals/template_tag_syntax/index.html
      index 62b7cb52..07995cf9 100644
      --- a/dev/concepts/fundamentals/template_tag_syntax/index.html
      +++ b/dev/concepts/fundamentals/template_tag_syntax/index.html
      @@ -1,4 +1,4 @@
      - Template tag syntax - Django-Components      

      Template tag syntax

      All template tags in django_component, like {% component %} or {% slot %}, and so on, support extra syntax that makes it possible to write components like in Vue or React (JSX).

      Self-closing tagsยค

      When you have a tag like {% component %} or {% slot %}, but it has no content, you can simply append a forward slash / at the end, instead of writing out the closing tags like {% endcomponent %} or {% endslot %}:

      So this:

      {% component "button" %}{% endcomponent %}
      + Template tag syntax - Django-Components      

      Template tag syntax

      All template tags in django_component, like {% component %} or {% slot %}, and so on, support extra syntax that makes it possible to write components like in Vue or React (JSX).

      Self-closing tagsยค

      When you have a tag like {% component %} or {% slot %}, but it has no content, you can simply append a forward slash / at the end, instead of writing out the closing tags like {% endcomponent %} or {% endslot %}:

      So this:

      {% component "button" %}{% endcomponent %}
       

      becomes

      {% component "button" / %}
       

      Special charactersยค

      New in version 0.71:

      Keyword arguments can contain special characters # @ . - _, so keywords like so are still valid:

      <body>
           {% component "calendar" my-date="2015-06-19" @click.native=do_something #some_id=True / %}
      diff --git a/dev/concepts/fundamentals/typing_and_validation/index.html b/dev/concepts/fundamentals/typing_and_validation/index.html
      index 1eb52385..ec39bf3a 100644
      --- a/dev/concepts/fundamentals/typing_and_validation/index.html
      +++ b/dev/concepts/fundamentals/typing_and_validation/index.html
      @@ -1,4 +1,4 @@
      - Typing and validation - Django-Components      

      Typing and validation

      Typing overviewยค

      Warning

      In versions 0.92 to 0.139 (inclusive), the component typing was specified through generics.

      Since v0.140, the types must be specified as class attributes of the Component class - Args, Kwargs, Slots, TemplateData, JsData, and CssData.

      See Migrating from generics to class attributes for more info.

      Warning

      Input validation was NOT part of Django Components between versions 0.136 and 0.139 (inclusive).

      The Component class optionally accepts class attributes that allow you to define the types of args, kwargs, slots, as well as the data returned from the data methods.

      Use this to add type hints to your components, to validate the inputs at runtime, and to document them.

      from typing import NamedTuple, Optional
      + Typing and validation - Django-Components      

      Typing and validation

      Typing overviewยค

      Warning

      In versions 0.92 to 0.139 (inclusive), the component typing was specified through generics.

      Since v0.140, the types must be specified as class attributes of the Component class - Args, Kwargs, Slots, TemplateData, JsData, and CssData.

      See Migrating from generics to class attributes for more info.

      Warning

      Input validation was NOT part of Django Components between versions 0.136 and 0.139 (inclusive).

      The Component class optionally accepts class attributes that allow you to define the types of args, kwargs, slots, as well as the data returned from the data methods.

      Use this to add type hints to your components, to validate the inputs at runtime, and to document them.

      from typing import NamedTuple, Optional
       from django.template import Context
       from django_components import Component, SlotInput
       
      diff --git a/dev/getting_started/adding_js_and_css/index.html b/dev/getting_started/adding_js_and_css/index.html
      index 7c6faf5e..dea567cf 100644
      --- a/dev/getting_started/adding_js_and_css/index.html
      +++ b/dev/getting_started/adding_js_and_css/index.html
      @@ -1,4 +1,4 @@
      - Adding JS and CSS - Django-Components      

      Adding JS and CSS

      Next we will add CSS and JavaScript to our template.

      Info

      In django-components, using JS and CSS is as simple as defining them on the Component class. You don't have to insert the <script> and <link> tags into the HTML manually.

      Behind the scenes, django-components keeps track of which components use which JS and CSS files. Thus, when a component is rendered on the page, the page will contain only the JS and CSS used by the components, and nothing more!

      1. Update project structureยค

      Start by creating empty calendar.js and calendar.css files:

      sampleproject/
      + Adding JS and CSS - Django-Components      

      Adding JS and CSS

      Next we will add CSS and JavaScript to our template.

      Info

      In django-components, using JS and CSS is as simple as defining them on the Component class. You don't have to insert the <script> and <link> tags into the HTML manually.

      Behind the scenes, django-components keeps track of which components use which JS and CSS files. Thus, when a component is rendered on the page, the page will contain only the JS and CSS used by the components, and nothing more!

      1. Update project structureยค

      Start by creating empty calendar.js and calendar.css files:

      sampleproject/
       โ”œโ”€โ”€ calendarapp/
       โ”œโ”€โ”€ components/
       โ”‚   โ””โ”€โ”€ calendar/
      diff --git a/dev/getting_started/adding_slots/index.html b/dev/getting_started/adding_slots/index.html
      index d2252963..f9d4aebc 100644
      --- a/dev/getting_started/adding_slots/index.html
      +++ b/dev/getting_started/adding_slots/index.html
      @@ -1,4 +1,4 @@
      - Adding slots - Django-Components      

      Adding slots

      Our calendar component's looking great! But we just got a new assignment from our colleague - The calendar date needs to be shown on 3 different pages:

      1. On one page, it needs to be shown as is
      2. On the second, the date needs to be bold
      3. On the third, the date needs to be in italics

      As a reminder, this is what the component's template looks like:

      <div class="calendar">
      + Adding slots - Django-Components      

      Adding slots

      Our calendar component's looking great! But we just got a new assignment from our colleague - The calendar date needs to be shown on 3 different pages:

      1. On one page, it needs to be shown as is
      2. On the second, the date needs to be bold
      3. On the third, the date needs to be in italics

      As a reminder, this is what the component's template looks like:

      <div class="calendar">
         Today's date is <span>{{ date }}</span>
       </div>
       

      There's many ways we could approach this:

      • Expose the date in a slot
      • Style .calendar > span differently on different pages
      • Pass a variable to the component that decides how the date is rendered
      • Create a new component

      First two options are more flexible, because the custom styling is not baked into a component's implementation. And for the sake of demonstration, we'll solve this challenge with slots.

      1. What are slotsยค

      Components support something called Slots.

      When a component is used inside another template, slots allow the parent template to override specific parts of the child component by passing in different content.

      This mechanism makes components more reusable and composable.

      This behavior is similar to slots in Vue.

      In the example below we introduce two tags that work hand in hand to make this work. These are...

      • {% slot <name> %}/{% endslot %}: Declares a new slot in the component template.
      • {% fill <name> %}/{% endfill %}: (Used inside a {% component %} tag pair.) Fills a declared slot with the specified content.

      2. Add a slot tagยค

      Let's update our calendar component to support more customization. We'll add {% slot %} tag to the template:

      <div class="calendar">
      diff --git a/dev/getting_started/components_in_templates/index.html b/dev/getting_started/components_in_templates/index.html
      index 7409d387..62c2f0a1 100644
      --- a/dev/getting_started/components_in_templates/index.html
      +++ b/dev/getting_started/components_in_templates/index.html
      @@ -1,4 +1,4 @@
      - Components in templates - Django-Components      

      Components in templates

      By the end of this section, we want to be able to use our components in Django templates like so:

      {% load component_tags %}
      + Components in templates - Django-Components      

      Components in templates

      By the end of this section, we want to be able to use our components in Django templates like so:

      {% load component_tags %}
       <!DOCTYPE html>
       <html>
         <head>
      diff --git a/dev/getting_started/parametrising_components/index.html b/dev/getting_started/parametrising_components/index.html
      index 7e8ad7f8..bfa8e2b8 100644
      --- a/dev/getting_started/parametrising_components/index.html
      +++ b/dev/getting_started/parametrising_components/index.html
      @@ -1,4 +1,4 @@
      - Parametrising components - Django-Components      

      Parametrising components

      So far, our Calendar component will always render the date 1970-01-01. Let's make it more useful and flexible by being able to pass in custom date.

      What we want is to be able to use the Calendar component within the template like so:

      {% component "calendar" date="2024-12-13" extra_class="text-red" / %}
      + Parametrising components - Django-Components      

      Parametrising components

      So far, our Calendar component will always render the date 1970-01-01. Let's make it more useful and flexible by being able to pass in custom date.

      What we want is to be able to use the Calendar component within the template like so:

      {% component "calendar" date="2024-12-13" extra_class="text-red" / %}
       

      1. Understading component inputsยค

      In section Create your first component, we defined the get_template_data() method that defines what variables will be available within the template:

      [project root]/components/calendar/calendar.py
      from django_components import Component, register
       
       @register("calendar")
      diff --git a/dev/getting_started/rendering_components/index.html b/dev/getting_started/rendering_components/index.html
      index 46aa86ad..32eec55d 100644
      --- a/dev/getting_started/rendering_components/index.html
      +++ b/dev/getting_started/rendering_components/index.html
      @@ -1,4 +1,4 @@
      - Rendering components - Django-Components      

      Rendering components

      Our calendar component can accept and pre-process data, defines its own CSS and JS, and can be used in templates.

      ...But how do we actually render the components into HTML?

      There's 3 ways to render a component:

      As a reminder, this is what the calendar component looks like:

      [project root]/components/calendar/calendar.py
      from django_components import Component, register
      + Rendering components - Django-Components      

      Rendering components

      Our calendar component can accept and pre-process data, defines its own CSS and JS, and can be used in templates.

      ...But how do we actually render the components into HTML?

      There's 3 ways to render a component:

      As a reminder, this is what the calendar component looks like:

      [project root]/components/calendar/calendar.py
      from django_components import Component, register
       
       @register("calendar")
       class Calendar(Component):
      diff --git a/dev/getting_started/your_first_component/index.html b/dev/getting_started/your_first_component/index.html
      index e954761f..892dced0 100644
      --- a/dev/getting_started/your_first_component/index.html
      +++ b/dev/getting_started/your_first_component/index.html
      @@ -1,4 +1,4 @@
      - Create your first component - Django-Components      

      Create your first component

      A component in django-components can be as simple as a Django template and Python code to declare the component:

      calendar.html
      <div class="calendar">
      + Create your first component - Django-Components      

      Create your first component

      A component in django-components can be as simple as a Django template and Python code to declare the component:

      calendar.html
      <div class="calendar">
         Today's date is <span>{{ date }}</span>
       </div>
       
      calendar.py
      from django_components import Component
      diff --git a/dev/guides/devguides/dependency_mgmt/index.html b/dev/guides/devguides/dependency_mgmt/index.html
      index 1a4830eb..504f913e 100644
      --- a/dev/guides/devguides/dependency_mgmt/index.html
      +++ b/dev/guides/devguides/dependency_mgmt/index.html
      @@ -1,4 +1,4 @@
      - JS and CSS rendering - Django-Components      

      JS and CSS renderingยค

      Aim of this doc is to share the intuition on how we manage the JS and CSS ("dependencies") associated with components, and how we render them.

      Starting conditionsยค

      1. First of all, when we consider a component, it has two kind of dependencies - the "inlined" JS and CSS, and additional linked JS and CSS via Media.js/css:

        from django_components import Component, types
        + JS and CSS rendering - Django-Components      

        JS and CSS renderingยค

        Aim of this doc is to share the intuition on how we manage the JS and CSS ("dependencies") associated with components, and how we render them.

        Starting conditionsยค

        1. First of all, when we consider a component, it has two kind of dependencies - the "inlined" JS and CSS, and additional linked JS and CSS via Media.js/css:

          from django_components import Component, types
           
           class MyTable(Component):
               # Inlined JS
          diff --git a/dev/guides/devguides/slot_rendering/index.html b/dev/guides/devguides/slot_rendering/index.html
          index 81673094..54b4cbc5 100644
          --- a/dev/guides/devguides/slot_rendering/index.html
          +++ b/dev/guides/devguides/slot_rendering/index.html
          @@ -1,4 +1,4 @@
          - Slot rendering - Django-Components      

          Slot rendering

          This doc serves as a primer on how component slots and fills are resolved.

          Flowยค

          1. Imagine you have a template. Some kind of text, maybe HTML:

            | ------
            + Slot rendering - Django-Components      

            Slot rendering

            This doc serves as a primer on how component slots and fills are resolved.

            Flowยค

            1. Imagine you have a template. Some kind of text, maybe HTML:

              | ------
               | ---------
               | ----
               | -------
              diff --git a/dev/guides/devguides/slots_and_blocks/index.html b/dev/guides/devguides/slots_and_blocks/index.html
              index 5162ba75..37cb4b0b 100644
              --- a/dev/guides/devguides/slots_and_blocks/index.html
              +++ b/dev/guides/devguides/slots_and_blocks/index.html
              @@ -1,4 +1,4 @@
              - Using slot and block tags - Django-Components     

              Using slot and block tags

              1. First let's clarify how include and extends tags work inside components.

                When component template includes include or extends tags, it's as if the "included" template was inlined. So if the "included" template contains slot tags, then the component uses those slots.

                If you have a template abc.html:

                <div>
                + Using slot and block tags - Django-Components     

                Using slot and block tags

                1. First let's clarify how include and extends tags work inside components.

                  When component template includes include or extends tags, it's as if the "included" template was inlined. So if the "included" template contains slot tags, then the component uses those slots.

                  If you have a template abc.html:

                  <div>
                     hello
                     {% slot "body" %}{% endslot %}
                   </div>
                  diff --git a/dev/guides/other/troubleshooting/index.html b/dev/guides/other/troubleshooting/index.html
                  index 61f46aec..4f6ef2f7 100644
                  --- a/dev/guides/other/troubleshooting/index.html
                  +++ b/dev/guides/other/troubleshooting/index.html
                  @@ -1,4 +1,4 @@
                  - Troubleshooting - Django-Components      

                  Troubleshooting

                  As larger projects get more complex, it can be hard to debug issues. Django Components provides a number of tools and approaches that can help you with that.

                  Component and slot highlightingยค

                  Django Components provides a visual debugging feature that helps you understand the structure and boundaries of your components and slots. When enabled, it adds a colored border and a label around each component and slot on your rendered page.

                  To enable component and slot highlighting for all components and slots, set highlight_components and highlight_slots to True in extensions defaults in your settings.py file:

                  from django_components import ComponentsSettings
                  + Troubleshooting - Django-Components      

                  Troubleshooting

                  As larger projects get more complex, it can be hard to debug issues. Django Components provides a number of tools and approaches that can help you with that.

                  Component and slot highlightingยค

                  Django Components provides a visual debugging feature that helps you understand the structure and boundaries of your components and slots. When enabled, it adds a colored border and a label around each component and slot on your rendered page.

                  To enable component and slot highlighting for all components and slots, set highlight_components and highlight_slots to True in extensions defaults in your settings.py file:

                  from django_components import ComponentsSettings
                   
                   COMPONENTS = ComponentsSettings(
                       extensions_defaults={
                  diff --git a/dev/guides/setup/caching/index.html b/dev/guides/setup/caching/index.html
                  index e82ca6de..03645f54 100644
                  --- a/dev/guides/setup/caching/index.html
                  +++ b/dev/guides/setup/caching/index.html
                  @@ -1,4 +1,4 @@
                  - Caching - Django-Components      

                  Caching

                  This page describes the kinds of assets that django-components caches and how to configure the cache backends.

                  Component cachingยค

                  You can cache the output of your components by setting the Component.Cache options.

                  Read more about Component caching.

                  Component's JS and CSS filesยค

                  django-components simultaneously supports:

                  • Rendering and fetching components as HTML fragments
                  • Allowing components (even fragments) to have JS and CSS files associated with them
                  • Features like JS/CSS variables or CSS scoping

                  To achieve all this, django-components defines additional temporary JS and CSS files. These temporary files need to be stored somewhere, so that they can be fetched by the browser when the component is rendered as a fragment. And for that, django-components uses Django's cache framework.

                  This includes:

                  By default, django-components uses Django's local memory cache backend to store these assets. You can configure it to use any of your Django cache backends by setting the COMPONENTS.cache option in your settings:

                  COMPONENTS = {
                  + Caching - Django-Components      

                  Caching

                  This page describes the kinds of assets that django-components caches and how to configure the cache backends.

                  Component cachingยค

                  You can cache the output of your components by setting the Component.Cache options.

                  Read more about Component caching.

                  Component's JS and CSS filesยค

                  django-components simultaneously supports:

                  • Rendering and fetching components as HTML fragments
                  • Allowing components (even fragments) to have JS and CSS files associated with them
                  • Features like JS/CSS variables or CSS scoping

                  To achieve all this, django-components defines additional temporary JS and CSS files. These temporary files need to be stored somewhere, so that they can be fetched by the browser when the component is rendered as a fragment. And for that, django-components uses Django's cache framework.

                  This includes:

                  By default, django-components uses Django's local memory cache backend to store these assets. You can configure it to use any of your Django cache backends by setting the COMPONENTS.cache option in your settings:

                  COMPONENTS = {
                       # Name of the cache backend to use
                       "cache": "my-cache-backend",
                   }
                  diff --git a/dev/guides/setup/development_server/index.html b/dev/guides/setup/development_server/index.html
                  index 57af2fd9..55d21eb9 100644
                  --- a/dev/guides/setup/development_server/index.html
                  +++ b/dev/guides/setup/development_server/index.html
                  @@ -1,4 +1,4 @@
                  - Development server - Django-Components      

                  Development server

                  Reload dev server on component file changesยค

                  This is relevant if you are using the project structure as shown in our examples, where HTML, JS, CSS and Python are in separate files and nested in a directory.

                  sampleproject/
                  + Development server - Django-Components      

                  Development server

                  Reload dev server on component file changesยค

                  This is relevant if you are using the project structure as shown in our examples, where HTML, JS, CSS and Python are in separate files and nested in a directory.

                  sampleproject/
                   โ”œโ”€โ”€ components/
                   โ”‚   โ””โ”€โ”€ calendar/
                   โ”‚       โ”œโ”€โ”€ calendar.py
                  diff --git a/dev/migrating_from_safer_staticfiles/index.html b/dev/migrating_from_safer_staticfiles/index.html
                  index 15788e74..64317e85 100644
                  --- a/dev/migrating_from_safer_staticfiles/index.html
                  +++ b/dev/migrating_from_safer_staticfiles/index.html
                  @@ -1,4 +1,4 @@
                  - Migrating from safer_staticfiles - Django-Components      

                  Migrating from safer_staticfilesยค

                  This guide is for you if you're upgrating django_components to v0.100 or later from older versions.

                  In version 0.100, we changed how components' static JS and CSS files are handled. See more in the "Static files" section.

                  Migration steps:

                  1. Remove django_components.safer_staticfiles from INSTALLED_APPS in your settings.py, and replace it with django.contrib.staticfiles.

                  Before:

                  INSTALLED_APPS = [
                  + Migrating from safer_staticfiles - Django-Components      

                  Migrating from safer_staticfilesยค

                  This guide is for you if you're upgrating django_components to v0.100 or later from older versions.

                  In version 0.100, we changed how components' static JS and CSS files are handled. See more in the "Static files" section.

                  Migration steps:

                  1. Remove django_components.safer_staticfiles from INSTALLED_APPS in your settings.py, and replace it with django.contrib.staticfiles.

                  Before:

                  INSTALLED_APPS = [
                      "django.contrib.admin",
                      ...
                      # "django.contrib.staticfiles",  # <-- ADD
                  diff --git a/dev/overview/code_of_conduct/index.html b/dev/overview/code_of_conduct/index.html
                  index 1210d564..554c61bb 100644
                  --- a/dev/overview/code_of_conduct/index.html
                  +++ b/dev/overview/code_of_conduct/index.html
                  @@ -1 +1 @@
                  - Code of Conduct - Django-Components      

                  Contributor Covenant Code of Conductยค

                  Our Pledgeยค

                  In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

                  Our Standardsยค

                  Examples of behavior that contributes to creating a positive environment include:

                  • Using welcoming and inclusive language
                  • Being respectful of differing viewpoints and experiences
                  • Gracefully accepting constructive criticism
                  • Focusing on what is best for the community
                  • Showing empathy towards other community members

                  Examples of unacceptable behavior by participants include:

                  • The use of sexualized language or imagery and unwelcome sexual attention or advances
                  • Trolling, insulting/derogatory comments, and personal or political attacks
                  • Public or private harassment
                  • Publishing others' private information, such as a physical or electronic address, without explicit permission
                  • Other conduct which could reasonably be considered inappropriate in a professional setting

                  Our Responsibilitiesยค

                  Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

                  Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

                  Scopeยค

                  This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

                  Enforcementยค

                  Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at emil@emilstenstrom.se. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

                  Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

                  Attributionยค

                  This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

                  For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq

                  \ No newline at end of file + Code of Conduct - Django-Components

                  Contributor Covenant Code of Conductยค

                  Our Pledgeยค

                  In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

                  Our Standardsยค

                  Examples of behavior that contributes to creating a positive environment include:

                  • Using welcoming and inclusive language
                  • Being respectful of differing viewpoints and experiences
                  • Gracefully accepting constructive criticism
                  • Focusing on what is best for the community
                  • Showing empathy towards other community members

                  Examples of unacceptable behavior by participants include:

                  • The use of sexualized language or imagery and unwelcome sexual attention or advances
                  • Trolling, insulting/derogatory comments, and personal or political attacks
                  • Public or private harassment
                  • Publishing others' private information, such as a physical or electronic address, without explicit permission
                  • Other conduct which could reasonably be considered inappropriate in a professional setting

                  Our Responsibilitiesยค

                  Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

                  Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

                  Scopeยค

                  This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

                  Enforcementยค

                  Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at emil@emilstenstrom.se. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

                  Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

                  Attributionยค

                  This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

                  For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq

                  \ No newline at end of file diff --git a/dev/overview/community/index.html b/dev/overview/community/index.html index de31e966..ed935b5a 100644 --- a/dev/overview/community/index.html +++ b/dev/overview/community/index.html @@ -1 +1 @@ - Community - Django-Components

                  Community

                  Community questionsยค

                  The best place to ask questions is in our Github Discussion board.

                  Please, before opening a new discussion, check if similar discussion wasn't opened already.

                  Community examplesยค

                  One of our goals with django-components is to make it easy to share components between projects (see how to package components). 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.

                  \ No newline at end of file + Community - Django-Components

                  Community

                  Community questionsยค

                  The best place to ask questions is in our Github Discussion board.

                  Please, before opening a new discussion, check if similar discussion wasn't opened already.

                  Community examplesยค

                  One of our goals with django-components is to make it easy to share components between projects (see how to package components). 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.

                  \ No newline at end of file diff --git a/dev/overview/compatibility/index.html b/dev/overview/compatibility/index.html index ca449112..9c539f9c 100644 --- a/dev/overview/compatibility/index.html +++ b/dev/overview/compatibility/index.html @@ -1 +1 @@ - Compatibility - Django-Components

                  Compatibility

                  Django-components supports all supported combinations versions of Django and Python.

                  Python version Django version
                  3.8 4.2
                  3.9 4.2
                  3.10 4.2, 5.1, 5.2
                  3.11 4.2, 5.1, 5.2
                  3.12 4.2, 5.1, 5.2
                  3.13 5.1, 5.2

                  Operating systemsยค

                  django-components is tested against Ubuntu and Windows, and should work on any operating system that supports Python.

                  Note

                  django-components uses Rust-based parsers for better performance.

                  These sub-packages are built with maturin which supports a wide range of operating systems, architectures, and Python versions (see the full list).

                  This should cover most of the cases.

                  However, if your environment is not supported, you will need to install Rust and Cargo to build the sub-packages from source.

                  \ No newline at end of file + Compatibility - Django-Components

                  Compatibility

                  Django-components supports all supported combinations versions of Django and Python.

                  Python version Django version
                  3.8 4.2
                  3.9 4.2
                  3.10 4.2, 5.1, 5.2
                  3.11 4.2, 5.1, 5.2
                  3.12 4.2, 5.1, 5.2
                  3.13 5.1, 5.2

                  Operating systemsยค

                  django-components is tested against Ubuntu and Windows, and should work on any operating system that supports Python.

                  Note

                  django-components uses Rust-based parsers for better performance.

                  These sub-packages are built with maturin which supports a wide range of operating systems, architectures, and Python versions (see the full list).

                  This should cover most of the cases.

                  However, if your environment is not supported, you will need to install Rust and Cargo to build the sub-packages from source.

                  \ No newline at end of file diff --git a/dev/overview/contributing/index.html b/dev/overview/contributing/index.html index c438c263..7c51e3ec 100644 --- a/dev/overview/contributing/index.html +++ b/dev/overview/contributing/index.html @@ -1 +1 @@ - Contributing - Django-Components

                  Contributing

                  Bug reportsยค

                  If you find a bug, please open an issue with detailed description of what happened.

                  Bug fixesยค

                  If you found a fix for a bug or typo, go ahead and open a PR with a fix. We'll help you out with the rest!

                  Feature requestsยค

                  For feature requests or suggestions, please open either a discussion or an issue.

                  Getting involvedยค

                  django_components is still under active development, and there's much to build, so come aboard!

                  Sponsoringยค

                  Another way you can get involved is by donating to the development of django_components.

                  \ No newline at end of file + Contributing - Django-Components

                  Contributing

                  Bug reportsยค

                  If you find a bug, please open an issue with detailed description of what happened.

                  Bug fixesยค

                  If you found a fix for a bug or typo, go ahead and open a PR with a fix. We'll help you out with the rest!

                  Feature requestsยค

                  For feature requests or suggestions, please open either a discussion or an issue.

                  Getting involvedยค

                  django_components is still under active development, and there's much to build, so come aboard!

                  Sponsoringยค

                  Another way you can get involved is by donating to the development of django_components.

                  \ No newline at end of file diff --git a/dev/overview/development/index.html b/dev/overview/development/index.html index 92177bfd..0b09ba8c 100644 --- a/dev/overview/development/index.html +++ b/dev/overview/development/index.html @@ -1,4 +1,4 @@ - Development - Django-Components

                  Development

                  Install locally and run the testsยค

                  Start by forking the project by clicking the Fork button up in the right corner in the GitHub. This makes a copy of the repository in your own name. Now you can clone this repository locally and start adding features:

                  git clone https://github.com/<your GitHub username>/django-components.git
                  + Development - Django-Components      

                  Development

                  Install locally and run the testsยค

                  Start by forking the project by clicking the Fork button up in the right corner in the GitHub. This makes a copy of the repository in your own name. Now you can clone this repository locally and start adding features:

                  git clone https://github.com/<your GitHub username>/django-components.git
                   cd django-components
                   

                  To quickly run the tests install the local dependencies by running:

                  pip install -r requirements-dev.txt
                   

                  You also have to install this local django-components version. Use -e for editable mode so you don't have to re-install after every change:

                  pip install -e .
                  diff --git a/dev/overview/installation/index.html b/dev/overview/installation/index.html
                  index bd2b245a..5557fe0c 100644
                  --- a/dev/overview/installation/index.html
                  +++ b/dev/overview/installation/index.html
                  @@ -1,4 +1,4 @@
                  - Installation - Django-Components      

                  Installation

                  Basic installationยค

                  1. Install django_components into your environment:

                    pip install django_components
                    + Installation - Django-Components      

                    Installation

                    Basic installationยค

                    1. Install django_components into your environment:

                      pip install django_components
                       
                    2. Load django_components into Django by adding it into INSTALLED_APPS in your settings file:

                      # app/settings.py
                       INSTALLED_APPS = [
                           ...,
                      diff --git a/dev/overview/license/index.html b/dev/overview/license/index.html
                      index 805f362a..a1f8c617 100644
                      --- a/dev/overview/license/index.html
                      +++ b/dev/overview/license/index.html
                      @@ -1 +1 @@
                      - License - Django-Components     

                      License

                      MIT License

                      Copyright (c) 2019 Emil Stenstrรถm

                      Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

                      The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

                      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

                      \ No newline at end of file + License - Django-Components

                      License

                      MIT License

                      Copyright (c) 2019 Emil Stenstrรถm

                      Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

                      The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

                      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

                      \ No newline at end of file diff --git a/dev/overview/migrating/index.html b/dev/overview/migrating/index.html index a96f089b..6e443d30 100644 --- a/dev/overview/migrating/index.html +++ b/dev/overview/migrating/index.html @@ -1 +1 @@ - Migrating - Django-Components

                      Migrating

                      Django-components is still in active development.

                      Since django-components is in pre-1.0 development, the public API is not yet frozen. This means that there may be breaking changes between minor versions. We try to minimize the number of breaking changes, but sometimes it's unavoidable.

                      When upgrading, please read the 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:

                      These versions introduced breaking changes that are not backwards compatible.

                      \ No newline at end of file + Migrating - Django-Components

                      Migrating

                      Django-components is still in active development.

                      Since django-components is in pre-1.0 development, the public API is not yet frozen. This means that there may be breaking changes between minor versions. We try to minimize the number of breaking changes, but sometimes it's unavoidable.

                      When upgrading, please read the 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:

                      These versions introduced breaking changes that are not backwards compatible.

                      \ No newline at end of file diff --git a/dev/overview/performance/index.html b/dev/overview/performance/index.html index de215699..6ec43c46 100644 --- a/dev/overview/performance/index.html +++ b/dev/overview/performance/index.html @@ -1 +1 @@ - Performance - Django-Components
                      \ No newline at end of file + Performance - Django-Components
                      \ No newline at end of file diff --git a/dev/overview/security_notes/index.html b/dev/overview/security_notes/index.html index 6cf46dd0..8b93d1ee 100644 --- a/dev/overview/security_notes/index.html +++ b/dev/overview/security_notes/index.html @@ -1,4 +1,4 @@ - Security notes ๐Ÿšจ - Django-Components

                      Security notes ๐Ÿšจ

                      It is strongly recommended to read this section before using django-components in production.

                      Static filesยค

                      TL;DR: No action needed from v0.100 onwards. Before v0.100, use safer_staticfiles to avoid exposing backend logic.

                      Components can be organized however you prefer. That said, our prefered way is to keep the files of a component close together by bundling them in the same directory.

                      This means that files containing backend logic, such as Python modules and HTML templates, live in the same directory as static files, e.g. JS and CSS.

                      From v0.100 onwards, we keep component files (as defined by COMPONENTS.dirs and COMPONENTS.app_dirs) separate from the rest of the static files (defined by STATICFILES_DIRS). That way, the Python and HTML files are NOT exposed by the server. Only the static JS, CSS, and other common formats.

                      Note

                      If you need to expose different file formats, you can configure these with COMPONENTS.static_files_allowed and COMPONENTS.static_files_forbidden.

                      Static files prior to v0.100ยค

                      Prior to v0.100, if your were using django.contrib.staticfiles to collect static files, no distinction was made between the different kinds of files.

                      As a result, your Python code and templates may inadvertently become available on your static file server. You probably don't want this, as parts of your backend logic will be exposed, posing a potential security vulnerability.

                      From v0.27 until v0.100, django-components shipped with an additional installable app django_components.safer_staticfiles. It was a drop-in replacement for django.contrib.staticfiles. Its behavior is 100% identical except it ignores .py and .html files, meaning these will not end up on your static files server.

                      To use it, add it to INSTALLED_APPS and remove django.contrib.staticfiles.

                      INSTALLED_APPS = [
                      + Security notes ๐Ÿšจ - Django-Components      

                      Security notes ๐Ÿšจ

                      It is strongly recommended to read this section before using django-components in production.

                      Static filesยค

                      TL;DR: No action needed from v0.100 onwards. Before v0.100, use safer_staticfiles to avoid exposing backend logic.

                      Components can be organized however you prefer. That said, our prefered way is to keep the files of a component close together by bundling them in the same directory.

                      This means that files containing backend logic, such as Python modules and HTML templates, live in the same directory as static files, e.g. JS and CSS.

                      From v0.100 onwards, we keep component files (as defined by COMPONENTS.dirs and COMPONENTS.app_dirs) separate from the rest of the static files (defined by STATICFILES_DIRS). That way, the Python and HTML files are NOT exposed by the server. Only the static JS, CSS, and other common formats.

                      Note

                      If you need to expose different file formats, you can configure these with COMPONENTS.static_files_allowed and COMPONENTS.static_files_forbidden.

                      Static files prior to v0.100ยค

                      Prior to v0.100, if your were using django.contrib.staticfiles to collect static files, no distinction was made between the different kinds of files.

                      As a result, your Python code and templates may inadvertently become available on your static file server. You probably don't want this, as parts of your backend logic will be exposed, posing a potential security vulnerability.

                      From v0.27 until v0.100, django-components shipped with an additional installable app django_components.safer_staticfiles. It was a drop-in replacement for django.contrib.staticfiles. Its behavior is 100% identical except it ignores .py and .html files, meaning these will not end up on your static files server.

                      To use it, add it to INSTALLED_APPS and remove django.contrib.staticfiles.

                      INSTALLED_APPS = [
                           # 'django.contrib.staticfiles',   # <-- REMOVE
                           'django_components',
                           'django_components.safer_staticfiles'  # <-- ADD
                      diff --git a/dev/overview/welcome/index.html b/dev/overview/welcome/index.html
                      index ef68a1db..8532a79a 100644
                      --- a/dev/overview/welcome/index.html
                      +++ b/dev/overview/welcome/index.html
                      @@ -1,4 +1,4 @@
                      - Welcome to Django Components - Django-Components      

                      Welcome to Django Components

                      django-components

                      PyPI - Version PyPI - Python Version PyPI - License PyPI - Downloads GitHub Actions Workflow Status asv

                      django-components combines Django's templating system with the modularity seen in modern frontend frameworks like Vue or React.

                      With django-components you can support Django projects small and large without leaving the Django ecosystem.

                      Quickstartยค

                      A component in django-components can be as simple as a Django template and Python code to declare the component:

                      components/calendar/calendar.html
                      <div class="calendar">
                      + Welcome to Django Components - Django-Components      

                      Welcome to Django Components

                      django-components

                      PyPI - Version PyPI - Python Version PyPI - License PyPI - Downloads GitHub Actions Workflow Status asv

                      django-components combines Django's templating system with the modularity seen in modern frontend frameworks like Vue or React.

                      With django-components you can support Django projects small and large without leaving the Django ecosystem.

                      Quickstartยค

                      A component in django-components can be as simple as a Django template and Python code to declare the component:

                      components/calendar/calendar.html
                      <div class="calendar">
                         Today's date is <span>{{ date }}</span>
                       </div>
                       
                      components/calendar/calendar.py
                      from django_components import Component, register
                      diff --git a/dev/reference/api/index.html b/dev/reference/api/index.html
                      index b2a6e483..012fb386 100644
                      --- a/dev/reference/api/index.html
                      +++ b/dev/reference/api/index.html
                      @@ -1,4 +1,4 @@
                      - API - Django-Components      

                      APIยค

                      BaseNode ยค

                      BaseNode(
                      + API - Django-Components      

                      APIยค

                      BaseNode ยค

                      BaseNode(
                           params: List[TagAttr],
                           flags: Optional[Dict[str, bool]] = None,
                           nodelist: Optional[NodeList] = None,
                      diff --git a/dev/reference/commands/index.html b/dev/reference/commands/index.html
                      index 13f6e444..7edc6c91 100644
                      --- a/dev/reference/commands/index.html
                      +++ b/dev/reference/commands/index.html
                      @@ -1,4 +1,4 @@
                      - CLI commands - Django-Components      

                      Commandsยค

                      These are all the Django management commands that will be added by installing django_components:

                      componentsยค

                      usage: python manage.py  components [-h] {create,upgrade,ext,list} ...
                      + CLI commands - Django-Components      

                      Commandsยค

                      These are all the Django management commands that will be added by installing django_components:

                      componentsยค

                      usage: python manage.py  components [-h] {create,upgrade,ext,list} ...
                       

                      See source code

                      The entrypoint for the 'components' commands.

                      Options:

                      • -h, --help
                        • show this help message and exit

                      Subcommands:

                      • create
                        • Create a new django component.
                      • upgrade
                        • Upgrade django components syntax from '{% component_block ... %}' to '{% component ... %}'.
                      • ext
                        • Run extension commands.
                      • list
                        • List all components created in this project.

                      The entrypoint for the "components" commands.

                      python manage.py components list
                       python manage.py components create <name>
                       python manage.py components upgrade
                      diff --git a/dev/reference/components/index.html b/dev/reference/components/index.html
                      index cfd8b85e..995f391c 100644
                      --- a/dev/reference/components/index.html
                      +++ b/dev/reference/components/index.html
                      @@ -1,4 +1,4 @@
                      - Components - Django-Components      

                      Componentsยค

                      These are the components provided by django_components.

                      DynamicComponent ยค

                      Bases: django_components.component.Component

                      See source code

                      This component is given a registered name or a reference to another component, and behaves as if the other component was in its place.

                      The args, kwargs, and slot fills are all passed down to the underlying component.

                      Parameters:

                      • is (str | Type[Component]) โ€“

                        Component that should be rendered. Either a registered name of a component, or a Component class directly. Required.

                      • registry (ComponentRegistry, default: None ) โ€“

                        Specify the registry to search for the registered name. If omitted, all registries are searched until the first match.

                      • *args (Optional[Any], default: None ) โ€“

                        Additional data passed to the component.

                      • **kwargs (Optional[Any], default: None ) โ€“

                        Additional data passed to the component.

                      Slots:

                      • Any slots, depending on the actual component.

                      Examples:

                      Django

                      {% component "dynamic" is=table_comp data=table_data headers=table_headers %}
                      + Components - Django-Components      

                      Componentsยค

                      These are the components provided by django_components.

                      DynamicComponent ยค

                      Bases: django_components.component.Component

                      See source code

                      This component is given a registered name or a reference to another component, and behaves as if the other component was in its place.

                      The args, kwargs, and slot fills are all passed down to the underlying component.

                      Parameters:

                      • is (str | Type[Component]) โ€“

                        Component that should be rendered. Either a registered name of a component, or a Component class directly. Required.

                      • registry (ComponentRegistry, default: None ) โ€“

                        Specify the registry to search for the registered name. If omitted, all registries are searched until the first match.

                      • *args (Optional[Any], default: None ) โ€“

                        Additional data passed to the component.

                      • **kwargs (Optional[Any], default: None ) โ€“

                        Additional data passed to the component.

                      Slots:

                      • Any slots, depending on the actual component.

                      Examples:

                      Django

                      {% component "dynamic" is=table_comp data=table_data headers=table_headers %}
                           {% fill "pagination" %}
                               {% component "pagination" / %}
                           {% endfill %}
                      diff --git a/dev/reference/exceptions/index.html b/dev/reference/exceptions/index.html
                      index 1cfdd60c..0134df48 100644
                      --- a/dev/reference/exceptions/index.html
                      +++ b/dev/reference/exceptions/index.html
                      @@ -1,3 +1,3 @@
                      - Exceptions - Django-Components      

                      Exceptionsยค

                      AlreadyRegistered ยค

                      Bases: Exception

                      See source code

                      Raised when you try to register a Component, but it's already registered with given ComponentRegistry.

                      NotRegistered ยค

                      Bases: Exception

                      See source code

                      Raised when you try to access a Component, but it's NOT registered with given ComponentRegistry.

                      TagProtectedError ยค

                      Bases: Exception

                      See source code

                      The way the TagFormatter works is that, based on which start and end tags are used for rendering components, the ComponentRegistry behind the scenes un-/registers the template tags with the associated instance of Django's Library.

                      In other words, if I have registered a component "table", and I use the shorthand syntax:

                      {% table ... %}
                      + Exceptions - Django-Components      

                      Exceptionsยค

                      AlreadyRegistered ยค

                      Bases: Exception

                      See source code

                      Raised when you try to register a Component, but it's already registered with given ComponentRegistry.

                      NotRegistered ยค

                      Bases: Exception

                      See source code

                      Raised when you try to access a Component, but it's NOT registered with given ComponentRegistry.

                      TagProtectedError ยค

                      Bases: Exception

                      See source code

                      The way the TagFormatter works is that, based on which start and end tags are used for rendering components, the ComponentRegistry behind the scenes un-/registers the template tags with the associated instance of Django's Library.

                      In other words, if I have registered a component "table", and I use the shorthand syntax:

                      {% table ... %}
                       {% endtable %}
                       

                      Then ComponentRegistry registers the tag table onto the Django's Library instance.

                      However, that means that if we registered a component "slot", then we would overwrite the {% slot %} tag from django_components.

                      Thus, this exception is raised when a component is attempted to be registered under a forbidden name, such that it would overwrite one of django_component's own template tags.

                      \ No newline at end of file diff --git a/dev/reference/extension_commands/index.html b/dev/reference/extension_commands/index.html index 94d31e78..9ca9c1db 100644 --- a/dev/reference/extension_commands/index.html +++ b/dev/reference/extension_commands/index.html @@ -1,4 +1,4 @@ - Extension commands API - Django-Components

                      Extension commands APIยค

                      Overview of all classes, functions, and other objects related to defining extension commands.

                      Read more on Extensions.

                      CommandArg dataclass ยค

                      CommandArg(
                      + Extension commands API - Django-Components      

                      Extension commands APIยค

                      Overview of all classes, functions, and other objects related to defining extension commands.

                      Read more on Extensions.

                      CommandArg dataclass ยค

                      CommandArg(
                           name_or_flags: Union[str, Sequence[str]],
                           action: Optional[Union[Extension hooks - Django-Components      

                      Extension hooksยค

                      Overview of all the extension hooks available in Django Components.

                      Read more on Extensions.

                      Hooksยค

                      on_component_class_created ยค

                      on_component_class_created(ctx: OnComponentClassCreatedContext) -> None
                      + Extension hooks - Django-Components      

                      Extension hooksยค

                      Overview of all the extension hooks available in Django Components.

                      Read more on Extensions.

                      Hooksยค

                      on_component_class_created ยค

                      on_component_class_created(ctx: OnComponentClassCreatedContext) -> None
                       

                      See source code

                      Called when a new Component class is created.

                      This hook is called after the Component class is fully defined but before it's registered.

                      Use this hook to perform any initialization or validation of the Component class.

                      Example:

                      from django_components import ComponentExtension, OnComponentClassCreatedContext
                       
                       class MyExtension(ComponentExtension):
                      diff --git a/dev/reference/extension_urls/index.html b/dev/reference/extension_urls/index.html
                      index bed11140..9bf98e37 100644
                      --- a/dev/reference/extension_urls/index.html
                      +++ b/dev/reference/extension_urls/index.html
                      @@ -1,4 +1,4 @@
                      - Extension URLs API - Django-Components      

                      Extension URLs APIยค

                      Overview of all classes, functions, and other objects related to defining extension URLs.

                      Read more on Extensions.

                      URLRoute dataclass ยค

                      URLRoute(
                      + Extension URLs API - Django-Components      

                      Extension URLs APIยค

                      Overview of all classes, functions, and other objects related to defining extension URLs.

                      Read more on Extensions.

                      URLRoute dataclass ยค

                      URLRoute(
                           path: str,
                           handler: Optional[URLRouteHandler] = None,
                           children: Iterable[Settings - Django-Components      

                      Settingsยค

                      You can configure django_components with a global COMPONENTS variable in your Django settings file, e.g. settings.py. By default you don't need it set, there are resonable defaults.

                      To configure the settings you can instantiate ComponentsSettings for validation and type hints. Or, for backwards compatibility, you can also use plain dictionary:

                      # settings.py
                      + Settings - Django-Components      

                      Settingsยค

                      You can configure django_components with a global COMPONENTS variable in your Django settings file, e.g. settings.py. By default you don't need it set, there are resonable defaults.

                      To configure the settings you can instantiate ComponentsSettings for validation and type hints. Or, for backwards compatibility, you can also use plain dictionary:

                      # settings.py
                       from django_components import ComponentsSettings
                       
                       COMPONENTS = ComponentsSettings(
                      diff --git a/dev/reference/signals/index.html b/dev/reference/signals/index.html
                      index 6e60d27c..e3be5e16 100644
                      --- a/dev/reference/signals/index.html
                      +++ b/dev/reference/signals/index.html
                      @@ -1,4 +1,4 @@
                      - Signals - Django-Components      

                      Signalsยค

                      Below are the signals that are sent by or during the use of django-components.

                      template_renderedยค

                      Django's template_rendered signal. This signal is sent when a template is rendered.

                      Django-components triggers this signal when a component is rendered. If there are nested components, the signal is triggered for each component.

                      Import from django as django.test.signals.template_rendered.

                      from django.test.signals import template_rendered
                      + Signals - Django-Components      

                      Signalsยค

                      Below are the signals that are sent by or during the use of django-components.

                      template_renderedยค

                      Django's template_rendered signal. This signal is sent when a template is rendered.

                      Django-components triggers this signal when a component is rendered. If there are nested components, the signal is triggered for each component.

                      Import from django as django.test.signals.template_rendered.

                      from django.test.signals import template_rendered
                       
                       # Setup a callback function
                       def my_callback(sender, **kwargs):
                      diff --git a/dev/reference/tag_formatters/index.html b/dev/reference/tag_formatters/index.html
                      index 69077cb4..bd702174 100644
                      --- a/dev/reference/tag_formatters/index.html
                      +++ b/dev/reference/tag_formatters/index.html
                      @@ -1,4 +1,4 @@
                      - Tag formatters - Django-Components      

                      Tag Formattersยค

                      Tag formatters allow you to change the syntax for calling components from within the Django templates.

                      Tag formatter are set via the tag_formatter setting.

                      Available tag formattersยค

                      ComponentFormatter ยค

                      Bases: django_components.tag_formatter.TagFormatterABC

                      See source code

                      The original django_component's component tag formatter, it uses the {% component %} and {% endcomponent %} tags, and the component name is given as the first positional arg.

                      Example as block:

                      {% component "mycomp" abc=123 %}
                      + Tag formatters - Django-Components      

                      Tag Formattersยค

                      Tag formatters allow you to change the syntax for calling components from within the Django templates.

                      Tag formatter are set via the tag_formatter setting.

                      Available tag formattersยค

                      ComponentFormatter ยค

                      Bases: django_components.tag_formatter.TagFormatterABC

                      See source code

                      The original django_component's component tag formatter, it uses the {% component %} and {% endcomponent %} tags, and the component name is given as the first positional arg.

                      Example as block:

                      {% component "mycomp" abc=123 %}
                           {% fill "myfill" %}
                               ...
                           {% endfill %}
                      diff --git a/dev/reference/template_tags/index.html b/dev/reference/template_tags/index.html
                      index 2905b3b7..d5f933a7 100644
                      --- a/dev/reference/template_tags/index.html
                      +++ b/dev/reference/template_tags/index.html
                      @@ -1,4 +1,4 @@
                      - Template tags - Django-Components      

                      Template tagsยค

                      All following template tags are defined in

                      django_components.templatetags.component_tags

                      Import as

                      {% load component_tags %}
                      + Template tags - Django-Components      

                      Template tagsยค

                      All following template tags are defined in

                      django_components.templatetags.component_tags

                      Import as

                      {% load component_tags %}
                       

                      component_css_dependenciesยค

                      {% component_css_dependencies  %}
                       

                      See source code

                      Marks location where CSS link tags should be rendered after the whole HTML has been generated.

                      Generally, this should be inserted into the <head> tag of the HTML.

                      If the generated HTML does NOT contain any {% component_css_dependencies %} tags, CSS links are by default inserted into the <head> tag of the HTML. (See Default JS / CSS locations)

                      Note that there should be only one {% component_css_dependencies %} for the whole HTML document. If you insert this tag multiple times, ALL CSS links will be duplicately inserted into ALL these places.

                      component_js_dependenciesยค

                      {% component_js_dependencies  %}
                       

                      See source code

                      Marks location where JS link tags should be rendered after the whole HTML has been generated.

                      Generally, this should be inserted at the end of the <body> tag of the HTML.

                      If the generated HTML does NOT contain any {% component_js_dependencies %} tags, JS scripts are by default inserted at the end of the <body> tag of the HTML. (See Default JS / CSS locations)

                      Note that there should be only one {% component_js_dependencies %} for the whole HTML document. If you insert this tag multiple times, ALL JS scripts will be duplicately inserted into ALL these places.

                      componentยค

                      {% component *args: Any, **kwargs: Any [only] %}
                      @@ -198,4 +198,4 @@
                               {% endfill %}
                             {% endcomponent %}
                           """
                      -
                      \ No newline at end of file +
                      \ No newline at end of file diff --git a/dev/reference/template_variables/index.html b/dev/reference/template_variables/index.html index 3a8b3f90..9614f0f8 100644 --- a/dev/reference/template_variables/index.html +++ b/dev/reference/template_variables/index.html @@ -1,4 +1,4 @@ - Template variables - Django-Components

                      Template variablesยค

                      Here is a list of all variables that are automatically available from inside the component's template:

                      args instance-attribute ยค

                      args: Any
                      + Template variables - Django-Components      

                      Template variablesยค

                      Here is a list of all variables that are automatically available from inside the component's template:

                      args instance-attribute ยค

                      args: Any
                       

                      See source code

                      The args argument as passed to Component.get_template_data().

                      This is the same Component.args that's available on the component instance.

                      If you defined the Component.Args class, then the args property will return an instance of that class.

                      Otherwise, args will be a plain list.

                      Example:

                      With Args class:

                      from django_components import Component, register
                       
                       @register("table")
                      @@ -90,4 +90,4 @@
                               return {
                                   "my_slot_filled": "my_slot" in slots
                               }
                      -
                      \ No newline at end of file +
                      \ No newline at end of file diff --git a/dev/reference/testing_api/index.html b/dev/reference/testing_api/index.html index 61bddaf5..fe6aab1e 100644 --- a/dev/reference/testing_api/index.html +++ b/dev/reference/testing_api/index.html @@ -1,4 +1,4 @@ - Testing API - Django-Components

                      Testing APIยค

                      djc_test ยค

                      djc_test(
                      + Testing API - Django-Components      

                      Testing APIยค

                      djc_test ยค

                      djc_test(
                           django_settings: Union[Optional[Dict], Callable, Type] = None,
                           components_settings: Optional[Dict] = None,
                           parametrize: Optional[
                      diff --git a/dev/reference/urls/index.html b/dev/reference/urls/index.html
                      index 41652722..5a6b5db9 100644
                      --- a/dev/reference/urls/index.html
                      +++ b/dev/reference/urls/index.html
                      @@ -1,7 +1,7 @@
                      - URLs - Django-Components      

                      URLsยค

                      Below are all the URL patterns that will be added by adding django_components.urls.

                      See Installation on how to add these URLs to your Django project.

                      Django components already prefixes all URLs with components/. So when you are adding the URLs to urlpatterns, you can use an empty string as the first argument:

                      from django.urls import include, path
                      + URLs - Django-Components      

                      URLsยค

                      Below are all the URL patterns that will be added by adding django_components.urls.

                      See Installation on how to add these URLs to your Django project.

                      Django components already prefixes all URLs with components/. So when you are adding the URLs to urlpatterns, you can use an empty string as the first argument:

                      from django.urls import include, path
                       
                       urlpatterns = [
                           ...
                           path("", include("django_components.urls")),
                       ]
                      -

                      List of URLsยค

                      • components/cache/<str:comp_cls_id>.<str:input_hash>.<str:script_type>

                      • components/cache/<str:comp_cls_id>.<str:script_type>

                      \ No newline at end of file +

                      List of URLsยค

                      • components/cache/<str:comp_cls_id>.<str:input_hash>.<str:script_type>

                      • components/cache/<str:comp_cls_id>.<str:script_type>

                      \ No newline at end of file diff --git a/dev/release_notes/index.html b/dev/release_notes/index.html index d80884f2..47cf3840 100644 --- a/dev/release_notes/index.html +++ b/dev/release_notes/index.html @@ -1,4 +1,4 @@ - Release Notes - Django-Components

                      Release notesยค

                      v0.141.1ยค

                      Fixยค

                      • Components' JS and CSS scripts (e.g. from Component.js or Component.js_file) are now cached at class creation time.

                        This means that when you now restart the server while having a page opened in the browser, the JS / CSS files are immediately available.

                        Previously, the JS/CSS were cached only after the components were rendered. So you had to reload the page to trigger the rendering, in order to make the JS/CSS files available.

                      • Fix the default cache for JS / CSS scripts to be unbounded.

                        Previously, the default cache for the JS/CSS scripts (LocMemCache) was accidentally limited to 300 entries (~150 components).

                      • Do not send template_rendered signal when rendering a component with no template. (#1277)

                      v0.141.0ยค

                      Featยค