---
title: "Conas clibeanna agus scagairí teimpléad saincheaptha a ch"
version: 5.2
locale: ga
source: https://docs.djangoproject.com/ga/5.2/howto/custom-template-tags/
canonical: https://djangodocs.dev/ga/5.2/howto/custom-template-tags/
---
# Conas clibeanna agus scagairí teimpléad saincheaptha a ch

Tagann teanga teimpléad Django le réimse leathan de: doc: clibeanna agus scagairí ionsuite 'atá deartha chun aghaidh a thabhairt ar riachtanais loi\</ref/templates/builtins\> ghic chur i láthair d'iarratais. Mar sin féin, b'fhéidir go mbeidh feidhmiúlacht ag teastáil uait nach bhfuil clúdaithe ag an gcroí-shraith de phríomh-theimpléid. \<load\>Is féidir leat an t-inneall teimpléid a leathnú trí chlibeanna agus scagairí saincheaptha a shainiú ag baint úsáide as Python, agus ansin iad a chur ar fáil do do theimpléid ag baint úsáide as an gclibe:ttag: \`{% load%}.

## Leagan amach cód

Tá an áit is coitianta chun clibeanna agus scagairí teimpléad saincheaptha a shonrú taobh istigh d'aip Django. Má bhaineann siad le aip atá ann cheana, bíonn sé ciallmhar iad a thionscailt ansin; ar shlí eile, is féidir iad a chur le aip nua. Nuair a chuirtear aip Django leis: setting: INSTALLED\_APPS, cuirtear aon chlibeanna a shainmhíníonn sé sa ghnáthshuíomh a thuairiscítear thíos ar fáil go huathoibríoch le luchtú laistigh de theimpléid.

Ba chóir go mbeadh eolaire ```templatetags ``sa aip, ag an leibhéal céanna le ``models.py```, views.py\`, srl. Mura bhfuil sé seo ann cheana féin, cruthaigh é - ná déan dearmad ar an gcomhad `__init__.py` chun a chinntiú go ndéileálfar leis an eolaire mar phacáiste Python.

> **Ní atosóidh freastalaí forbartha go huath**
>
> Tar éis duit an modúl templatetags a chur leis, beidh ort do fhreastalaí a atosú sula bhféadfaidh tú na clibeanna nó na scagairí a úsáid i dteimpléid.

Beidh do chlibeanna saincheaptha agus scagairí cónaí i modúl taobh istigh den eolaire templatetags . Is é ainm an chomhaid modúl an t-ainm a úsáidfidh tú chun na clibeanna a luchtú níos déanaí, mar sin bí cúramach ainm a roghnú nach mbeidh ag teacht le clibeanna agus scagairí saincheaptha in aip eile.

Mar shampla, má tá do chlibeann/scagairí saincheaptha i gcomhad ar a dtugtar poll\_extras.py\`, d'fhéadfadh cuma seo a bheith ar leagan amach do aip:

```text
polls/
    __init__.py
    models.py
    templatetags/
        __init__.py
        poll_extras.py
    views.py
```

Agus i do theimpléad úsáideann tú an méid seo a leanas:

```html+django
{% load poll_extras %}
```

\<load\>Caithfidh an aip ina bhfuil na clibeanna saincheaptha a bheith in:setting: INSTALLED\_APPS ionas go n-oibreoidh an clibe:ttag: {% load%}. Is gné slándála í seo: Ligeann sé duit cód Python a óstáil do go leor leabharlanna teimpléad ar mheaisín óstach amháin gan rochtain a chumasú ar gach ceann acu do gach suiteáil Django.

Níl aon teorainn ar cé mhéad modúl a chuireann tú sa phacáiste templatetags . Coinnigh i gcuimhne go luchtál \<load\>faidh ráiteas a:ttag: {% load%} clibeannaí/scagairí d'ainm an mhodúil Python tugtha, ní ainm an aip.

Le bheith ina leabharlann bailí clibeanna, ní mór athróg leibhéal modúl a bheith sa mhodúl darb ainm `register` is sampla `Template.Library`, ina bhfuil na clibeanna agus na scagairí go léir cláraithe. Mar sin, in aice le barr do mhodúl, cuir an méid seo a leanas:

```
from django import template

