Skip to content

Commit bb1e2e9

Browse files
committed
Added slots & changed simple_components tags
1 parent 00f764b commit bb1e2e9

24 files changed

+571
-136
lines changed

README.md

Lines changed: 156 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,176 @@ TEMPLATES = [
4444
If you choose not use it as a built-in, you will need to add `{% load simple_components %}` to the top of your template whenever you want to use simple components.
4545

4646
### 2. Create component inside your template:
47+
You can define a base component that can be reused later. For example:
4748
```html
4849
{% load simple_components %}
4950

50-
{% set_component "first_component" %}
51+
{% #set_component "card" %}
5152
<div class="card">
5253
<h3>{{ title }}</h3>
5354
<p>{{ description }}</p>
5455
</div>
55-
{% end_set_component %}
56+
{% /set_component %}
5657

5758
<div class="card-list">
58-
{% component "first_component" title="Hello world!" description="Some text..." %}
59-
{% component "first_component"
60-
title="Some lines"
61-
description="Other text..."
62-
%}
63-
64-
{% with value="this text will be capitalized later" %}
65-
{% component "first_component" title=123 description=value|capfirst %}
66-
{% endwith %}
59+
{% component "card" title="Post 1" description="..." %}
60+
{% component "card" title="Post 2" description="..." %}
61+
{% component "card" title="Post 3" description="..." %}
6762
</div>
6863
```
6964

65+
You can also use named slots to change the contents of a component as quickly as possible:
66+
```html
67+
{% load simple_components %}
68+
69+
{% #set_component "profile" %}
70+
<div class="profile">
71+
<div class="avatar">
72+
{% @set_slot "avatar" %}
73+
<!-- fallback username as bdage -->
74+
<span class="badge">{{ username.0 }}</span>
75+
{% /set_slot %}
76+
</div>
77+
<div class="info">
78+
{{ username }}
79+
</div>
80+
</div>
81+
{% /set_component %}
82+
83+
{% #set_component "card" %}
84+
<div class="card">
85+
{% set_slot "image" %}
86+
87+
<h3>{{ title }}</h3>
88+
<p>{{ description }}</p>
89+
</div>
90+
{% /set_component %}
91+
92+
<div class="page">
93+
{% component "profile" username="Default" %}
94+
95+
<div class="card-list">
96+
{% #component "card" title="Post 1" description="..." %}
97+
{% @slot "image" %}
98+
<img src="..." alt="slot image" />
99+
{% /slot %}
100+
{% /component %}
101+
</div>
102+
</div>
103+
```
70104
### 3. Hooray! Everything is ready to use it.
71105

106+
## Template syntax
107+
### Create component
108+
To define a component you need to use the Django tag `{# set_component name %}` where name is the name of the component,
109+
listed in quotes. This is a paired tag, which means it needs to be closed:
110+
```html
111+
{% #set_component "card" %}
112+
<p>{{ title }}</p>
113+
{% /set_component %}
114+
```
115+
116+
### Use component
117+
In the example above, we defined the "card" component and specified a variable that will be used during rendering later.
118+
Now, to use this component, you just need to write:
119+
```html
120+
{% component "card" title="Post" %}
121+
```
122+
123+
Components can also render children - anything specified between the opening and closing `component` tags:
124+
```html
125+
{% #set_component "card" %}
126+
<div class="c1 c2 c3 c4 c5">
127+
<p>{{ title }}</p>
128+
{{ children }}
129+
</div>
130+
{% /set_component %}
131+
132+
{% #component "card" title="Post" %}
133+
<p>Simple</p>
134+
<p>Content</p>
135+
{% /component %}
136+
```
137+
138+
### Create slots
139+
Slots are a powerful opportunity to upgrade your components! Slots can accept any content.
140+
Each slot has a name, and is specified inside the set_component tag:
141+
```html
142+
{% #set_component "card" %}
143+
<div class="card">
144+
<div class="card-header">
145+
<h3>{{ title }}</h3>
146+
</div>
147+
<div class="card-body">
148+
{% set_slot "body" %}
149+
</div>
150+
</div>
151+
{% /set_component %}
152+
```
153+
154+
Any slot can have a fallback template, which will be displayed if this slot was not passed to the component.
155+
Otherwise, a `SlotNotFoundError` will be raised:
156+
```html
157+
{% @set_slot "custom" %}
158+
fallback
159+
{% /set_slot %}
160+
```
161+
162+
### Use slots
163+
To use slots in components, you need to pass the slot when rendering where it is needed:
164+
```html
165+
{% #set_component "card" %}
166+
<div class="card">
167+
...
168+
<div class="card-body">
169+
{% set_slot "body" %}
170+
</div>
171+
</div>
172+
{% /set_component %}
173+
174+
{% #component "card" %}
175+
{% @slot "body" %}
176+
render slot inside card-body class
177+
{% /slot %}
178+
{% /component %}
179+
```
180+
181+
### Summarize
182+
All paired tags in simple components close with `%{ /tag %}`, where `tag` can be `set_component`, `set_slot`, `component`.
183+
184+
There are `{% component %}` and `{% set_slot %}` which can be defined on the same line. For the component,
185+
this means that it cannot use slots and children. For `set_slot` this means that the fallback template is not specified:
186+
```html
187+
{% component "card" title="Post" description="..." %}
188+
```
189+
```html
190+
{% set_slot "avatar" %}
191+
```
192+
193+
To define a component or use it, you can specify `#` at the beginning of the tag (only for closable tags):
194+
```html
195+
{% #set_component name="simple" %}
196+
{{ children }}
197+
{% /set_component %}
198+
```
199+
```html
200+
{% #component name="simple" %}
201+
component with children content
202+
{% /component %}
203+
```
204+
205+
To define a slot or use it, you can specify `@` at the beginning of the tag (only for closable tags):
206+
```html
207+
{% @set_slot "custom" %}
208+
fallback
209+
{% /set_slot %}
210+
```
211+
```html
212+
{% @slot "custom" %}
213+
render slot
214+
{% /slot %}
215+
```
216+
72217
## Contributing
73218
If you would like to suggest a new feature, you can create an issue on the GitHub repository for this project.
74219
Also you can fork the repository and submit a pull request with your changes.

simple_components/exceptions.py

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
11
from django import template
22

33

4-
class SetComponentNameError(template.TemplateSyntaxError):
5-
pass
6-
7-
8-
class ComponentNameError(template.TemplateSyntaxError):
9-
pass
10-
11-
12-
class ComponentArgsError(template.TemplateSyntaxError):
13-
pass
14-
15-
16-
class ComponentNotDefined(template.TemplateSyntaxError):
17-
pass
4+
class TagNameRequiredError(template.TemplateSyntaxError):
5+
def __init__(self, tag_name, example):
6+
self.message = '\'%s\' takes at least one required argument "name":\n%s' % (
7+
tag_name,
8+
example,
9+
)
10+
super().__init__(self.message)
11+
12+
13+
class TagPropsArgumentError(template.TemplateSyntaxError):
14+
def __init__(self, bit, example):
15+
self.message = 'Argument %s must be takes as params:\n%s' % (bit, example)
16+
super().__init__(self.message)
17+
18+
19+
class TagPropsChildrenError(template.TemplateSyntaxError):
20+
def __init__(self, name):
21+
self.message = (
22+
'The parameter \'%s\' cannot be specified in props because it is built-in '
23+
'and cannot be overridden in this way.' % name
24+
)
25+
super().__init__(self.message)
26+
27+
28+
class ComponentNotFoundError(template.TemplateSyntaxError):
29+
def __init__(self, name):
30+
self.message = (
31+
'The component \'%s\' has not been previously defined. '
32+
'Check that the component is named correctly.' % name
33+
)
34+
super().__init__(self.message)
35+
36+
37+
class SlotNotFoundError(template.TemplateSyntaxError):
38+
def __init__(self, name, *args):
39+
self.message = 'Expected slot with name \'%s\'!' % name
40+
super().__init__(self.message)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{% load simple_components %}
2+
3+
{% #set_component "card" %}
4+
<div class="card">
5+
<h3>{{ title }}</h3>
6+
<p>{{ description }}</p>
7+
</div>
8+
{% /set_component %}
9+
10+
<div class="card-list">
11+
{% component "card" title="Post 1" description="..." %}
12+
{% component "card" title="Post 2" description="..." %}
13+
{% component "card" title="Post 3" description="..." %}
14+
</div>

simple_components/templates/simple_components/example.html

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{% load simple_components %}
2+
3+
{% #set_component "profile" %}
4+
<div class="profile">
5+
<div class="avatar">
6+
{% @set_slot "avatar" %}
7+
<!-- fallback username as bdage -->
8+
<span class="badge">{{ username.0 }}</span>
9+
{% /set_slot %}
10+
</div>
11+
<div class="info">
12+
{{ username }}
13+
</div>
14+
</div>
15+
{% /set_component %}
16+
17+
{% #set_component "card" %}
18+
<div class="card">
19+
{% set_slot "image" %}
20+
21+
<h3>{{ title }}</h3>
22+
<p>{{ description }}</p>
23+
</div>
24+
{% /set_component %}
25+
26+
<div class="page">
27+
{% component "profile" username="Default" %}
28+
29+
<div class="card-list">
30+
{% #component "card" title="Post 1" description="..." %}
31+
{% @slot "image" %}
32+
<img src="..." alt="slot image" />
33+
{% /slot %}
34+
{% /component %}
35+
</div>
36+
</div>

0 commit comments

Comments
 (0)