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.
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.
Django-components provides a seamless integration with HTML fragments (HTML over the wire), whether you're using HTMX, AlpineJS, or vanilla JavaScript.
When you define a component that has extra JS or CSS, and you use django-components to render the fragment, 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:
User makes an action - clicks a button or submits a form
The action causes a request to be made from the client to the server.
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).
A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.
Django-components provides a seamless integration with HTML fragments (HTML over the wire), whether you're using HTMX, AlpineJS, or vanilla JavaScript.
When you define a component that has extra JS or CSS, and you use django-components to render the fragment, 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:
User makes an action - clicks a button or submits a form
The action causes a request to be made from the client to the server.
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).
A library like HTMX, AlpineJS, or custom function inserts the new HTML into the correct place.
classFrag(Component):defget(self,request):# IMPORTANT: Don't forget `type="fragment"`
@@ -118,33 +118,33 @@
# NOTE: We wrap the actual fragment in a template tag with x-if="false" to prevent it# from being rendered until we have registered the component with AlpineJS.
-template="""
- <template x-if="false" data-name="frag">
- <div class="frag">
- 123
- <span x-data="frag" x-text="fragVal">
- </span>
- </div>
- </template>
- """
+template="""
+<templatex-if="false"data-name="frag">
+<divclass="frag">
+ 123
+<spanx-data="frag"x-text="fragVal">
+</span>
+</div>
+</template>
+"""
-js="""
- Alpine.data('frag', () => ({
- fragVal: 'xxx',
- }));
+js="""
+Alpine.data('frag',()=>({
+fragVal:'xxx',
+}));
- // Now that the component has been defined in AlpineJS, we can "activate"
- // all instances where we use the `x-data="frag"` directive.
- document.querySelectorAll('[data-name="frag"]').forEach((el) => {
- el.setAttribute('x-if', 'true');
- });
- """
+// Now that the component has been defined in AlpineJS, we can "activate"
+// all instances where we use the `x-data="frag"` directive.
+document.querySelectorAll('[data-name="frag"]').forEach((el)=>{
+el.setAttribute('x-if','true');
+});
+"""
-css="""
- .frag {
- background: blue;
- }
- """
+css="""
+.frag{
+background:blue;
+}
+"""
\ No newline at end of file
diff --git a/dev/concepts/advanced/provide_inject/index.html b/dev/concepts/advanced/provide_inject/index.html
index 2fd0d70d..67d33d66 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 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.
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.
First we use the {% provide %} tag to define the data we want to "provide" (make available).
{%provide"my_data"key="hi"another=123%}{%component"child"/%} <--- Can access "my_data"{%endprovide%}
@@ -23,10 +23,10 @@
return{}
The instance returned from inject() is a subclass of NamedTuple, so the instance is immutable. This ensures that the data returned from inject will always have all the keys that were passed to the provide tag.
NOTE: inject() works strictly only in get_context_data. If you try to call it from elsewhere, it will raise an error.
However, there is a problem here - When we call render_dependencies() inside CardActions.render(), we extract and REMOVE the info on components' JS and CSS from the HTML. But the template of CardActions contains no {% component_depedencies %} tags, and nor <head> nor <body> HTML tags. So the component's JS and CSS will NOT be inserted, and will be lost.
However, there is a problem here - When we call render_dependencies() inside CardActions.render(), we extract and REMOVE the info on components' JS and CSS from the HTML. But the template of CardActions contains no {% component_depedencies %} tags, and nor <head> nor <body> HTML tags. So the component's JS and CSS will NOT be inserted, and will be lost.
If you pre-render one component to pass it into another, the pre-rendered component must be rendered with render_dependencies=False.
\ No newline at end of file
diff --git a/dev/concepts/advanced/tag_formatter/index.html b/dev/concepts/advanced/tag_formatter/index.html
index 919a619c..462f2558 100644
--- a/dev/concepts/advanced/tag_formatter/index.html
+++ b/dev/concepts/advanced/tag_formatter/index.html
@@ -1,4 +1,4 @@
- Tag formatters - Django-Components
Template tags introduced by django-components, such as {% component %} and {% slot %}, offer additional features over the default Django template tags:
Template tags introduced by django-components, such as {% component %} and {% slot %}, offer additional features over the default Django template tags:
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.
Every component that you want to use in the template with the {% component %} tag needs to be registered with the ComponentRegistry. Normally, we use the @register decorator for that:
Every component that you want to use in the template with the {% component %} tag needs to be registered with the ComponentRegistry. Normally, we use the @register decorator for that:
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
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_context_data by accessing the property self.outer_context.
However, as a best practice, it’s recommended not to rely on accessing the outer context directly through self.outer_context. Instead, explicitly pass the variables to the component. For instance, continue passing the variables in the component tag as shown in the previous examples.
django_components supports both Django and Vue-like behavior when it comes to passing data to and through components. This can be configured in context_behavior.
This has two modes:
"django"
The default Django template behavior.
Inside the {% fill %} tag, the context variables you can access are a union of:
All the variables that were OUTSIDE the fill tag, including any\ {% with %} tags.
Any loops ({% for ... %}) that the {% fill %} tag is part of.
Similar behavior to Vue or React, this is useful if you want to make sure that components don't accidentally access variables defined outside of the component.
Inside the {% fill %} tag, you can ONLY access variables from 2 places:
Any loops ({% for ... %}) that the {% fill %} tag is part of.
"django" - my_var has access to data from get_context_data() of both Inner and Outer. If there are variables defined in both, then Inner overshadows Outer.
"isolated" - my_var has access to data from get_context_data() of ONLY Outer.
Then if get_context_data() of the component "my_comp" returns following data:
{"my_var":456}
Then the template will be rendered as:
123 # my_var # cheese
-
Because variables "my_var" and "cheese" are searched only inside RootComponent.get_context_data(). But since "cheese" is not defined there, it's empty.
Info
Notice that the variables defined with the {% with %} tag are ignored inside the {% fill %} tag with the "isolated" mode.
\ No newline at end of file
+
Because variables "my_var" and "cheese" are searched only inside RootComponent.get_context_data(). But since "cheese" is not defined there, it's empty.
Info
Notice that the variables defined with the {% with %} tag are ignored inside the {% fill %} tag with the "isolated" mode.
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/components_as_views/index.html b/dev/concepts/fundamentals/components_as_views/index.html
index cffca4de..8fa8b27e 100644
--- a/dev/concepts/fundamentals/components_as_views/index.html
+++ b/dev/concepts/fundamentals/components_as_views/index.html
@@ -1,19 +1,19 @@
- Components as views - Django-Components
Note: Since 0.92, Component no longer subclasses View. To configure the View class, set the nested Component.View class
Components can now be used as views:
Components define the Component.as_view() class method that can be used the same as View.as_view().
By default, you can define GET, POST or other HTTP handlers directly on the Component, same as you do with View. For example, you can override get and post to handle GET and POST requests, respectively.
In addition, Component now has a render_to_response method that renders the component template based on the provided context and slots' data and returns an HttpResponse object.
Note: Since 0.92, Component no longer subclasses View. To configure the View class, set the nested Component.View class
Components can now be used as views:
Components define the Component.as_view() class method that can be used the same as View.as_view().
By default, you can define GET, POST or other HTTP handlers directly on the Component, same as you do with View. For example, you can override get and post to handle GET and POST requests, respectively.
In addition, Component now has a render_to_response method that renders the component template based on the provided context and slots' data and returns an HttpResponse object.
Here's an example of a calendar component defined as a view:
# In a file called [project root]/components/calendar.pyfromdjango_componentsimportComponent,ComponentView,register@register("calendar")classCalendar(Component):
-template="""
- <div class="calendar-component">
- <div class="header">
- {% slot "header" / %}
- </div>
- <div class="body">
- Today's date is <span>{{ date }}</span>
- </div>
- </div>
- """
+template="""
+<divclass="calendar-component">
+<divclass="header">
+{%slot"header"/%}
+</div>
+<divclass="body">
+ Today's date is <span>{{date}}</span>
+</div>
+</div>
+"""# Handle GET requestsdefget(self,request,*args,**kwargs):
@@ -80,4 +80,4 @@
super(request,*args,**kwargs)do_something_extra(request,*args,**kwargs)
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/components_in_python/index.html b/dev/concepts/fundamentals/components_in_python/index.html
index 2bc5554f..596eb5bf 100644
--- a/dev/concepts/fundamentals/components_in_python/index.html
+++ b/dev/concepts/fundamentals/components_in_python/index.html
@@ -1,11 +1,11 @@
- Components in Python - Django-Components
Components can be rendered outside of Django templates, calling them as regular functions ("React-style").
The component class defines render and render_to_response class methods. These methods accept positional args, kwargs, and slots, offering the same flexibility as the {% component %} tag:
Components can be rendered outside of Django templates, calling them as regular functions ("React-style").
The component class defines render and render_to_response class methods. These methods accept positional args, kwargs, and slots, offering the same flexibility as the {% component %} tag:
When you set extend to a list, the list is expected to contain Component classes (or other classes that have a nested Media class).
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/html_attributes/index.html b/dev/concepts/fundamentals/html_attributes/index.html
index 722e577c..12b7532c 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
All together (2) - attrs and defaults as kwargs args: {% html_attrs class="added_class" class=class_from_var data-id=123 attrs=attrs defaults=defaults %}
The most common use of django-components is to render HTML for a given request. As such, there are a few features that are dependent on the request object.
The most common use of django-components is to render HTML for a given request. As such, there are a few features that are dependent on the request object.
Components can be defined in a single file, which is useful for small 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, defined in a single file:
Components can be defined in a single file, which is useful for small 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, defined in a single file:
This makes it easy to create small components without having to create a separate template, CSS, and JS file.
To add syntax highlighting to these snippets, head over to Syntax highlighting.
\ No newline at end of file
+js:types.js="""
+(function(){
+if(document.querySelector(".calendar")){
+document.querySelector(".calendar").onclick=()=>{
+alert("Clicked calendar!");
+};
+}
+})()
+"""
+
This makes it easy to create small components without having to create a separate template, CSS, and JS file.
To add syntax highlighting to these snippets, head over to Syntax highlighting.
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/slots/index.html b/dev/concepts/fundamentals/slots/index.html
index 60a26717..d02c37ef 100644
--- a/dev/concepts/fundamentals/slots/index.html
+++ b/dev/concepts/fundamentals/slots/index.html
@@ -1,4 +1,4 @@
- Slots - Django-Components
The slot tag now serves only to declare new slots inside the component template.
To override the content of a declared slot, use the newly introduced fill tag instead.
Whereas unfilled slots used to raise a warning, filling a slot is now optional by default.
To indicate that a slot must be filled, the new required option should be added at the end of the slot tag.
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 block 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.
Let's update our calendar component to support more customization. We'll add slot tag pairs to its template, template.html.
The slot tag now serves only to declare new slots inside the component template.
To override the content of a declared slot, use the newly introduced fill tag instead.
Whereas unfilled slots used to raise a warning, filling a slot is now optional by default.
To indicate that a slot must be filled, the new required option should be added at the end of the slot tag.
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 block 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.
Let's update our calendar component to support more customization. We'll add slot tag pairs to its template, template.html.
Consider a component with slot(s). This component may do some processing on the inputs, and then use the processed variable in the slot's default template:
\ No newline at end of file
+template="""
+<div>
+{%component"child"%}
+{%forslot_nameinslots%}
+{%fillname=slot_namedata="data"%}
+{%slotname=slot_name...data/%}
+{%endfill%}
+{%endfor%}
+{%endcomponent%}
+</div>
+"""
+
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/subclassing_components/index.html b/dev/concepts/fundamentals/subclassing_components/index.html
index 477f0e4d..286f6471 100644
--- a/dev/concepts/fundamentals/subclassing_components/index.html
+++ b/dev/concepts/fundamentals/subclassing_components/index.html
@@ -1,32 +1,32 @@
- Subclassing components - Django-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:
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.
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:
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.
The Component.Media nested class follows Django's media inheritance rules:
If both parent and child define a Media class, the child's media will automatically include both its own and the parent's JS and CSS files.
This behavior can be configured using the extend attribute in the Media class, similar to Django's forms. Read more on this in Controlling Media Inheritance.
For example:
classBaseModal(Component):template="<div>Modal content</div>"
@@ -46,14 +46,14 @@
css=["simple_modal.css"]# Only this CSS will be includedjs=["simple_modal.js"]# Only this JS will be included
\ No newline at end of file
diff --git a/dev/concepts/fundamentals/template_tag_syntax/index.html b/dev/concepts/fundamentals/template_tag_syntax/index.html
index 568b375d..dda0b772 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
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).
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
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).
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 %}:
Sometimes, a component may expect a dictionary as one of its inputs.
Most commonly, this happens when a component accepts a dictionary of HTML attributes (usually called attrs) to pass to the underlying template.
In such cases, we may want to define some HTML attributes statically, and other dynamically. But for that, we need to define this dictionary on Python side:
But as you can see in the case above, the event handler @click.stop and styling pa-4 flex are disconnected from the template. If the component grew in size and we moved the HTML to a separate file, we would have hard time reasoning about the component's template.
Luckily, there's a better way.
When we want to pass a dictionary to a component, we can define individual key-value pairs as component kwargs, so we can keep all the relevant information in the template. For that, we prefix the key with the name of the dict and :. So key class of input attrs becomes attrs:class. And our example becomes:
\ No newline at end of file
diff --git a/dev/getting_started/adding_js_and_css/index.html b/dev/getting_started/adding_js_and_css/index.html
index 8871c54c..5f5a5eb5 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
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!
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!
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:
On one page, it needs to be shown as is
On the second, the date needs to be bold
On the third, the date needs to be in italics
As a reminder, this is what the component's template looks like:
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:
On one page, it needs to be shown as is
On the second, the date needs to be bold
On the third, the date needs to be in italics
As a reminder, this is what the component's template looks like:
<divclass="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.
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.
If you "inline" the HTML, JS and CSS code into the Python class, you can set up syntax highlighting for better experience. However, autocompletion / intellisense does not work with syntax highlighting.
We'll start by creating a component that defines only a Django template:
\ No newline at end of file
diff --git a/dev/guides/devguides/dependency_mgmt/index.html b/dev/guides/devguides/dependency_mgmt/index.html
index 2a79ced2..46556a34 100644
--- a/dev/guides/devguides/dependency_mgmt/index.html
+++ b/dev/guides/devguides/dependency_mgmt/index.html
@@ -1,17 +1,17 @@
- JS and CSS rendering - Django-Components
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:
fromdjango_componentsimportComponent,types
+ JS and CSS rendering - Django-Components
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:
fromdjango_componentsimportComponent,typesclassMyTable(Component):# Inlined JS
-js:types.js="""
- console.log(123);
- """
+js:types.js="""
+console.log(123);
+"""# Inlined CSS
-css:types.css="""
- .my-table {
- color: red;
- }
- """
+css:types.css="""
+.my-table{
+color:red;
+}
+"""# Linked JS / CSSclassMedia:
@@ -80,4 +80,4 @@
// Or mark one as already-loaded, so it is ignored when// we call `loadJs`Components.markScriptLoaded("js","/abc/def");
-
Note that loadJs() / loadCss() receive whole <script> / <link> tags, not just the URL. This is because when Django's Media class renders JS and CSS, it formats it as <script> and <link> tags. And we allow users to modify how the JS and CSS should be rendered into the <script> and <link> tags.
So, if users decided to add an extra attribute to their <script> tags, e.g. <script defer src="http://..."></script>, then this way we make sure that the defer attribute will be present on the <script> tag when it is inserted into the DOM at the time of loading the JS script.
To be able to fetch component's inlined JS and CSS, django-components adds a URL path under:
This endpoint takes the component's unique hash, e.g. my_table_10bc2c, and looks up the component's inlined JS or CSS.
Thus, with this approach, we ensure that:
All JS / CSS dependencies are loaded / executed only once.
The approach is compatible with HTML fragments
The approach is compatible with JS / CSS variables.
Inlined JS / CSS may be post-processed by plugins
\ No newline at end of file
+
Note that loadJs() / loadCss() receive whole <script> / <link> tags, not just the URL. This is because when Django's Media class renders JS and CSS, it formats it as <script> and <link> tags. And we allow users to modify how the JS and CSS should be rendered into the <script> and <link> tags.
So, if users decided to add an extra attribute to their <script> tags, e.g. <script defer src="http://..."></script>, then this way we make sure that the defer attribute will be present on the <script> tag when it is inserted into the DOM at the time of loading the JS script.
To be able to fetch component's inlined JS and CSS, django-components adds a URL path under:
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
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.
Will still render the component content just the same:
<div>hello 1 XYZ</div>
You CAN override the block tags of abc.html if the component template uses extends. In that case, just as you would expect, the block inner inside abc.html will render OVERRIDEN:
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.
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.
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.
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.
django-components caches the JS and CSS files associated with your components. This enables components to be rendered as HTML fragments and still having the associated JS and CSS files loaded with them.
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:
django-components caches the JS and CSS files associated with your components. This enables components to be rendered as HTML fragments and still having the associated JS and CSS files loaded with them.
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 38d07a78..a3408e47 100644
--- a/dev/guides/setup/development_server/index.html
+++ b/dev/guides/setup/development_server/index.html
@@ -1 +1 @@
- Development server - Django-Components
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.
In this case you may notice that when you are running a development server, the server sometimes does not reload when you change component files.
TL;DR is that the server won't reload if it thinks the changed file is in a templates directory, or in a nested sub directory of a templates directory. This is by design.
To make the dev server reload on all component files, set reload_on_file_change to True. This configures Django to watch for component files too.
Note
This setting should be enabled only for the dev environment!
\ No newline at end of file
+ Development server - Django-Components
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.
In this case you may notice that when you are running a development server, the server sometimes does not reload when you change component files.
TL;DR is that the server won't reload if it thinks the changed file is in a templates directory, or in a nested sub directory of a templates directory. This is by design.
To make the dev server reload on all component files, set reload_on_file_change to True. This configures Django to watch for component files too.
Note
This setting should be enabled only for the dev environment!
\ No newline at end of file
diff --git a/dev/guides/setup/syntax_highlight/index.html b/dev/guides/setup/syntax_highlight/index.html
index 2804ca22..ef656221 100644
--- a/dev/guides/setup/syntax_highlight/index.html
+++ b/dev/guides/setup/syntax_highlight/index.html
@@ -1,4 +1,4 @@
- Syntax highlighting - Django-Components
Next, in your component, set typings of Component.template/css/js to types.django_html, types.css, and types.js respectively. The extension will recognize these and will activate syntax highlighting.
[project root]/components/calendar.py
# In a file called [project root]/components/calendar.py
+ Syntax highlighting - Django-Components
Next, in your component, set typings of Component.template/css/js to types.django_html, types.css, and types.js respectively. The extension will recognize these and will activate syntax highlighting.
With PyCharm (or any other editor from Jetbrains), you don't need to use types.django_html, types.css, types.js since Pycharm uses language injections. You only need to write the comments # language=<lang> above the variables.
Pygments is a syntax highlighting library written in Python. It's also what's used by this documentation site (mkdocs-material) to highlight code blocks.
To write code blocks with syntax highlighting, you need to install the pygments-djc package.
pipinstallpygments-djc
+
And then initialize it by importing pygments_djc:
importpygments_djc
+
Now you can write code blocks with syntax highlighting.
\ No newline at end of file
diff --git a/dev/migrating_from_safer_staticfiles/index.html b/dev/migrating_from_safer_staticfiles/index.html
index ac6af1cb..d2d906d3 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