register = template.Library()
```

De rogha air sin, is féidir modúil clib teimpléad a chlárú tríd an argóint 'libraries'\` chuig:class: ~django.template.backends.django.djangoTemplates. Tá sé seo úsáideach más mian leat lipéad difriúil a úsáid ó ainm an mhodúil clib teimpléid agus clibeanna teimpléad á luchtú. Cuireann sé ar do chumas clibeanna a chlárú gan feidhmchlár a shuiteáil.

> **Taobh thiar de na radhairc**
>
> Le haghaidh tonna samplaí, léigh an cód foinse do scagairí agus clibeanna réamhshocraithe Django. Tá siad in:source: django/template/defaultfilters.py agus:source: django/template/defaulttags.py, faoi seach.
>
> Le haghaidh tuilleadh faisnéise faoin gclibe:ttag: load, léigh a dhoiciméadú.

## Scagairí teimpléad saincheaptha

Is feidhmeanna Python iad scagairí saincheaptha a thógann argóint amháin nó dhó:

- Luach an athróg (ionchur) - ní gá gur sreang é.
- Luach na hargóinte - is féidir luach réamhshocraithe a bheith aige seo, nó é a fhágáil amach ar fad.

Mar shampla, sa scagaire `{{var|foo: "bar”}}`, chuirfeadh an scagaire `foo` ar an athróg `var` agus an argóint `"bar"`.

Ós rud é nach soláthraíonn teanga an teimpléid láimhseáil eisceachta, nochtfar aon eisceacht a ardaítear ó scagaire teimpléid mar earráid freastalaí Dá bhrí sin, ba cheart d'fheidhmeanna scagaire eisceachtaí a ardú a sheachaint má tá luach titim réasúnta le filleadh. I gcás ionchuir a léiríonn fabht shoiléir i dteimpléad, b'fhéidir go mbeadh eisceacht níos fearr fós ná teip chiúin a chuireann an fabht i bhfolach.

Seo sainmhíniú scagaire sampla:

```
def cut(value, arg):
    """Removes all values of arg from the given string"""
    return value.replace(arg, "")
```

Agus seo sampla den chaoi a n-úsáidfí an scagaire sin:

```html+django
{{ somevariable|cut:"0" }}
```

Ní ghlacann mórchuid na scagairí argóintí. Sa chás seo, fág an argóint as do fheidhm:

```
def lower(value):  # Only one argument.
    """Converts a string into all lowercase"""
    return value.lower()
```

### Clárú scagairí saincheap

#### `django.template.Library.filter()`

Nuair a bheidh do shainmhíniú scagaire scagaire scagaire scríofa agat, ní mór duit é a chlárú le do shampla `Leabharla`, chun é a chur ar fáil do theanga teimpléad Django:

```
register.filter("cut", cut)
register.filter("lower", lower)
```

Tógann an modh Library.filter () dhá argóint:

1. Ainm an scagaire - sreang.
2. An fheidhm tiomsaithe - feidhm Python (ní ainm na feidhme mar shreang).

Is féidir leat register.filter () a úsáid mar mhaisitheoir ina ionad sin:

```
@register.filter(name="cut")
def cut(value, arg):
    return value.replace(arg, "")

@register.filter
def lower(value):
    return value.lower()
```

Má fhágann tú an argóint ainm amach, mar atá sa dara sampla thuas, úsáidfidh Django ainm na feidhme mar ainm an scagaire.

Faoi dheireadh, glacann ```register.filter () ``le trí argóint eochairfhocal freisin, ``is_safe```, needs\_autoescape\`, agus `expects_localtime`. \<filters-timezones\>Déantar cur síos ar na hargóintí seo in:ref: scagairí agus éalú uathoibríoch \`agus \<filters-auto-escaping\>:ref: \`scagairí agus criosanna ama thíos.

### Scagairí teimpléad a bhfuil súil le

#### `django.template.defaultfilters.stringfilter()`

Má tá scagaire teimpléad á scríobh agat nach bhfuil súil le sreang ach mar an chéad argóint, ba cheart duit an maisitheoir `stringfilter` a úsáid. Déanfaidh sé seo réad a thiontú go luach sreangán sula gcuirfear ar aghaidh chuig do fheidhm:

```
from django import template
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter
@stringfilter
def lower(value):
    return value.lower()
```

Ar an mbealach seo, beidh tú in ann, abair, sláimhir a chur chuig an scagaire seo, agus ní bheidh sé ina chúis le `AttributeError` (toisc nach bhfuil modhanna lower () ag sláimhreacha).

### Scagairí agus éalú uathoibrí

Agus scagaire saincheaptha á scríobh agat, smaoinigh roinnt ar an gcaoi a n-idirghníomhaíonn an scagaire le hiompar éalaithe uathoibríoch Tabhair faoi deara gur féidir dhá chineál teaghráin a chur timpeall taobh istigh den chód teimpléid:

- **Is iad sreangaí amha** na teaghráin dúchasacha Python. Ar aschur, éalaítear iad má tá éalú uathoibríoch i bhfeidhm agus má chuirtear i láthair gan athrú, ar shlí eile.
- \*\* Is teaghráin iad sreangaí sábháilte\*\* atá marcáilte sábháilte ó éalú breise ag am aschuir. Tá aon éalú riachtanach déanta cheana féin. Úsáidtear iad go coitianta le haghaidh aschur ina bhfuil HTML amh atá beartaithe a léirmhíniú mar atá ar thaobh an chliaint.

  Go hinmheánach, tá na teaghráin seo de chineál:class: ~django.utils.safeString.SafeString. Is féidir leat tástáil a dhéanamh dóibh ag baint úsáide as cód mar:

  ```
  from django.utils.safestring import SafeString

  if isinstance(value, SafeString):
      # Do something with the "safe" string.
      ...
  ```

Tagann cód scagaire teimpléad i gceann de dhá chás:

1. Ní thugann do scagaire aon charachtair neamhshábháilte HTML isteach (`<`, \>\`, `` , ` ``,\`\`\` ``nó `&``) isteach sa toradh nach raibh i láthair cheana féin. Sa chás seo, is féidir leat ligean do Django aire a thabhairt don láimhseáil uathoibríoch a éalú duit. Níl le déanamh agat ach an bhratach `is_safe` a shocrú go `True` nuair a chláraíonn tú do fheidhm scagaire, mar sin:

   ```
   @register.filter(is_safe=True)
   def myfilter(value):
       return value
   ```

   Insíonn an bratach seo le Django má chuirtear sreang “sábháilte” isteach i do scagaire, go mbeidh an toradh fós “sábháilte” agus má chuirtear sreang neamh-shábháilte isteach, éalóidh Django go huathoibríoch é, más gá.

   Is féidir leat smaoineamh air seo mar chiallaíonn “tá an scagaire seo sábháilte - ní thugann sé isteach aon fhéidearthacht go mbeidh HTML neamhshábháilte ann.”

   Is é an chúis go bhfuil is\_safe\` riachtanach ná go bhfuil neart gnáthoibríochtaí teaghrán ann a chasfaidh réad Safedata\` ar ais ina ngnáthrud str\` agus, seachas iarracht a dhéanamh iad go léir a ghabháil, rud a bheadh an-deacair, déanann Django an damáiste tar éis don scagaire a bheith críochnaithe.

   Mar shampla, cuir i gcás go bhfuil scagaire agat a chuireann an teaghrán `xx` le deireadh aon ionchuir. Ós rud é nach dtugann sé seo aon charachtair HTML contúirteacha isteach don toradh (seachas aon cheann a bhí i láthair cheana féin), ba cheart duit do scagaire a mharcáil le `is_safe`:

   ```
   @register.filter(is_safe=True)
   def add_xx(value):
       return "%sxx" % value
   ```

   Nuair a úsáidtear an scagaire seo i dteimpléad ina bhfuil éalú uathoibríoch cumasaithe, éalóidh Django ón aschur aon uair nach bhfuil an t-ionchur marcáilte mar “sábháilte” cheana féin.

   De réir réamhshocraithe, is é `is_safe` False\`, agus is féidir leat é a fhágáil ó aon scagairí nuair nach bhfuil sé ag teastáil.

   Bí cúramach agus tú ag cinneadh an bhfágann do scagaire teaghráin sábháilte chomh sábháilte Má tá carachtair agata\* á bhaint agat, d'fhéadfá clibeanna nó eintiteas HTML neamhchothromaithe a fhágáil sa toradh de thaisme. Mar shampla, d'fhéadfadh `>` a bhaint as an ionchur \`\` a iompú ina \<a\>\<a\`, a bheadh a éalú ar aschur chun fadhbanna a sheachaint. Ar an gcaoi chéanna, is féidir leath-earrthóg a bhaint (`;`) & \`\`a iompú ina \`&\`, nach eintiteas bailí a thuilleadh é agus dá bhrí sin ní mór tuilleadh éalú. Ní bheidh an chuid is mó de na cásanna beagnach deacair seo, ach coinnigh súil amach ar aon fhadhbanna mar sin agus tú ag athbhreithniú ar do chód.

   Cuirfidh marcáil scagaire `is_safe` iallach ar luach fillte an scagaire chuig teaghrán. Más chóir do scagaire luach boolean nó neamh-sreang eile a thabhairt ar ais, is dócha go mbeidh iarmhairtí neamhbheartaithe ag é a mharcáil `is_safe` (mar shampla False boolean a thiontú go dtí an sreang 'False').
2. De rogha air sin, is féidir le do chód scagaire aire a thabhairt de láimh d'aon éalú riachtanach. Tá sé seo riachtanach nuair a bhíonn marcáil HTML nua á thabhairt isteach sa toradh. Ba mhaith leat an t-aschur a mharcáil mar shábháilte ó éalú breise ionas nach n-éalaíonn do mharcáil HTML níos faide, mar sin beidh ort an t-ionchur a láimhseáil tú féin.

   Chun an t-aschur a mharcáil mar shreang sábháilte, bain úsáid as: func: django.utils.safestring.mark\_safe.

   Bí cúramach, áfach. Ní mór duit níos mó a dhéanamh ná an t-aschur a mharcáil mar shábháilte. Ní mór duit a chinntiú go bhfuil sé\* sábháilte i ndáiríre, agus braitheann an méid a dhéanann tú ar an bhfuil éalú uathoibríoch i bhfeidhm. Is é an smaoineamh scagairí a scríobh atá in ann oibriú i dteimpléid ina bhfuil éalú uathoibríoch ar nó as d'fhonn rudaí a dhéanamh níos éasca d'údair teimpléid.

   Ionas go mbeidh a fhios ag do scagaire an stát reatha éalaithe uathoibríoch, socraigh an bhratach needs\_autoescape\` go True\` nuair a chláraíonn tú d'fheidhm scagaire. (Mura ndéanann tú an bratach seo a shonrú, tá sé réamhshocraithe go `False`). Insíonn an bratach seo do Django go bhfuil d'fheidhm scagaire ag iarraidh argóint eochairfhocal breise a rith, ar a dtugtar `autoescape`, is é sin `True` má tá éalú uathoibríoch i bhfeidhm agus `False` a shlí eile. Moltar réamhshocrú an pharaiméadar `autoescape` a shocrú go `True`, ionas go mbeidh éalú cumasaithe aige de réir réamhshocraithe má ghlaonn tú ar an bhfeidhm ó chód Python.

   Mar shampla, scríobhfaimis scagaire a chuireann béim ar an gcéad charachtar de shreang:

   ```
   from django import template
   from django.utils.html import conditional_escape
   from django.utils.safestring import mark_safe

   register = template.Library()

   @register.filter(needs_autoescape=True)
   def initial_letter_filter(text, autoescape=True):
       first, other = text[0], text[1:]
       if autoescape:
           esc = conditional_escape
       else:
           esc = lambda x: x
       result = "<strong>%s</strong>%s" % (esc(first), esc(other))
       return mark_safe(result)
   ```

   Ciallaíonn an bhratach needs\_autoescape\` agus an argóint eochairfhocal `autoescape` go mbeidh a fhios ag ár bhfeidhm an bhfuil éalú uathoibríoch i bhfeidhm nuair a ghlaofar an scagaire. Úsáidimid `autoescape` chun cinneadh a dhéanamh an gcaithfear na sonraí ionchuir a chur tríd `django.utils.html.conditional_escape` nó nach bhfuil. (Sa chás deireanach, úsáidimid an fheidhm aitheantais mar fheidhm “éalaithe”.) Tá an fheidhm ```conditional_escape () ``cosúil le ``escape ()``` ach amháin nach n-éalaíonn sé ach ionchur nach ion\*\* mar shampla ```SafeData`. Má chuirtear cás ``SafeData``` chuig conditional\_escape () \`, cuirtear na sonraí ar ais gan athrú.

   Faoi dheireadh, sa sampla thuas, cuimhnímid an toradh a mharcáil mar shábháilte ionas go gcuirfear ár HTML isteach go díreach sa teimpléad gan éalú breise.

   Ní gá a bheith buartha faoin mbratach `is_safe` sa chás seo (cé nach ndéanfadh sé dochar ar bith). Aon uair a láimhseálann tú de láimh na fadhbanna uath-éalaithe agus a sheolann tú sreang shábháilte ar ais, ní athróidh an bhratach `is_sábháilte` tada ach an oiread.

> **Warning**
>
> Leochaileachtaí XSS a sheachaint agus scagairí ionsuite á athúsáid
>
> Tá autoescape=True\` ag scagairí ionsuite Django de réir réamhshocraithe d'fhonn an t-iompar ceart autoescaping a fháil agus leochaileacht script tras-láithreáin a sheachaint.
>
> I leaganacha níos sine de Django, bí cúramach agus tú ag athúsáid scagairí ionsuite Django mar réamhshocraithe `autoescape` go ```None ``. Beidh ort pas a dhéanamh ``autoescape=True``` chun autoescaping a fháil.
>
> Mar shampla, dá dteastaíonn uait scagaire saincheaptha a scríobh darb ainm urlize\_and\_linebreaks\` a chomhcheangail scagairí:tfilter: urlize agus:tfilter: linebreaksbr, bheadh an scagaire mar:
>
> ```
> from django.template.defaultfilters import linebreaksbr, urlize
>
>
> @register.filter(needs_autoescape=True)
> def urlize_and_linebreaks(text, autoescape=True):
>     return linebreaksbr(urlize(text, autoescape=autoescape), autoescape=autoescape)
> ```
>
> Ansin:
>
> ```html+django
> {{ comment|urlize_and_linebreaks }}
> ```
>
> bheadh sé coibhéiseach le:
>
> ```html+django
> {{ comment|urlize|linebreaksbr }}
> ```

### Scagairí agus criosanna ama

Má scríobhann tú scagaire saincheaptha a oibríonn ar ruda:class: ~datetime.datetime, de ghnáth cláróidh tú é leis an bhratach `expects_localtime` atá socraithe go `True`:

```
@register.filter(expects_localtime=True)
def businesshours(value):
    try:
        return 9 <= value.hour < 17
    except AttributeError:
        return ""
```

\<time-zones-in-templates\>Nuair a shocraítear an bratach seo, más dáta-am atá ar an eolas ar chrios ama an chéad argóint le do scagaire, tiontóidh Django é go dtí an crios ama reatha sula gcuireann sé chuig do scagaire nuair is cuí, de réir: ref: rialacha maidir le tiontaithe criosanna ama i dteimpléid .

## Clibeanna teimpléad saincheaptha a

Tá clibeanna níos casta ná scagairí, toisc gur féidir le clibeanna rud ar bith a dhéanamh. Soláthraíonn Django roinnt aicearraí a fhágann go bhfuil an chuid is mó de na cineálacha clibeanna níos éasca scrí Ar dtús déanfaimid iniúchadh ar na aicearraí sin, ansin míneoimid conas clib a scríobh ón tús do na cásanna sin nuair nach bhfuil na aicearraí cumhachtach go leor.

### Clibeanna simplí

#### `django.template.Library.simple_tag()`

Tógann go leor clibeanna teimpléid roinnt argóintí - teaghráin nó athróga teimpléad - agus filleann siad toradh ar ais tar éis roinnt próiseála a dhéanamh bunaithe ar na hargóintí ionchuir agus roinnt faisnéise seachtrach amháin. Mar shampla, d'fhéadfadh clib `current_time` glacadh le teaghrán formáide agus an t-am a thabhairt ar ais mar shreang a fhormáidithe dá réir.

Chun cruthú na gcineálacha clibeanna seo a éascú, soláthraíonn Django feidhm chúntóra, ```simple_tag ``. Glacann an fheidhm seo, ar modh é de ``Django.Template.Library```, feidhm a ghlacann le haon líon argóintí, fillteann sé i bhfeidhm `render` agus na giotáin riachtanacha eile a luaitear thuas agus cláraíonn sé leis an gcóras teimpléid.

Mar sin d'fhéadfaí ár bhfeidhm `current_time` a scríobh mar seo:

```
import datetime
from django import template

register = template.Library()

@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)
```

Cúpla rud le tabhairt faoi deara faoin bhfeidhm chúntóra `simple_tag`:

- Rinneadh an líon riachtanach argóintí, srl., Seiceáil cheana féin faoin am a dtugtar ár bhfeidhm, mar sin ní gá dúinn é sin a dhéanamh.
- Tá na luachana timpeall an argóint (más ann) curtha amach cheana féin, mar sin faighimid sreang simplí.
- Más athróg teimpléad a bhí ag an argóint, cuirtear ár bhfeidhm ar luach reatha an athróg a rith, ní an athróg féin.

Murab ionann agus fóntais clibeanna eile, téann `simple_tag` a aschur trí:func: ~django.utils.html.conditional\_escape má tá comhthéacs an teimpléid i mód autoescape, chun HTML ceart a chinntiú agus tú a chosaint ó leochaileachtaí XSS.

Mura bhfuil éalú breise ag teastáil, beidh ort: func: ~django.utils.safestring.mark\_safe a úsáid má tá tú cinnte go hiomlán nach bhfuil leochaileachtaí XSS i do chód. Chun scoileanna beaga HTML a thógáil, moltar go láidir: func: ~django.utils.html.format\_html in ionad mark\_safe () .

Más gá do chlib teimpléad rochtain a fháil ar an gcomhthéacs reatha, is féidir leat an argóint `takes_context` a úsáid agus do chlib á chlárú:

```
@register.simple_tag(takes_context=True)
def current_time(context, format_string):
    timezone = context["timezone"]
    return your_get_current_time_method(timezone, format_string)
```

Tabhair faoi deara go gcaithfear context\` a thugtar ar an gcéad argóint .

\<howto-custom-template-tags-inclusion-tags\>Le haghaidh tuilleadh faisnéise faoin gcaoi a n-oibríonn an rogha `takes_context`, féach an chuid ar:ref: clibeanna cuimsithe .

Más gá duit do chlib a athainmniú, is féidir leat ainm saincheaptha a sholáthar dó:

```
register.simple_tag(lambda x: x - 1, name="minusone")

@register.simple_tag(name="minustwo")
def some_function(value):
    return value - 2
```

Féadfaidh feidhmeanna simple\_tag glacadh le haon líon argóintí seasaimh nó eochairfhocal. Mar shampla:

```
@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs["warning"]
    profile = kwargs["profile"]
    ...
    return ...
```

Ansin, sa teimpléad féadfar aon líon argóintí, scartha le spásanna, a chur chuig an gclib teimpléid. Cosúil le Python, socraítear na luachanna le haghaidh argóintí eochairfhocal ag baint úsáide as an gcomhartha comhionann (“= \`”) agus caithfear iad a sholáthar tar éis na hargóintí seasaimh. Mar shampla:

```html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
```

Is féidir torthaí an chlib a stóráil in athróg teimpléad seachas é a chur amach go díreach. Déantar é seo tríd an argóint `as` a úsáid ina dhiaidh sin an t-ainm athróg. Má dhéantar é sin, cuireann sé ar do chumas an t-ábhar a aschur tú féin nuair is cuí leat:

```html+django
{% current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>
```

### Simple block tags

> **New in Django 5.2**

#### `django.template.Library.simple_block_tag()`

When a section of rendered template needs to be passed into a custom tag,
Django provides the `simple_block_tag` helper function to accomplish this.
Similar to [`simple_tag()`](#django.template.Library.simple_tag), this function accepts
a custom tag function, but with the additional `content` argument, which
contains the rendered content as defined inside the tag. This allows dynamic
template sections to be easily incorporated into custom tags.

For example, a custom block tag which creates a chart could look like this:

```
from django import template
from myapp.charts import render_chart

register = template.Library()

@register.simple_block_tag
def chart(content):
    return render_chart(source=content)
```

The `content` argument contains everything in between the `{% chart %}`
and `{% endchart %}` tags:

```html+django
{% chart %}
  digraph G {
      label = "Chart for {{ request.user }}"
      A -> {B C}
  }
{% endchart %}
```

If there are other template tags or variables inside the `content` block,
they will be rendered before being passed to the tag function. In the example
above, `request.user` will be resolved by the time `render_chart` is
called.

Block tags are closed with `end{name}` (for example, `endchart`). This can
be customized with the `end_name` parameter:

```
@register.simple_block_tag(end_name="endofchart")
def chart(content):
    return render_chart(source=content)
```

Which would require a template definition like this:

```html+django
{% chart %}
  digraph G {
      label = "Chart for {{ request.user }}"
      A -> {B C}
  }
{% endofchart %}
```

A few things to note about `simple_block_tag`:

- The first argument must be called `content`, and it will contain the
  contents of the template tag as a rendered string.
- Variables passed to the tag are not included in the rendering context of the
  content, as would be when using the `{% with %}` tag.

Just like [simple\_tag](#howto-custom-template-tags-simple-tags),
`simple_block_tag`:

- Validates the quantity and quality of the arguments.
- Strips quotes from arguments if necessary.
- Escapes the output accordingly.
- Supports passing `takes_context=True` at registration time to access
  context. Note that in this case, the first argument to the custom function
  *must* be called `context`, and `content` must follow.
- Supports renaming the tag by passing the `name` argument when registering.
- Supports accepting any number of positional or keyword arguments.
- Supports storing the result in a template variable using the `as` variant.

> **Content Escaping**
>
> `simple_block_tag` behaves similarly to `simple_tag` regarding
> auto-escaping. For details on escaping and safety, refer to `simple_tag`.
> Because the `content` argument has already been rendered by Django, it is
> already escaped.

#### A complete example

Consider a custom template tag that generates a message box that supports
multiple message levels and content beyond a simple phrase. This could be
implemented using a `simple_block_tag` as follows:

*`testapp/templatetags/testapptags.py`*

```python
from django import template
from django.utils.html import format_html

register = template.Library()

@register.simple_block_tag(takes_context=True)
def msgbox(context, content, level):
    format_kwargs = {
        "level": level.lower(),
        "level_title": level.capitalize(),
        "content": content,
        "open": " open" if level.lower() == "error" else "",
        "site": context.get("site", "My Site"),
    }
    result = """
    <div class="msgbox {level}">
      <details{open}>
        <summary>
          <strong>{level_title}</strong>: Please read for <i>{site}</i>
        </summary>
        <p>
          {content}
        </p>
      </details>
    </div>
    """
    return format_html(result, **format_kwargs)
```

When combined with a minimal view and corresponding template, as shown here:

*`testapp/views.py`*

```python
from django.shortcuts import render

def simpleblocktag_view(request):
    return render(request, "test.html", context={"site": "Important Site"})
```

*`testapp/templates/test.html`*

```html+django
{% extends "base.html" %}

{% load testapptags %}

{% block content %}

  {% msgbox level="error" %}
    Please fix all errors. Further documentation can be found at
    <a href="http://example.com">Docs</a>.
  {% endmsgbox %}

  {% msgbox level="info" %}
    More information at: <a href="http://othersite.com">Other Site</a>/
  {% endmsgbox %}

{% endblock %}
```

The following HTML is produced as the rendered output:

```html
<div class="msgbox error">
  <details open>
    <summary>
      <strong>Error</strong>: Please read for <i>Important Site</i>
    </summary>
    <p>
      Please fix all errors. Further documentation can be found at
      <a href="http://example.com">Docs</a>.
    </p>
  </details>
</div>

<div class="msgbox info">
  <details>
    <summary>
      <strong>Info</strong>: Please read for <i>Important Site</i>
    </summary>
    <p>
      More information at: <a href="http://othersite.com">Other Site</a>
    </p>
  </details>
</div>
```

### Clibeanna cuimsithe

#### `django.template.Library.inclusion_tag()`

Cineál coitianta eile de chlib teimpléad is ea an cineál a thaispeánann roinnt sonraí trí\* teimpléad\* eile a rindreáil. Mar shampla, úsáideann comhéadan riaracháin Django clibeanna teimpléad saincheaptha chun na cnaipí a thaispeáint feadh bun na leathanaigh fhoirme “cuir/athraigh”. Breathnaíonn na cnaipí sin mar an gcéanna i gcónaí, ach athraíonn spriocanna na nasc ag brath ar an réad atá á chur in eagar - mar sin is cás foirfe iad chun teimpléad beag a úsáid atá líonta le sonraí ón réad reatha. (I gcás an riaracháin, is é seo an chlib submit\_row .)

Tugtar “clibeanna cuimsithe” ar na cineálacha clibeanna seo.

Is dócha gur fearr clibeanna cuimsithe a scríobh le sampla. \<creating-models\>Scríobhfaimis clib a aschuireann liosta roghanna le haghaidh réad `Poll` ar leith, mar a cruthaíodh in:ref: ranganna teagaisc\`. Úsáidfimid an chlib mar seo:

```html+django
{% show_results poll %}
```

... agus beidh an t-aschur mar seo:

```html
<ul>
  <li>First choice</li>
  <li>Second choice</li>
  <li>Third choice</li>
</ul>
```

Ar dtús, sainmhínigh an fheidhm a thógann an argóint agus a tháirgeann foclóir sonraí don toradh. Is é an pointe tábhachtach anseo ná nach gá dúinn ach foclóir a thabhairt ar ais, ní rud ar bith níos casta. Úsáidfear é seo mar chomhthéacs teimpléid don bhrúin teimpléid. Sampla:

```
def show_results(poll):
    choices = poll.choice_set.all()
    return {"choices": choices}
```

Ansin, cruthaigh an teimpléad a úsáidtear chun aschur an chlib a léiriú. Is gné seasta den chlib é an teimpléad seo: sonraíonn an scríbhneoir clib é, ní dearthóir an teimpléid. Ag leanúint ár sampla, tá an teimpléad an-ghearr:

```html+django
<ul>
{% for choice in choices %}
    <li> {{ choice }} </li>
{% endfor %}
</ul>
```

Anois, cruthaigh agus cláraigh an chlib cuimsithe tríd an modh inclusion\_tag () \`a ghlaoch ar réad \`\`Leabharla\`. Ag leanúint ár sampla, má tá an teimpléad thuas i gcomhad ar a dtugtar results.html\` i eolaire a chuardaigh an lódóir teimpléid, chlárfaimis an chlib mar seo:

```
# Here, register is a django.template.Library instance, as before
@register.inclusion_tag("results.html")
def show_results(poll): ...
```

De rogha air sin is féidir an clib cuimsithe a chlárú ag baint úsáide as:: class: django.template.template:

```
from django.template.loader import get_template

t = get_template("results.html")
register.inclusion_tag(t)(show_results)
```

... nuair a chruthaíonn sé an fheidhm ar dtús.

Uaireanta, d'fhéadfadh go mbeadh líon mór argóintí ag teastáil ó do chlibeanna cuimsithe, rud a fhágann gur pian d'údair teimpléid na hargóintí go léir a chur isteach agus cuimhneamh ar Chun é seo a réiteach, soláthraíonn Django rogha `takes_context` le haghaidh clibeanna cuimsithe. Má shonraíonn tú `takes_context` chun clib teimpléad a chruthú, ní bheidh aon argóintí riachtanacha ag an gclib, agus beidh argóint amháin ag an bhfeidhm bhunúsach Python - comhthéacs an teimpléid amhail nuair a ghlaoadh an chlib.

Mar shampla, abair go bhfuil clib cuimsithe á scríobh agat a úsáidfear i gcónaí i gcomhthéacs ina bhfuil athróga `home_link` agus home\_title\` a thaispeánann siar chuig an bpríomhleathanach. Seo an chuma a bheadh ar fheidhm Python:

```
@register.inclusion_tag("link.html", takes_context=True)
def jump_link(context):
    return {
        "link": context["home_link"],
        "title": context["home_title"],
    }
```

Tabhair faoi deara go gcaithfear context\` a thugtar ar an gcéad pharaiméadar don fheidhme\*\*.

Sa líne ```register.inclusion_tag () ``sin, shonraíomar ``Takes_context=True``` agus ainm an teimpléid. Seo an chuma a d'fhéadfadh a bheith ar an teimpléad `link.html`:

```html+django
Jump directly to <a href="{{ link }}">{{ title }}</a>.
```

Ansin, aon uair ar mhaith leat an chlib saincheaptha sin a úsáid, luchtaigh a leabharlann agus glaoigh air gan aon argóintí, mar sin:

```html+django
{% jump_link %}
```

Tabhair faoi deara nuair a bhíonn `takes_context=True` in úsáid agat, ní gá argóintí a chur ar aghaidh chuig an gclib teimpléad. Faigheann sé rochtain go huathoibríoch ar an gcomhthéacs.

Tá an paraiméadar `takes_context` réamhshocraithe go `False`. Nuair a shocraítear é go True\`, cuirtear an chlib ar aghaidh an réad comhthéacs, mar atá sa sampla seo. Sin an t-aon difríocht idir an cás seo agus an sampla inclusion\_tag roimhe seo.

Féadfaidh feidhmeanna inclusion\_tag glacadh le haon líon argóintí seasaimh nó eochairfhocal. Mar shampla:

```
@register.inclusion_tag("my_template.html")
def my_tag(a, b, *args, **kwargs):
    warning = kwargs["warning"]
    profile = kwargs["profile"]
    ...
    return ...
```

Ansin, sa teimpléad féadfar aon líon argóintí, scartha le spásanna, a chur chuig an gclib teimpléid. Cosúil le Python, socraítear na luachanna le haghaidh argóintí eochairfhocal ag baint úsáide as an gcomhartha comhionann (“= \`”) agus caithfear iad a sholáthar tar éis na hargóintí seasaimh. Mar shampla:

```html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
```

### Clibeanna teimpléad saincheaptha chun

Uaireanta ní leor na gnéithe bunúsacha le haghaidh cruthú clib teimpléad saincheaptha. Ná bíodh imní ort, tugann Django rochtain iomlán duit ar na hinmheánacha a theastaíonn chun clib teimpléad a thógáil ón talamh suas.

### Forbhreathnú tapa

Oibríonn an córas teimpléid i bpróiseas dhá chéim: tiomsú agus rindreáil. Chun clib teimpléad saincheaptha a shainiú, sonraíonn tú conas a oibríonn an tiomsú agus conas a oibríonn an rindreáil.

Nuair a thiomsaíonn Django teimpléad, scoilteann sé téacs an teimpléid amh ina “nóid”. Is sampla de `Django.Template.Node` é gach nód agus tá modh ```render () ``aige. Is é teimpléad tiomsaithe liosta de rudaí ``Node```. Nuair a ghlaonn tú ar render () \`\`ar réad teimpléad tiomsaithe, glaonn an teimpléad \`\`render ()\` ```ar gach ``Nód``` ina liosta nód, leis an gcomhthéacs a thugtar. Déantar na torthaí go léir a chomhcheangal le chéile chun aschur an teimpléid a fhoirmiú.

Dá bhrí sin, chun clib teimpléad saincheaptha a shainiú, sonraíonn tú conas a dhéantar an chlib teimpléad amh a thiontú ina ```Nód ``(an fheidhm tiomsaithe), agus cad a dhéanann modh `render ()``` an nód.

### Scríobh an fheidhm tiomsaithe

Maidir le gach clib teimpléad a thagann an parser teimpléad, glaonn sé feidhm Python le hábhar an chlib agus an réad parser féin. Tá an fheidhm seo freagrach as sampla Node a thabhairt ar ais bunaithe ar ábhar an chlib.

Mar shampla, scríobhfaimis cur i bhfeidhm iomlán dár gclib teimpléad, `{% current_time%}`, a thaispeánann an dáta/am reatha, formáidithe de réir pharaiméadar a thugtar sa chlib, in:func: ~time.strftime comhréir. Is smaoineamh maith é comhréir an chlib a chinneadh roimh aon rud eile. Inár gcás, abair gur chóir an chlib a úsáid mar seo:

```html+django
<p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
```

Ba chóir don pháirseoir don fheidhm seo greim a ghlacadh leis an bparaiméadar agus réad `Node` a chruthú:

```
from django import template

def do_current_time(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, format_string = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires a single argument" % token.contents.split()[0]
        )
    if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
        raise template.TemplateSyntaxError(
            "%r tag's argument should be in quotes" % tag_name
        )
    return CurrentTimeNode(format_string[1:-1])
```

Nótaí:

- Is é `parser` an réad parser teimpléad. Níl sé de dhíth orainn sa sampla seo.
- Is teaghrán é `token.contents` d'amhábhar na clibe. Inár sampla, is é `'an t-am_reatha "%Y-%m-%d %I:%M %p"'`.
- Déanann an modh token.split\_contents () scarann na hargóintí ar spásanna agus teaghráin luaite á choinneáil le chéile. Ní bheadh an token.contents.split () níos simplí chomh láidir, mar a roinnfeadh sé go naif ar\*gach spásanna, lena n-áirítear iad siúd laistigh de theaghráin luaite. Is smaoineamh maith é token.split\_contents () a úsáid i gcónaí.
- Tá an fheidhm seo freagrach as `Django.Template.Template.TemplateSyntaxError` a ardú, le teachtaireachtaí cabhracha, le haghaidh aon earráid comhréireachta.
- Úsáideann eisceachtaí `TemplateSyntaxError` an athróg `tag_name`. Ná déan ainm an chlib a chódú go crua i do theachtaireachtaí earráide, toisc go gcomhcheanglaíonn sé ainm an chlib le do fheidhm. token.contents.split () \[0\] is ainm do chlib “i gcónaí” - fiú nuair nach bhfuil aon argóintí ag an gclib.
- Tugann an fheidhm `CurrentTimeNode` ar ais le gach rud a chaithfidh an nód a bheith ar an eolas faoin gclib seo. Sa chás seo, téann sé an argóint - `"%Y-%M-%D %I: %M %p"`. Baintear na luachana tosaigh agus leantacha ón gclib teimpléid i format\_string \[1: -1\] .
- Tá an parsáil an-íseal. Rinne forbróirí Django turgnamh le creataí beaga a scríobh ar bharr an chórais pháirseála seo, ag baint úsáide as teicnící cosúil le gramadaí EBNF, ach rinne na turgnaimh sin an t-inneall teimpléid ró-mhall. Tá sé ar leibhéal íseal toisc go bhfuil sé sin is tapúla.

### An láithreoir a scríobh

Is é an dara céim chun clibeanna saincheaptha a scríobh ná fo-aicme `Node` a bhfuil modh render () aige a shainiú.

Ag leanúint leis an sampla thuas, ní mór dúinn `CurrentTimeNode` a shainiú:

```
import datetime
from django import template

class CurrentTimeNode(template.Node):
    def __init__(self, format_string):
        self.format_string = format_string

    def render(self, context):
        return datetime.datetime.now().strftime(self.format_string)
```

Nótaí:

- Faigheann ```__init__ () ``an `format_string``` ó `do_current_time ()`. Cuir aon roghanna/paraiméadair/argóintí i gcónaí chuig ```Nód ``tríd a ``__init__ ()```.
- Is é an modh render () an áit a dtarlaíonn an obair i ndáiríre.
- De ghnáth ba chóir go dteipeadh ar render () \`\`go ciúin, go háirithe i dtimpeallacht táirgeachta. I roinnt cásanna áfach, go háirithe má tá \`\`context.template.engine.debug\` `True`, féadfaidh an modh seo eisceacht a ardú chun dífhabhtú a dhéanamh níos éasca. Mar shampla, ardaíonn roinnt croíchlibeanna `django.template.templateSyntaxError` má fhaigheann siad an líon mícheart nó an cineál argóintí.

I ndeireadh na dála, is é an toradh a bhíonn ar an díchúpláil seo ar thiomsú agus ar rindreáil ná córas éifeachtach teimpléad, toisc gur féidir le teimpléad comhthéacsanna iolracha a sholáthar gan gá a pharsáil go minic.

### Creithnithe uathoibríoch

Níl an t-aschur ó chlibeanna teimpléad\*\* a reáchtáil go huathoibríoch tríd na scagairí éalaithe uathoibríoch (seachas:: ~django.template.library.simple\_tag mar a thuairiscítear thuas). Mar sin féin, tá cúpla rud ann fós ba chóir duit a choinneáil i gcuimhne agus tú ag scríobh clib teimpléad.

Má stóráilíonn modh render () \`\`do chlib teimpléad an toradh in athróg comhthéacs (seachas an toradh a thabhairt ar ais i sreang), ba chóir dó aire a thabhairt ar \`\`mark\_safe ()\` más cuí. Nuair a léirítear an t-athróg sa deireadh, beidh tionchar ag an suíomh uathoibríoch éalaithe atá i bhfeidhm ag an am air, mar sin ní mór ábhar a bheith sábháilte ó éalú breise a mharcáil mar sin.

Chomh maith leis sin, má chruthaíonn do chlib teimpléad comhthéacs nua chun roinnt fo-rindreáil a dhéanamh, socraigh an tréith éalaithe uathoibríoch le luach an chomhthéacs Glacann an modh `__init__` don rang `Context` paraiméadar ar a dtugtar `autoescape` is féidir leat a úsáid chun na críche seo. Mar shampla:

```
from django.template import Context

def render(self, context):
    # ...
    new_context = Context({"var": obj}, autoescape=context.autoescape)
    # ... Do something with new_context ...
```

Ní staid an-choitianta é seo, ach tá sé úsáideach má tá teimpléad á rindreáil agat féin. Mar shampla:

```
def render(self, context):
    t = context.template.engine.get_template("small_fragment.html")
    return t.render(Context({"var": obj}, autoescape=context.autoescape))
```

\<autoescape\>Dá mbeadh faillí againn an luach reatha `context.autoescape` a rith chuig ár `Context` nua sa sampla seo, bheadh na torthaí éalaithe go huathoibríoch i gcónaí\*, agus b'fhéidir nach é an t-iompar atá ag teastáil má úsáidtear an chlib teimpléad taobh istigh de a:ttag: {% autoescape off%} block.

### Creithnithe sábháilteachta

Nuair a bheidh nód parsáilte, féadfar a mhodh \`\` rindreála\`\` a thabhairt ar aon líon uaireanta. Ós rud é go reáchtáiltear Django uaireanta i dtimpeallachtaí il-snáithithe, d'fhéadfadh nód amháin a bheith ag rindreáil ag an am céanna le comhthéacsanna éagsúla mar fhreagra ar dhá iarratas ar leith. Mar sin, tá sé tábhachtach a chinntiú go bhfuil do chlibeanna teimpléid sábháilte le snáithe.

Chun a chinntiú go bhfuil do chlibeanna teimpléid sábháilte snáithe, níor cheart duit faisnéis stáit a stóráil ar an nód féin Mar shampla, soláthraíonn Django clib teimpléad buntin:ttag: timthriall a thioclaíonn i measc liosta de na teaghráin ar leith gach uair a dhéantar é a léiriú:

```html+django
{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2' %}">
        ...
    </tr>
{% endfor %}
```

D'fhéadfadh go mbeadh cuma mar seo ar chur i bhfeidhm naif ar `Cyclenode`:

```
import itertools
from django import template

class CycleNode(template.Node):
    def __init__(self, cyclevars):
        self.cycle_iter = itertools.cycle(cyclevars)

    def render(self, context):
        return next(self.cycle_iter)
```

Ach, cuir i gcás go bhfuil dhá theimpléad againn a dhéanann an snippet teimpléad ó thuas ag an am céanna:

1. Déanann Snáithe 1 a chéad athrú lúb, Cyclenode.render () filleann 'row1'
2. Déanann Snáithe 2 a chéad athrú lúb, Cyclenode.render () filleann 'row2'
3. Déanann Snáithe 1 a dara athrú lúb, Cyclenode.render () filleann 'row1'
4. Déanann Snáithe 2 a dara athrú lúb, Cyclenode.render () filleann 'row2'

Tá an CycleNode ag athrú, ach tá sé ag athrú ar fud an domhain. Chomh fada agus a bhaineann le Snáithe 1 agus Snáithe 2, bíonn an luach céanna ar ais i gcónaí. Ní hé seo an rud a theastaíonn uainn!

Chun aghaidh a thabhairt ar an bhfadhb seo, soláthraíonn Django `render_context` a bhaineann le `context` an teimpléid atá á rinneadh faoi láthair. Iompraíonn an `render_context` cosúil le foclóir Python, agus ba chóir é a úsáid chun stát `Node` a stóráil idir inghairmithe an modh `render`.

Déanaimis ár bhfeidhmiú `Cyclenode` a athfhachtú chun an `render_context` a úsáid:

```
class CycleNode(template.Node):
    def __init__(self, cyclevars):
        self.cyclevars = cyclevars

    def render(self, context):
        if self not in context.render_context:
            context.render_context[self] = itertools.cycle(self.cyclevars)
        cycle_iter = context.render_context[self]
        return next(cycle_iter)
```

Tabhair faoi deara go bhfuil sé sábháilte faisnéis dhomhanda a stóráil nach n-athróidh ar feadh saol an `Node` mar thréith. I gcás `Cyclenode`, ní athraíonn an argóint `ciclevars` tar éis an `Node` a bhunú, mar sin ní gá dúinn é a chur sa render\_context\`. Ach ba chóir faisnéis stáit atá sonrach don teimpléad atá á rinneadh faoi láthair, cosúil le hathrú reatha an `Cyclenode`, a stóráil sa `render_context`.

> **Note**
>
> Tabhair faoi deara conas a d'úsáid muid ```féin ``chun an fhaisnéis shonrach ``Cyclenode``` a scóip laistigh den `render_context`. D'fhéadfadh go mbeadh iolracha `Cyclenodes` i dteimpléad ar leith, mar sin ní mór dúinn a bheith cúramach gan faisnéis stáit nód eile a chlacadh. Is é an bealach is éasca chun é seo a dhéanamh ná `self` a úsáid i gcónaí mar an eochair isteach `render_context`. Má tá súil á choinneáil agat ar roinnt athróg stáit, déan foclóir render\_context \[self\] .

### An chlib a chlárú

\<howto-writing-custom-template-tags\>Mar fhocal scoir, cláraigh an chlib le sampla `Leabharlanna` do mhodúil, mar a mhínítear in:ref: clibeanna teimpléad saincheaptha a scríobh thuas. Sampla:

```
register.tag("current_time", do_current_time)
```

Tógann an modh tag () dhá argóint:

1. Ainm an chlib teimpléad - sreang. Má fhágtar é seo amach, úsáidfear ainm na feidhme tiomsaithe.
2. An fheidhm tiomsaithe - feidhm Python (ní ainm na feidhme mar shreang).

Mar is amhlaidh le clárú scagaire, is féidir é seo a úsáid mar mhaisitheoir freisin:

```
@register.tag(name="current_time")
def do_current_time(parser, token): ...

@register.tag
def shout(parser, token): ...
```

Má fhágann tú an argóint ainm amach, mar atá sa dara sampla thuas, úsáidfidh Django ainm na feidhme mar ainm an chlib.

### Athróga teimpléad a chur chuig an gclib

Cé gur féidir leat líon ar bith argóintí a chur chuig clib teimpléad ag baint úsáide as token.split\_contents () , déantar na hargóintí go léir díphacáil mar litríochtaí teaghrán. Teastaíonn beagán níos mó oibre d'fhonn ábhar dinimiciúil (athróg teimpléad) a chur chuig clib teimpléad mar argóint.

Cé gur fhormáidigh na samplaí roimhe seo an t-am reatha i sreang agus chuir an sreang ar ais, cuir i gcás gur theastaigh uait pas a: class: ~django.db.models.DateTimeField ó réad agus go mbeadh an formáid clib teimpléad agat an dáta-am sin:

```html+django
<p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>
```

Ar dtús, tabharfaidh token.split\_contents () trí luach ar ais:

1. Ainm an chlib `format_time`.
2. An teaghrán blog\_entry.date\_updated' (gan na luachana máguaird).
3. An teaghrán formáidithe `'"%Y-%M-%D %I: %M %p"'`. Cuimsíonn an luach tuairisceáin ó split\_contents () na luachana tosaigh agus na luachana leantacha le haghaidh litríochtaí sreangacha mar seo.

Anois ba chóir go dtosóidh cuma seo ar do chlib:

```
from django import template

def do_format_time(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, date_to_be_formatted, format_string = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires exactly two arguments" % token.contents.split()[0]
        )
    if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
        raise template.TemplateSyntaxError(
            "%r tag's argument should be in quotes" % tag_name
        )
    return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
```

Caithfidh tú an renderer a athrú freisin chun ábhar iarbhír na maoine `date_updated` den réad `blog_entry` a aisghabháil. Is féidir é seo a chur i gcrích trí úsáid a bhaint as an aicme ```Athraitheach () ``i `django.template```.

Chun an aicme `Variable` a úsáid, cuir ainm an athróg atá le réiteach é, agus ansin glaoigh ar variable.solve (context) . Mar sin, mar shampla:

```
class FormatTimeNode(template.Node):
    def __init__(self, date_to_be_formatted, format_string):
        self.date_to_be_formatted = template.Variable(date_to_be_formatted)
        self.format_string = format_string

    def render(self, context):
        try:
            actual_date = self.date_to_be_formatted.resolve(context)
            return actual_date.strftime(self.format_string)
        except template.VariableDoesNotExist:
            return ""
```

Caithfidh réiteach athraitheach eisceacht `VariableDoesNotExist` mura féidir leis an sreang a chuirtear chuige a réiteach i gcomhthéacs reatha an leathanaigh.

### Athróg a shocrú sa chomhthéacs

Aschuir na samplaí thuas luach. Go ginearálta, bíonn sé níos solúbtha má shocraíonn do chlibeanna teimpléid athróga teimpléid in ionad luachanna a aschuir. Ar an mbealach sin, is féidir le húdair teimpléid na luachanna a chruthaíonn do chlibeanna teimpléid a athúsáid.

Chun athróg a shocrú sa chomhthéacs, bain úsáid as sannadh foclóra ar an réad comhthéacs sa mhodh render () \`. Seo leagan nuashonraithe de `CurrentTimeNode` a leagann athróg teimpléad `current_time` in ionad é a chur amach:

```
import datetime
from django import template

class CurrentTimeNode2(template.Node):
    def __init__(self, format_string):
        self.format_string = format_string

    def render(self, context):
        context["current_time"] = datetime.datetime.now().strftime(self.format_string)
        return ""
```

Tabhair faoi deara go bhfilleann render () an teaghrán folamh. Ba chóir go gcuirfeadh render () aschur sreinge ar ais i gcónaí. Más athróg a shocraíonn an chlib teimpléad go léir, ba chóir go gcuirfeadh render () an teaghrán folamh ar ais.

Seo conas a úsáideann tú an leagan nua seo den chlib:

```html+django
{% current_time "%Y-%m-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>
```

> **Raon feidhme athraitheach i gcomh**
>
> Ní bheidh aon athróg atá leagtha amach sa chomhthéacs ar fáil ach sa `bloc` céanna den teimpléad ina sannadh é. Tá an t-iompar seo d'aon ghnó; soláthraíonn sé scóip d'athróga ionas nach mbeidh siad ag coinbhleacht le comhthéacs i mbloic eile.

Ach, tá fadhb ann le `CurrentTimeNode2`: Tá an t-ainm athróg `current_time` crua-chódaithe. Ciallaíonn sé seo go gcaithfidh tú a chinntiú nach n-úsáideann do theimpléad `{{current_time}}` áit ar bith eile, toisc go ndéanfaidh an `{% current_time%}` luach an athróg sin a fhorscríobh go dall. Réiteach níos glaine is ea an chlib teimpléid a shonrú ainm an athróg aschuir, mar sin:

```html+django
{% current_time "%Y-%m-%d %I:%M %p" as my_current_time %}
<p>The current time is {{ my_current_time }}.</p>
```

Chun é sin a dhéanamh, beidh ort an fheidhm thiomsaithe agus an rang Node a athfhachtú, mar sin:

```
import re

class CurrentTimeNode3(template.Node):
    def __init__(self, format_string, var_name):
        self.format_string = format_string
        self.var_name = var_name

    def render(self, context):
        context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
        return ""

def do_current_time(parser, token):
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires arguments" % token.contents.split()[0]
        )
    m = re.search(r"(.*?) as (\w+)", arg)
    if not m:
        raise template.TemplateSyntaxError("%r tag had invalid arguments" % tag_name)
    format_string, var_name = m.groups()
    if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
        raise template.TemplateSyntaxError(
            "%r tag's argument should be in quotes" % tag_name
        )
    return CurrentTimeNode3(format_string[1:-1], var_name)
```

Is é an difríocht anseo ná go nglacann ```do_current_time () ``an teaghrán formáide agus an t-ainm athraitheach, ag dul araon chuig ``CurrentTimeNode3```.

Faoi dheireadh, mura gá duit ach comhréir simplí a bheith agat le haghaidh do chlib teimpléad saincheaptha a nuashonrú comhthéacs, smaoinigh ar aiceara:meth: ~django.template.library.simple\_tag a úsáid, a thacaíonn le torthaí an chlib a shannadh d'athróg teimpléad.

### Parsáil go dtí chlib bloc eile

Is féidir le clibeanna teimpléad oibriú in éineacht Mar shampla, folaíonn an tag caighdeán:ttag: {% comment%}\<comment\> gach rud go dtí `{% endcomment%}`. Chun clib teimpléad mar seo a chruthú, bain úsáid as parser.parse () i do fheidhm tiomsaithe.

Seo mar a d'fhéadfaí clib {% comment%} simplithe a chur i bhfeidhm:

```
def do_comment(parser, token):
    nodelist = parser.parse(("endcomment",))
    parser.delete_first_token()
    return CommentNode()

class CommentNode(template.Node):
    def render(self, context):
        return ""
```

> **Note**
>
> Tá cur i bhfeidhm iarbhír de:ttag: {% comment%}\<comment\> beagán difriúil sa mhéid go gceadaíonn sé clibeanna teimpléad briste le feiceáil idir ``{% comment%} `agus`` {% endcomment%}\`. Déanann sé amhlaidh trí ghlaoch ar parser.skip\_past ('endcomment') \`\`in ionad \`\`parser.parse ('endcomment',))\` ina dhiaidh sin parser.delete\_first\_token () \`, agus ar an gcaoi sin giniúint liosta nód a sheachaint.

Tógann ```parser.parse () ``cúpla ainmneacha de chlibeanna bloc “le parsáil go dtí”. Tugann sé sampla de ``Django.Template.NodeList``` ar liosta é de na rudaí `Node` go léir a bhuail an parser “roimh” bhuail sé aon cheann de na clibeanna a ainmníodh sa tuple.

I ```"nodelist = parser.parse ('endcomment',)) "``sa sampla thuas, is liosta de na nóid go léir idir``` {% comment%} `agus` {% endcomment%} `, gan comhaireamh` {% comment%} `agus` {% endcomment%} féin.

Tar éis ```parser.parse () ``a ghlaoch, níor “ith” an parser an chlib``` {% endcomment%} ```fós, mar sin ní mór don chód glaoch go sainráite ar ``parser.delete_first_token ()```.

Tugann ```CommentNode.render () ``teaghrán folamh ar ais. Déantar neamhaird ar aon rud idir ``{% comment%}``` agus `{% endcomment%}`.

### Parsáil go dtí chlib bloc eile, agus ábhar a shábháil

Sa sampla roimhe seo, chaith ```do_comment () ``gach rud idir``` {% comment%} `agus` {% endcomment%} . In ionad sin a dhéanamh, is féidir rud éigin a dhéanamh leis an gcód idir clibeanna bloc.

Mar shampla, seo clib teimpléad saincheaptha, `{% upper%}`, a chaipitlíonn gach rud eatarthu féin agus `{% endupper%}`.

Úsáid:

```html+django
{% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
```

Mar atá sa sampla roimhe seo, úsáidfimid ```parser.parse () ``. Ach an uair seo, cuirimid an `nodelist``` mar thoradh air sin chuig an `Node`:

```
def do_upper(parser, token):
    nodelist = parser.parse(("endupper",))
    parser.delete_first_token()
    return UpperNode(nodelist)

class UpperNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist

    def render(self, context):
        output = self.nodelist.render(context)
        return output.upper()
```

Is é an t-aon choincheap nua anseo an ```self.nodelist.render (comhthéacs) ``i `UpperNode.render ()```.

\<if\>Le haghaidh tuilleadh samplaí de rindreáil casta, féach an cód foinse de:ttag: {% for%} in:source: \<for\>\`django/template/defaulttags.py\` agus:ttag: {% if%} in:source: django/template/smartif.py.
