{"title":"Penyesuaian etiket cetakan dan saringan","version":"3.2","locale":"id","docname":"howto/custom-template-tags","url":"/id/3.2/howto/custom-template-tags/","canonical":"https://djangodocs.dev/id/3.2/howto/custom-template-tags/","summary":"Cetakan bahasa Django datang dengan beragam luas dari built-in tags and filters dirancang untuk megnalamatkan kebutuhan pembawaan logis dari aplikasi anda. Namun,…","html":"<h1>Penyesuaian etiket cetakan dan saringan<a class=\"heading-anchor\" href=\"#custom-template-tags-and-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Cetakan bahasa Django datang dengan beragam luas dari <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/\"><span class=\"doc\">built-in tags and filters</span></a> dirancang untuk megnalamatkan kebutuhan pembawaan logis dari aplikasi anda. Namun, anda mungkin menemukan diri anda sendiri membutuhkan fungsi yang tidak dicakupi oleh inti kumpulan dari cetakan primitif. Anda dapat memperpanjang cetakan mesin dengan menentukan penyesuaian etiket dan penyaring menggunakan Python, dan membuat mereka tersedua pada cetakan anda menggunakan etiket <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a>.</p>\n<section id=\"code-layout\">\n<h2>Tata letak kode<a class=\"heading-anchor\" href=\"#code-layout\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Tempat paling umum untuk menentukan cetakan etiket dan penyaring adalah didalam aplikasi Django. Jika mereka terhubung pada aplikasi yang ada, dia masuk akal untuk menggabungkan mereka; kalau tidak, mereka dapat ditambahkan ke aplikasi baru. Ketika aplikasi Django ditambahkan ke <a class=\"reference internal\" href=\"/id/3.2/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>, etiket apapun dia tentukan dalam tempat biasa dibawah otomatis dibuat tersedia untuk dimuat dengan cetakan.</p>\n<p>Aplikasi harus mengandung sebuah direktori <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>, pada tingkatan sama seperti <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">views.py</span></code>, dll. Jika ini tidak ada, buat dia - jangan lupakan berkas <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__.py</span></code> untuk memastikan direktori diperlakukan sebagai paket Python.</p>\n<aside class=\"admonition-development-server-won-t-automatically-restart admonition\">\n<p class=\"admonition-title\">Peladen pengembangan tidak akan otomatis nyala kembali</p>\n<p>Setelah menambahkan modul  <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>, anda akan butuh memulai kembali peladen anda sebelum anda dapat menggunakan etiket atau penyaring dalam cetakan.</p>\n</aside>\n<p>Penyesuaian etiket dan penyaring anda akan berada dalam sebuah modul didalam direktori <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>. Nama dari berkas modul adalah nama anda akan gunakan untuk memuat etiket kemudian, jadi berhati-hatilah untuk mengambil sebuah nama yang tidak akan bentrok dengan penyesuaian etiket dan penyaring di aplikasi lain.</p>\n<p>Sebagai contoh, jika penyesuaian etiket/penyaring anda berada dalam sebuah berkas yang dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">poll_extras.py</span></code>, tata letak eplikasi anda mungkin terlihat seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">polls</span><span class=\"o\">/</span>\n    <span class=\"fm\">__init__</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">templatetags</span><span class=\"o\">/</span>\n        <span class=\"fm\">__init__</span><span class=\"o\">.</span><span class=\"n\">py</span>\n        <span class=\"n\">poll_extras</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">py</span>\n</code></pre></div>\n<p>Dan di cetakan anda, anda akan menggunakan berikut:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">load</span> <span class=\"nv\">poll_extras</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Aplikasi yang mengandung penyesuaian etiket harus berada dalam <a class=\"reference internal\" href=\"/id/3.2/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a> agar etiket <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a> bekerja. Ini adalah fitur keamanan: Dia mengizinkan anda untuk menempatkan kode Python untuk banyak cetakan pustaka pada sebuah mesin rumah tunggal tanpa mengadakan akses ke semua dari mereka untuk setiap pemasangan Django.</p>\n<p>Tidak ada batasan pada bagaimana banyak modul anda taruh dalam paket <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>. Hanya perlu diingat bahwa sebuah pernyataan <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a> akan memuatetiket/penyaring untuk nama modul Python yang diberikan, bukan nama dari aplikasi.</p>\n<p>Untuk menjadi pustaka sah, modul harus mengandung sebuah variabel tingkat-modul yang dinamai <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code> yaitu sebuah instance <code class=\"docutils literal notranslate\"><span class=\"pre\">template.Library</span></code>, dimana semua etiket dan penyaring didaftarkan. Jadi dekat diatas modul anda, taruh berikut:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Kalau tidak, cetakan modul etiket dapat didaftarkan melalui argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">'libraries'</span></code> ke <a class=\"reference internal\" href=\"/id/3.2/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code></a>. Ini berguna jika anda ingin menggunakan label berbeda dari nama cetakan modul etiket ketika memuat cetakan etiket. Dia juga mengadakan anda untuk mendaftar etiket tanpa memasang sebuah aplikasi.</p>\n<aside class=\"admonition-behind-the-scenes admonition\">\n<p class=\"admonition-title\">Dibalik layar</p>\n<p>Untuk banyak contoh, baca kode sumber untuk penatingan dan etiket awal Django. Mereka berada di <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/defaultfilters.py</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/defaulttags.py</span></code>, masing-masing.</p>\n<p>Untuk informasi lebih pada etiket <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">load</span></code></a>, baca dokumentasinya.</p>\n</aside>\n</section>\n<section id=\"writing-custom-template-filters\">\n<span id=\"howto-writing-custom-template-filters\"></span><h2>Menulis saringan cetakan penyesuaian<a class=\"heading-anchor\" href=\"#writing-custom-template-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Penyaring penyesuaian adalah fungsi Python yang mengambil satu atau dua argumen:</p>\n<ul class=\"simple\">\n<li><p>Nilai dari variabel (masukan) -- tidak perlu deretan karakter.</p></li>\n<li><p>Nilai dari argumen -- ini dapat mempunyai nilai awal, atau ditinggalkan sama sekali.</p></li>\n</ul>\n<p>Sebagai contoh, dalam saringan <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">var|foo:&quot;bar&quot;</span> <span class=\"pre\">}}</span></code>, the filter <code class=\"docutils literal notranslate\"><span class=\"pre\">foo</span></code> akan dilewatkan variabel <code class=\"docutils literal notranslate\"><span class=\"pre\">var</span></code> dan argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">''bar''</span></code>.</p>\n<p>Sejak cetakan bahasa tidak menyediakan penanganan pengecualian, setiap pengecualian yang muncul dari sebuah cetakan saringan akan tidak terlindungi sebagai sebuah kesalahan peladen. Dengan demikian, fungsi penyaring harus menghindari memunculkan pengecualian jika ada alasan nilai mundur untuk kembali. Dalam kasus dari masukan yang mewakili kesalahan jelas dalam sebuah cetakan, menampilkan pencegualian mungkin masih lebih baik daripada kegagalan diam yang menyembunyikan kesalahan.</p>\n<p>Ini adalah sebuah contoh pengertian saringan</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">cut</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;Removes all values of arg from the given string&quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">replace</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Dan ini adalah sebuah contoh bagaimana saringan itu akan digunakan:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">somevariable</span><span class=\"o\">|</span><span class=\"nf\">cut</span><span class=\"s2\">:&quot;0&quot;</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>Kebanyakan penyaring tidak mengambil argumen. Dalam kasus ini, tinggalkan argumen dari fungsi anda:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span> <span class=\"c1\"># Only one argument.</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;Converts a string into all lowercase&quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<section id=\"registering-custom-filters\">\n<h3>Mendaftarkan saringan penyesuaian<a class=\"heading-anchor\" href=\"#registering-custom-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.filter\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">filter</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.filter\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Sekali anda telah menulis arti saringan anda, anda butuh mendaftarkannya dengan instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Library</span></code> anda, untuk membuatnya tersedia pada bahasa cetakan Django:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"s1\">&#39;cut&#39;</span><span class=\"p\">,</span> <span class=\"n\">cut</span><span class=\"p\">)</span>\n<span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"s1\">&#39;lower&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cara <code class=\"docutils literal notranslate\"><span class=\"pre\">Library.filter()</span></code> mengambil dua argumen:</p>\n<ol class=\"arabic simple\">\n<li><p>Nama dari saringan -- sebuah deretan karakter.</p></li>\n<li><p>Fungsi himpunan -- Sebuah fungsi Python (bukan nama fungsi sebagai deretan karakter).</p></li>\n</ol>\n<p>Anda dapat menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">register.filter()</span></code> sebagai penghias:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;cut&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">cut</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">replace</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Jika anda tidak mengubah argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code>, seperti di contoh kedua di atas, Django akan menggunakan nama fungsi sebagai nama filter.</p>\n<p>Akhirnya, <code class=\"docutils literal notranslate\"><span class=\"pre\">register.filter()</span></code> juga menerima tiga argumen katakunci, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code>, dan <code class=\"docutils literal notranslate\"><span class=\"pre\">expects_localtime</span></code>. Argumen ini digambarkan dalam <a class=\"reference internal\" href=\"#filters-auto-escaping\"><span class=\"std std-ref\">penyaring dan pelolosan otomatis</span></a> dan <a class=\"reference internal\" href=\"#filters-timezones\"><span class=\"std std-ref\">penyaring dan zona waktu</span></a> dibawah.</p>\n</section>\n<section id=\"template-filters-that-expect-strings\">\n<h3>Cetakan penyaring yang mengharapkan deretan karakter<a class=\"heading-anchor\" href=\"#template-filters-that-expect-strings\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.defaultfilters.stringfilter\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.defaultfilters.</span></span><span class=\"sig-name descname\"><span class=\"pre\">stringfilter</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.defaultfilters.stringfilter\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Jika anda sedang menulis sebuah cetakan penyaring yang hanya menerima sebuah deretan karakter sebagai argumen pertama, anda harus menggunakan decorator <code class=\"docutils literal notranslate\"><span class=\"pre\">stringfilter</span></code>. Ini akan merubah sebuah obyek ke nilai deretan karakternya sebelum dilewatkan ke fungsi anda:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.defaultfilters</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">stringfilter</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span>\n<span class=\"nd\">@stringfilter</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Jalan ini, anda akan dapat melewatkan, katakan, sebuah integer ke penyaring ini, dan dia tidak menyebabkan sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">AttributeError</span></code> (karena integer tidak mempunyai cara <code class=\"docutils literal notranslate\"><span class=\"pre\">lower()</span></code>).</p>\n</section>\n<section id=\"filters-and-auto-escaping\">\n<span id=\"filters-auto-escaping\"></span><h3>Penyaring dan pelolosan otomatis<a class=\"heading-anchor\" href=\"#filters-and-auto-escaping\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Ketika menulis penyesuaian penyaring, berikan beberapa pemikiran bagaimana penyaring akan berinteraksi dengan perilaku pelolosan-otomatis Django. Catat bahwa dua jenis dari string dapat dilewatkan didalam sekitar kode cetakan:</p>\n<ul>\n<li><p><strong>Raw strings</strong> adalah string Python asli. Pada keluaran, mereka diloloskan jika pelolosan-otomatis dalam pengaruh dan dihadirkan tidak berubah, sebaliknya.</p></li>\n<li><p><strong>Safe strings</strong> adalah deretan karakter yang telah ditandai aman dari pelolosan lanjut pada waktu keluar. Apa saja yang diperlukan pelolosan telah dilakukan. Mereka umumnya digunakan untuk keluaran yang mengandung HTML mentah yang akan di ditafsirkan apa adanya pada sisi klien.</p>\n<p>Secara internal, string ini adalah jenis <a class=\"reference internal\" href=\"/id/3.2/ref/utils/#django.utils.safestring.SafeString\" title=\"django.utils.safestring.SafeString\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SafeString</span></code></a>. Anda dapat mencoba mereka menggunakan kode seperti:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.safestring</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SafeString</span>\n\n<span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">SafeString</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Do something with the &quot;safe&quot; string.</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n</ul>\n<p>Kode cetakan penyaring gagal kedalam satu dari dua keadaan:</p>\n<ol class=\"arabic\">\n<li><p>Penyaring anda tidak memperkenalkan salah satu karakter tidak aman (<code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">&gt;</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">'</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;</span></code> atau <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;</span></code>) kedalam hasil yang tidak hadir. Dalam kasus ini, anda dapat membiarkan Django mengambil semua penanganan pelolosan otomatis untuk anda. Semua anda butuh untuk dilakukan adalah menyetel bendera <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> ke <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ketika anda mendaftar fungsi penyaringan, seperti begitu:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">is_safe</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">myfilter</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span>\n</code></pre></div>\n<p>Bendera ini memberitahu Django bahwa jika sebuah deretan karakter &quot;safe&quot; dilewatkan kedalam penyaring anda, hasil akan masih menjadi &quot;safe&quot; dan jika sebuah deretan karakter tidak aman dilewatkan, Django akan otomatis meloloskannya, jika diperlukan.</p>\n<p>Anda dapat berpikir dari ini sebagai berarti &quot;penyaring ini aman -- dia tidak memperkenalkan kemungkinan apapun dari HTML tidak aman.&quot;</p>\n<p>Alasan <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> perlu adalah karena ada banyak tindakan-tindakan string biasa yang akan merubah sebuah obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code> kembali ke obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code> biasa dan, daripada mencoba menangkap mereka semua, yang akan sangat sulit, Django memperbaiki kerusakan setelah penyaring lengkap.</p>\n<p>Sebagi contoh, andaikan anda mempunyai sebuah penyaring yang menambahkan deretan karakter <code class=\"docutils literal notranslate\"><span class=\"pre\">xx</span></code> ke akhir dari masukan. Sejak ini diperkenalkan karakter HTML tidak berbahaya ke hasil (selain dari apapun itu sudah hadir), anda harus menandai penyaring anda dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">is_safe</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">add_xx</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">xx&#39;</span> <span class=\"o\">%</span> <span class=\"n\">value</span>\n</code></pre></div>\n<p>Ketika penyaring ini digunakan dalam sebuah cetakan dimana pelolosan otomatis diadakan, Django akan meloloskan keluaran ketika masukan belum ditandai sebagai &quot;safe&quot;.</p>\n<p>Secara awalan, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, dan anda dapat menghilangkannya dari saringan dimana dia tidak wajib.</p>\n<p>Hati-hati ketika memutuskan jika penyaring anda sangat membiarkan deretan karakter aman sebagai safe. Jika anda sedang <em>memidnahkan</em> karakter, anda mungkin secara tidak sengaja membiarkan etiket HTML tidak seimbang atau kesatuan dalam hasil. Sebagai contoh, memindahkan sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">&gt;</span></code> dari masukan mungkin mengubah <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;a&gt;</span></code> menjadi <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;a</span></code>, yang akan butuh diloloskan pada keluaran untuk menghindari masalah. Demikian pula, memindahkan titik koma (<code class=\"docutils literal notranslate\"><span class=\"pre\">;</span></code>) dapat merubah <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;amp;</span></code> into <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;amp</span></code>, yang tidak lagi kesatuan sah dan demikian butuh pelolosan. Kebanyakan kasus tidak dekat dengan trik ini, tetapi jaga mata anda untuk masalah apapun seperti itu ketika meninjau kode anda.</p>\n<p>Menandai sebuah penyaring <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> akan memaksa nilai kembalian penyaring menjadi deretan karakter. Jika penyaring anda harus mengembalikan sebuah boolean atau nilai bukan deretan karakter, tandai dia <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> akan mungkin mempunyai konsekuensi yang tidak diinginkan (seperti merubah boolean False menjadi deretan karakter 'False').</p>\n</li>\n<li><p>Kalau tidak, kode penyaring anda dapat secara manual merawat pelolosan apapun yang dibutuhkan. Ini adalah penting ketika anda sedang memperkenalkan markah HTML baru kedalam hasil. Anda ingin menandai keluaran sebagai aman dari pelolosan lebih lanjut sehingga markah HTML anda tidak diloloskan lebih lanjut, jadi anda akan butuh menangani masukan diri anda sendiri.</p>\n<p>Untuk menandai keluaran sebagai deretan karakter aman, gunakan <a class=\"reference internal\" href=\"/id/3.2/ref/utils/#django.utils.safestring.mark_safe\" title=\"django.utils.safestring.mark_safe\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.utils.safestring.mark_safe()</span></code></a>.</p>\n<p>Berhati-hatilah, meskipun. Anda butuh melakukan lagi daripada hanya menandai keluaran sebagai aman. Anda butuh memastikan dia sangat <em>adalah</em> aman, dan apa yang anda lakukan tergantung pada apakah pelolosan otomatis berpengaruh. Idenya adalah menulis penyaring yang dapat berjalan dalam cetakan dimana pelolosan otomatis salah satunya nyala atau mati agar membuat hal-hal semakin mudah untuk cetakan penulis anda.</p>\n<p>Agar penyaring anda mengetahui keadaan pelolosan otomatis saat ini, setel bendera <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code> ke <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ketika anda mendaftar fungsi penyaring anda. (Jika anda tidak menentukan bendera ini, dia awalnya adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>). Bendera ini mengatakan Django bahwa fungsi penyaring anda ingin dilewatkan sebuah argumen katakunci tambahan, dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code>, yaitu <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> jika pelolosan otomatis dalam efek dan <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> sebaliknya. Sangat dianjurkan untuk menyetel parameter <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> ke <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, sehingga jika anda memanggil fungsi dari kode Python dia akan mempunyai pelolosan diadakan secara awal.</p>\n<p>Sebagai contoh, mari kita menulis penyaring yang menekankan karakter pertama dari sebuah deretan karakter:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.html</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">conditional_escape</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.safestring</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">mark_safe</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">needs_autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initial_letter_filter</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"n\">first</span><span class=\"p\">,</span> <span class=\"n\">other</span> <span class=\"o\">=</span> <span class=\"n\">text</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">text</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span>\n    <span class=\"k\">if</span> <span class=\"n\">autoescape</span><span class=\"p\">:</span>\n        <span class=\"n\">esc</span> <span class=\"o\">=</span> <span class=\"n\">conditional_escape</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">esc</span> <span class=\"o\">=</span> <span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">x</span>\n    <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;&lt;strong&gt;</span><span class=\"si\">%s</span><span class=\"s1\">&lt;/strong&gt;</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">esc</span><span class=\"p\">(</span><span class=\"n\">first</span><span class=\"p\">),</span> <span class=\"n\">esc</span><span class=\"p\">(</span><span class=\"n\">other</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">mark_safe</span><span class=\"p\">(</span><span class=\"n\">result</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code> flag and the <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> keyword argument mean\nthat our function will know whether automatic escaping is in effect when the\nfilter is called. We use <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> to decide whether the input data\nneeds to be passed through <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.html.conditional_escape</span></code> or not.\n(In the latter case, we use the identity function as the &quot;escape&quot; function.)\nThe <code class=\"docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code> function is like <code class=\"docutils literal notranslate\"><span class=\"pre\">escape()</span></code> except it only\nescapes input that is <strong>not</strong> a <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code> instance. If a <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code>\ninstance is passed to <code class=\"docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code>, the data is returned\nunchanged.</p>\n<p>Akhirnya, dalam contoh diatas, kami ingat untuk menandai hasil sebagai aman sehingga HTML kami dimasukkan langsung kedalam cetakan tanpa pelolosan lanjut.</p>\n<p>Tidak perlu khawatir tentang bendera <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> dalam kasus ini (meskipun termasuknya tidak akaan melukai apapun). Kapanpun anda secara manual menangani masalah pelolosan otomatis dan mengembalikan sebuah deretan karakter aman, bendera <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> tidak merubah apapun.</p>\n</li>\n</ol>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Peringatan</p>\n<p>Menghindari kerentanan XSS ketika menggunakan ulang filter bawaan</p>\n<p>Penyaring siap pakai Django mempunyai <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape=True</span></code> secara awal agar mendapatkan kebiasaan pelolosan otomatis yang benar dan menghindari kerentanan cross-site script.</p>\n<p>Dalam versi lama Django, berhati-hatilah ketika menggunakan penyaring pasang-tetap Django sebagai <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> nilai awal ke <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>. Anda akan butuh melewatkan <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape=True</span></code> untuk mendapatkan pelolosan otomatis.</p>\n<p>Sebagai contoh, jika anda ingin menulis penyesuaian penyaring dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">urlize_and_linebreaks</span></code> yang menggabungkan penyaring <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatefilter-urlize\"><code class=\"xref std std-tfilter docutils literal notranslate\"><span class=\"pre\">urlize</span></code></a> dan <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatefilter-linebreaksbr\"><code class=\"xref std std-tfilter docutils literal notranslate\"><span class=\"pre\">linebreaksbr</span></code></a>, penyaring akan kelihatan seperti:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.defaultfilters</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">linebreaksbr</span><span class=\"p\">,</span> <span class=\"n\">urlize</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">needs_autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">urlize_and_linebreaks</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">linebreaksbr</span><span class=\"p\">(</span>\n        <span class=\"n\">urlize</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">autoescape</span><span class=\"p\">),</span>\n        <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">autoescape</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p>Kemudian:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">comment</span><span class=\"o\">|</span><span class=\"nf\">urlize_and_linebreaks</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>akan setara dengan:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">comment</span><span class=\"o\">|</span><span class=\"nf\">urlize</span><span class=\"o\">|</span><span class=\"nf\">linebreaksbr</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n</aside>\n</section>\n<section id=\"filters-and-time-zones\">\n<span id=\"filters-timezones\"></span><h3>Saringan dan zona waktu<a class=\"heading-anchor\" href=\"#filters-and-time-zones\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Jika anda menulis sebuah penyesuaian penyaring yang dijalankan pada obyek <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.datetime\" title=\"(di Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">datetime</span></code></a>, anda akan biasanya mendaftarkannya dengan bendera <code class=\"docutils literal notranslate\"><span class=\"pre\">expects_localtime</span></code> disetel ke <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">expects_localtime</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">businesshours</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"mi\">9</span> <span class=\"o\">&lt;=</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">hour</span> <span class=\"o\">&lt;</span> <span class=\"mi\">17</span>\n    <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>Ketika bendera ini disetel, jika argumen pertama pada penyaring anda adalah zona waktu perhatikan datetime, Django akan merubahnya ke zona waktu saat ini sebelum melewatkannya ke penyaring anda ketika sesuai, menurut pada <a class=\"reference internal\" href=\"/id/3.2/topics/i18n/timezones/#time-zones-in-templates\"><span class=\"std std-ref\">aturan untuk perubahan zona waktu dalam cetakan</span></a>.</p>\n</section>\n</section>\n<section id=\"writing-custom-template-tags\">\n<span id=\"howto-writing-custom-template-tags\"></span><h2>Menulis etiket cetakan penyesuaian<a class=\"heading-anchor\" href=\"#writing-custom-template-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Etiket lebih rumit daripada penyaring, karena etiket dapat melakukan apapun. Django menyediakan sejumlah jalan pintas yang membuat penulisan kebanyakan jenis etiket lebih mudah. Pertama kami akan menjelajahi jalan pintas tersebut, kemudian menjelaskan bagaimana menulis sebuah etiket dari goresan untuk kasus-kasus tersebut ketika jalan pintas tidak cukup kuat.</p>\n<section id=\"simple-tags\">\n<span id=\"howto-custom-template-tags-simple-tags\"></span><h3>Etiket sederhana<a class=\"heading-anchor\" href=\"#simple-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.simple_tag\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">simple_tag</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.simple_tag\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Banyak cetakan etiket mengambil sejumlah argumen -- deretan karakter atau cetakan variabel -- dan mengembalikan sebuah hasil setelah melakukan beberapa pengolahan berdasarkan hanya pada masukan argumen dan beberapa informasi luar. Sebagai contoh, sebuah etiket <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> mungkin menerima sebuah bentuk deretan karakter dan mengembalikan waktu sebagai bentuk deretan karakter.</p>\n<p>Untuk meringankan pembuatan dari jenis ini dari etiket, Django menyediakan fungsi pembantu, <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code>. Fungsi ini, yaitu sebuah cara dari <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.Library</span></code>, mengambil sebuah fungsi yang menerima angka apapun dari argumen, membungkusnya dalam fungsi <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code> dan bit-bit yang dibutuhkan lainnya disebutkan diatas dan mendaftarkannya dengan cetakan sistem.</p>\n<p>Fungsi <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> kami dapat jadi ditulis seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_time</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Beberapa hal untuk dicatat tentang fungsi pembantu <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code>:</p>\n<ul class=\"simple\">\n<li><p>Memeriksa angka wajib dari argumen, dll., telah selesai dilakukan oleh waktu fungsi kami dipanggil, jadi kami tidak butuh melakukan itu.</p></li>\n<li><p>Kutipan sekitar argumen (jika ada) telah dihilangkan, jadi kami menerima string polos.</p></li>\n<li><p>Jika argumen adalah cetakan variabel, fungsi kami dilewatkan nilai sast ini dari variabel, bukan variabel itu sendiri.</p></li>\n</ul>\n<p>Tidak seperti peralatan etiket lain, <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code> melewatkan keluarannya melalui <a class=\"reference internal\" href=\"/id/3.2/ref/utils/#django.utils.html.conditional_escape\" title=\"django.utils.html.conditional_escape\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code></a> jika konteks cetakan dalam suasana pelolosan otomatis, untuk memastikan HTML benar dan melindungi anda dari kerentanan XSS.</p>\n<p>Jika tambahan pelolosan tidak diharapkan, anda akan butuh menggunakan <a class=\"reference internal\" href=\"/id/3.2/ref/utils/#django.utils.safestring.mark_safe\" title=\"django.utils.safestring.mark_safe\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code></a> jika anda sepenuhnya yakin bahwa kode anda tidak mengandung kerentanan XSS. Untuk membangun potongan kecil HTML, gunakan <a class=\"reference internal\" href=\"/id/3.2/ref/utils/#django.utils.html.format_html\" title=\"django.utils.html.format_html\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">format_html()</span></code></a> daripada <code class=\"docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code> sangat kuat dianjurkan.</p>\n<p>Jika etiket cetakan anda butuh untuk mengakses konteks saat ini, anda dapat menggunakan argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> ketika mendaftarkan etiket anda:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"n\">takes_context</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_time</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n    <span class=\"n\">timezone</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;timezone&#39;</span><span class=\"p\">]</span>\n    <span class=\"k\">return</span> <span class=\"n\">your_get_current_time_method</span><span class=\"p\">(</span><span class=\"n\">timezone</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Catat bahwa argumen pertama <em>harus</em> dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code>.</p>\n<p>Untuk informasi lebih pada bagaimana pilihan <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> bekerja, lihat bagian pada <a class=\"reference internal\" href=\"#howto-custom-template-tags-inclusion-tags\"><span class=\"std std-ref\">inclusion tags</span></a>.</p>\n<p>Jika anda butuh menamai kembali etiket anda, anda dapat menyediakan nama penyesuaian untuknya:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">x</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;minusone&#39;</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;minustwo&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_function</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span> <span class=\"o\">-</span> <span class=\"mi\">2</span>\n</code></pre></div>\n<p>Fungsi <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code> mungkin menerima angka apapun dari argumen terkait atau kata kunci. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_tag</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">warning</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;warning&#39;</span><span class=\"p\">]</span>\n    <span class=\"n\">profile</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;profile&#39;</span><span class=\"p\">]</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">return</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Kemudian dalam cetakan angka apapun dari argumen, dipisahkan oleh spasi, mungkin dilewatkan ke cetakan etiket. Seperti dalam Python, nilai untuk argumen katakunci disetel menggunakan tanda sama dengan (&quot;<code class=\"docutils literal notranslate\"><span class=\"pre\">=</span></code>&quot;) dan harus disediakan setelah penempatan argumen. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">my_tag</span> <span class=\"m\">123</span> <span class=\"s2\">&quot;abcd&quot;</span> <span class=\"nv\">book.title</span> <span class=\"nv\">warning</span><span class=\"o\">=</span><span class=\"nv\">message</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"nv\">profile</span><span class=\"o\">=</span><span class=\"nv\">user.profile</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Itu dimungkinkan untuk menyimpan hasil etiket dalam sebuah cetakan variabel daripada secara langsung mengeluarkannya. Ini dilakukan dengan menggunakan argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">as</span></code> diikuti oleh nama variabel. Melakukannya mengadakan anda untuk mengeluarkan isi diri anda dimana anda melihatnya cocok:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"k\">as</span> <span class=\"nv\">the_time</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{{</span> <span class=\"nv\">the_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"inclusion-tags\">\n<span id=\"howto-custom-template-tags-inclusion-tags\"></span><h3>Penyertaaan etiket<a class=\"heading-anchor\" href=\"#inclusion-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.inclusion_tag\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">inclusion_tag</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.inclusion_tag\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Jenis umum lainnya dari cetakan etiket adalah jenis yang menampilkan beberapa data dengan membangun cetakan <em>lain</em>. Sebagai contoh, antarmuka admin Django menggunakan penyesuaian etiket cetakan untuk menampilkan tombol dibawah dari halaman formulir &quot;add/change&quot;. Tombol-tombol tersebut selalu terlihat sama, tetapi ssaran tautan berubah tergantung pada obyek yang sedang disunting -- sehingga mereka kasus sempurna untuk menggunakan cetakan kecil yang diisi dengan rincian dari obyek saat ini. (Dalam kasus admin, ini adalah etiket <code class=\"docutils literal notranslate\"><span class=\"pre\">submit_row</span></code>.)</p>\n<p>Urutan etiket ini dipanggil &quot;penyertaan etiket&quot;.</p>\n<p>Menulis pencatuman etiket adalah mungkin pertunjukan terbaik dengan contoh. Mari kita menulis sebuah etiket yang mengeluarkan daftar pilihan untuk obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Poll</span></code> yang diberikan, seperti dibuat dalam <a class=\"reference internal\" href=\"/id/3.2/intro/tutorial02/#creating-models\"><span class=\"std std-ref\">tutorial</span></a>. Kami akan menggunakan etiket seperti ini:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">show_results</span> <span class=\"nv\">poll</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>...dan keluaran akan kelihatan seperti ini:</p>\n<div class=\"code-block\" data-language=\"html\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Html code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>First choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Second choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Third choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Pertama, tentukan fungsi yang mengambil argumen dan menghasulkan kamus dari data untuk hasil. Titik terpenting disini adalah kami hanya butuh mengembalikan sebuah kamus, bukan apapun lebih rumit. Ini akan digunakan sebagai konteks cetakan untuk fragmen cetakan. Contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">show_results</span><span class=\"p\">(</span><span class=\"n\">poll</span><span class=\"p\">):</span>\n    <span class=\"n\">choices</span> <span class=\"o\">=</span> <span class=\"n\">poll</span><span class=\"o\">.</span><span class=\"n\">choice_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"s1\">&#39;choices&#39;</span><span class=\"p\">:</span> <span class=\"n\">choices</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>Next, create the template used to render the tag's output. This template is a\nfixed feature of the tag: the tag writer specifies it, not the template\ndesigner. Following our example, the template is very short:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">choice</span> <span class=\"k\">in</span> <span class=\"nv\">choices</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span> <span class=\"cp\">{{</span> <span class=\"nv\">choice</span> <span class=\"cp\">}}</span> <span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Sekarang, buat dan daftar penyertaan etiket dengan memanggil cara <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag()</span></code> pada sebuah obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Library</span></code>. Mengikuti contoh kami, jika cetakan diatas dalam sebuah berkas dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">results.html</span></code> dalam sebuah direktori yang dicari oleh pemuat cetakan, kami akan mendaftar etiket seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># Here, register is a django.template.Library instance, as before</span>\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;results.html&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">show_results</span><span class=\"p\">(</span><span class=\"n\">poll</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Kemungkinan lain dia memungkinkan mendaftarkan pemasukan etiket menggunakan instace <a class=\"reference internal\" href=\"/id/3.2/ref/templates/api/#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.template.Template</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.loader</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_template</span>\n<span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;results.html&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">)(</span><span class=\"n\">show_results</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>...ketika pertama membuat fungsi.</p>\n<p>Terkadang, penyertaan etiket anda mungkin membutuhkan sejumlah besar argumen, membuatnya sakit untuk cetakan penulis melewatkan semua argumen dan mengingat urutan mereka. Untuk mengatasi ini, Django menyediakan sebuah pilihan <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> untuk penyertaan etiket. Jika anda menentukan <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> dalam sebuah cetakan etiket, etiket tidak akan mempunyai argumen wajib, dan pokok fungsi Python akan mempunyai satu argumen -- konteks cetakan mulai ketika etiket dipanggil.</p>\n<p>Sebagai contoh, katakan anda sedang menulis sebuah penyertaan etiket yang akan selalu digunakan dalam sebuah konteks yang mengandung variabel <code class=\"docutils literal notranslate\"><span class=\"pre\">home_link</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">home_title</span></code> yang menunjuk kembali ke halaman utama. Disini fungsi Python akan kelihatan seperti:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;link.html&#39;</span><span class=\"p\">,</span> <span class=\"n\">takes_context</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">jump_link</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;link&#39;</span><span class=\"p\">:</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;home_link&#39;</span><span class=\"p\">],</span>\n        <span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;home_title&#39;</span><span class=\"p\">],</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>Catat bahwa parameter pertama pada fungsi <em>harus</em> dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code>.</p>\n<p>Dalam baris <code class=\"docutils literal notranslate\"><span class=\"pre\">register.inclusion_tag()</span></code> itu, kami mencirikan <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context=True</span></code> dan nama dari cetakan. Ini adalah cetakan <code class=\"docutils literal notranslate\"><span class=\"pre\">link.html</span></code> mungkin kelihatan seperti:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code>Jump directly to <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">link</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">title</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>.\n</code></pre></div>\n<p>Lalu, kapanpun anda ingin menggunakan tag tersuai, muat pustakanya dan panggil tanpa argument, seperti:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">jump_link</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Catat bahwa ketika anda menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context=True</span></code>, tidak perlu melewatkan argumen ke etiket cetakan. Dia otomatis mendapatkan akses ke konteks.</p>\n<p>Parameter <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> awalnya adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>. Ketika disetel ke <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, etiket melewatkan obyek konteks, seperti dalam contoh ini. Itu hanya oerbedaan diantara kasus ini dan contoh <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag</span></code> sebelumnya.</p>\n<p>Fungsi <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag</span></code> mungkin menerima angka apapun dari penempatan atau argumen kata kunci. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_template.html&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_tag</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">warning</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;warning&#39;</span><span class=\"p\">]</span>\n    <span class=\"n\">profile</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;profile&#39;</span><span class=\"p\">]</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">return</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Kemudian dalam cetakan angka apapun dari argumen, dipisahkan oleh spasi, mungkin dilewatkan ke cetakan etiket. Seperti dalam Python, nilai untuk argumen katakunci disetel menggunakan tanda sama dengan (&quot;<code class=\"docutils literal notranslate\"><span class=\"pre\">=</span></code>&quot;) dan harus disediakan setelah penempatan argumen. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">my_tag</span> <span class=\"m\">123</span> <span class=\"s2\">&quot;abcd&quot;</span> <span class=\"nv\">book.title</span> <span class=\"nv\">warning</span><span class=\"o\">=</span><span class=\"nv\">message</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"nv\">profile</span><span class=\"o\">=</span><span class=\"nv\">user.profile</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n</section>\n<section id=\"advanced-custom-template-tags\">\n<h3>Etiket cetakan penyesuaian tingkat lanjut<a class=\"heading-anchor\" href=\"#advanced-custom-template-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Terkadang fitur dasar untuk pembuatan etiket cetakan penyesuaian tidak cukup. Jangan khawatir, Django memberikan anda akses lengkap ke internal yang diwajibkan untuk membangun sebuah etiket cetakan dari bawah ke atas.</p>\n</section>\n<section id=\"a-quick-overview\">\n<h3>Ikhtisar cepat<a class=\"heading-anchor\" href=\"#a-quick-overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Sistem cetakan bekerja dalam dua langkah pengolahan: menyusun dan membangun. Untuk menentukan etiket cetakan penyesuaian, anda menentukan bagaimana penyusunan bekerja dan bagaimana pembangunan bekerja.</p>\n<p>When Django compiles a template, it splits the raw template text into\n''nodes''. Each node is an instance of <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.Node</span></code> and has\na <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> method. A compiled template is a list of <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> objects. When\nyou call <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> on a compiled template object, the template calls\n<code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> on each <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> in its node list, with the given context.  The\nresults are all concatenated together to form the output of the template.</p>\n<p>Jadi, untuk menentukan penyesuaian cetakan etiket, anda menentukan bagaimana cetakan etiket mentah dirubah kedalam <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> (fungsi penyusunan), dan apa cara <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> node lakukan.</p>\n</section>\n<section id=\"writing-the-compilation-function\">\n<h3>Menulis fungsi himpunan<a class=\"heading-anchor\" href=\"#writing-the-compilation-function\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Untuk setiap etiket cetakan pertemuan pengurai cetakan, dia memanggil fungsi Python dengan isi etiket dan pengurai obyek itu sendiri. Fungsi ini bertanggung jawab untuk mengembalikan sebuah contoh <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> berdasarkan pada isi dari etiket.</p>\n<p>For example, let's write a full implementation of our template tag,\n<code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">current_time</span> <span class=\"pre\">%}</span></code>, that displays the current date/time, formatted according\nto a parameter given in the tag, in <a class=\"reference external\" href=\"https://docs.python.org/3/library/time.html#time.strftime\" title=\"(di Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">strftime()</span></code></a> syntax. It's a good\nidea to decide the tag syntax before anything else. In our case, let's say the\ntag should be used like this:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Pengurai untuk fungsi ini harus mengambil parameter dan membuat obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># split_contents() knows not to split quoted strings.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">split_contents</span><span class=\"p\">()</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires a single argument&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">CurrentTimeNode</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Catatan:</p>\n<ul class=\"simple\">\n<li><p>parser` adalah obyek pengurai cetakan. Kami tidak membutuhkannya dalam contoh ini.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents</span></code> adalah deretan karakter dari isi mentah dari etiket. Dalam contoh kami, dia adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">'current_time</span> <span class=\"pre\">&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;'</span></code>.</p></li>\n<li><p>Cara <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code> memisahkan argumen pada ruang selama menjaga deretan karakter dikutip bersama. Lebih mudah <code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents.split()</span></code> tidak akan menjadi kuat, karena akan naif pisah pada <em>semua</em> ruang, termasuk itu dalam deretan karakter dikutip. Adalah ide bagus untuk selalu menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code>.</p></li>\n<li><p>Fungsi ini bertanggungjawab untuk memunculkan <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.TemplateSyntaxError</span></code>, dengan pesan membantu, untuk sintakses kesalahan apapun.</p></li>\n<li><p>Pengecualian <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateSyntaxError</span></code> menggunakan variabel <code class=\"docutils literal notranslate\"><span class=\"pre\">tag_name</span></code>. Jangan mengkode keraskan nama etiket dalam pesan-pesan kesalahan anda, karena itu memasangkan nama etiket ke fungsi anda. <code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents.split()[0]</span></code> akan ''selalu'' menjadi nama dari etiket anda -- bahkan ketika etiket tidak mempunyai argumen.</p></li>\n<li><p>The function returns a <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code> with everything the node needs\nto know about this tag. In this case, it passes the argument --\n<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;</span></code>. The leading and trailing quotes from the\ntemplate tag are removed in <code class=\"docutils literal notranslate\"><span class=\"pre\">format_string[1:-1]</span></code>.</p></li>\n<li><p>Penguraian adalah tingkat-rendah. Pengembang Django mempunyai percobaan dengan menulis kerangka kecil diatas dari sistem penyurai ini, menggunakan teknik seperti tata bahasa EBNF, tetapi percobaan tersebut membuat cetakan mesin terlalu lambat. Dia adalah tingkat-rendah karena itu tercepat.</p></li>\n</ul>\n</section>\n<section id=\"writing-the-renderer\">\n<h3>Menulis pembangun<a class=\"heading-anchor\" href=\"#writing-the-renderer\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Langkah kedua dalam menulis penyesuaian etiket adalah menentukan sebuah subkelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> yang mempunyai cara <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code>.</p>\n<p>Melanjutkan contoh diatas, kami butuh menentukan <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Catatan:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> mendapatkan <code class=\"docutils literal notranslate\"><span class=\"pre\">format_string</span></code> dari <code class=\"docutils literal notranslate\"><span class=\"pre\">do_current_time()</span></code>. Selalu melewati options/parameters/arguments apapun ke <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> melalui <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> nya.</p></li>\n<li><p>Cara <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> adalah dimana pekerjaan sebenarnya terjadi.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> harus pada umumnya gagal secara diam, khususnya dalam lingkungan produksi. Dalam beberapa kasus bagaimanapun, khususnya jika <code class=\"docutils literal notranslate\"><span class=\"pre\">context.template.engine.debug</span></code> adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, cara ini mungkin memunculkan sebuah pengecualian untuk membuat mencari kesalahan lebih mudah. Sebagai contoh, beberapa etiket inti memunculkan <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.TemplateSyntaxError</span></code> jika mereka menerima nomor atau jenis salah dari argumen</p></li>\n</ul>\n<p>Akhirnya, pemisahan ini dari hasil penyusunan dan pembangunan dalam sebuah sistem cetakan efesien, karena sebuah cetakan dapat membangun banyak konteks tanpa harus diuraikan banyak kali.</p>\n</section>\n<section id=\"auto-escaping-considerations\">\n<span id=\"tags-auto-escaping\"></span><h3>Pertimbangan pelolosan otomatis<a class=\"heading-anchor\" href=\"#auto-escaping-considerations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Keluaran dari cetakan etiket <em>tidak*</em> otomatis berjalan melalui penyaring pelolosan otomatis (dengan pencegualian dari <a class=\"reference internal\" href=\"#django.template.Library.simple_tag\" title=\"django.template.Library.simple_tag\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">simple_tag()</span></code></a> seperti yang digambarkan diatas). Bagaimanapun, masih terdapat sepasang hal anda harus ingat ketika menulis sebuah cetakan etiket.</p>\n<p>If the <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> method of your template tag stores the result in a context\nvariable (rather than returning the result in a string), it should take care\nto call <code class=\"docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code> if appropriate. When the variable is ultimately\nrendered, it will be affected by the auto-escape setting in effect at the\ntime, so content that should be safe from further escaping needs to be marked\nas such.</p>\n<p>Juga, jika cetakan etiket anda membuat konteks baru untuk melakukan beberapa sub pembangunan, setel atribut pelolosan otomatis ke nilai konteks saat ini. Cara <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> untuk kelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> mengambil parameter dipanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> dimana anda dapat menggunakan untuk tujuan ini. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Context</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"n\">new_context</span> <span class=\"o\">=</span> <span class=\"n\">Context</span><span class=\"p\">({</span><span class=\"s1\">&#39;var&#39;</span><span class=\"p\">:</span> <span class=\"n\">obj</span><span class=\"p\">},</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">autoescape</span><span class=\"p\">)</span>\n    <span class=\"c1\"># ... Do something with new_context ...</span>\n</code></pre></div>\n<p>Ini bukan situasi paling umum, tetapi ini berguna jika anda membangun cetakan anda sendiri. Sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">engine</span><span class=\"o\">.</span><span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;small_fragment.html&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">t</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">Context</span><span class=\"p\">({</span><span class=\"s1\">&#39;var&#39;</span><span class=\"p\">:</span> <span class=\"n\">obj</span><span class=\"p\">},</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">autoescape</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Jika kami mempunyai terlantar untuk dilewatkan dalam nilai <code class=\"docutils literal notranslate\"><span class=\"pre\">context.autoescape</span></code> saat ini ke <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> baru kami dalam contoh ini, hasil akan mempunyai <em>selalu</em> otomatis diloloskan, yang mungkin perilaku yang tidak diinginkan jika cetakan etiket digunakan dalam sebuah blok <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-autoescape\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">autoescape</span> <span class=\"pre\">off</span> <span class=\"pre\">%}</span></code></a>.</p>\n</section>\n<section id=\"thread-safety-considerations\">\n<span id=\"template-tag-thread-safety\"></span><h3>Pertimbangan Thread-safety<a class=\"heading-anchor\" href=\"#thread-safety-considerations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Sekali node diuraikan, cara <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code> dia mungkin dipanggil sejumlah kali. Sejak Django terkadang berjalan dalam lingkungan banyak-rangkaian, sebuah node tunggal mungkin secara berkelanjutan membangun dengan konteks berbeda dalam menjawab ke dua permintaan terpisah. Oleh sebab itu, sangat penting untuk memastikan cetakan etiket anda adalah aman.</p>\n<p>Untuk memastikan cetakan etiket anda thread safe, anda harus jangan menyimpan informasi keadaan pada node itu sendiri. Sebagai contoh, Django menyediakan cetakan etiket <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">cycle</span></code></a> siap pakai yang berputar terhadap sebuah daftar dari deretan karakter yang diberikan setiap kali dia dibangun:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">o</span> <span class=\"k\">in</span> <span class=\"nv\">some_list</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">tr</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">cycle</span> <span class=\"s1\">&#39;row1&#39;</span> <span class=\"s1\">&#39;row2&#39;</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>\n        ...\n    <span class=\"p\">&lt;/</span><span class=\"nt\">tr</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Sebuah penerapan yang dibuat-buat dari <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> mungkin kelihatan kurang lebih seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">itertools</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CycleNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">cyclevars</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cycle_iter</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">cycle</span><span class=\"p\">(</span><span class=\"n\">cyclevars</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">next</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cycle_iter</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Tetapi, seandainya kami mempunyai dua cetakan membangun potongan cetakan dari atas pada waktu bersamaan:</p>\n<ol class=\"arabic simple\">\n<li><p>Urutan 1 melakukan pengulangan pertamanya, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> mengembalikan 'row1'</p></li>\n<li><p>Urutan 2 melakukan pengulangan pertamanya, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> mengembalikan 'row2'</p></li>\n<li><p>Urutan 1 melakukan pengulangan keduanya, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> mengembalikan 'row1'</p></li>\n<li><p>Urutan 2 melakukan pengulangan keduanya, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> mengembalikan 'row2'</p></li>\n</ol>\n<p>The CycleNode is iterating, but it's iterating globally. As far as Thread 1\nand Thread 2 are concerned, it's always returning the same value. This is\nnot what we want!</p>\n<p>Untuk mengalamatkan masalah ini, Django menyediakan sebuah <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code> yang terhubung dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> dari cetakan yang saat ini sedang dibangun. <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code> berperilaku seperti sebuah kamus Python, dan harus digunakan untuk menyimpan keadaan <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> diantara permohonan dari cara <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code>.</p>\n<p>Mari kita refactor penerapan <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> kami untuk menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CycleNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">cyclevars</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cyclevars</span> <span class=\"o\">=</span> <span class=\"n\">cyclevars</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">:</span>\n            <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">cycle</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cyclevars</span><span class=\"p\">)</span>\n        <span class=\"n\">cycle_iter</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> <span class=\"nb\">next</span><span class=\"p\">(</span><span class=\"n\">cycle_iter</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Catat bahwa ini sangat aman untuk menyimpan informasi umum yang tidak akan merubah keseluruhan hidup dari <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> sebagai sebuah atribut. Dalam kasus <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code>, argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">cyclevars</span></code> tidak berubah setelah <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> dipakai, jadi kami tidak butuh menaruhnya ke dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Tetapi keadaan informasi yang khusus pada cetakan yang saat ini sedang dibangun, seperti putaran saat ini dari <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code>, harus disimpan dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Catatan</p>\n<p>Perhatikan bagaimana kami menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> untuk menjangkau <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> informasi tertentu dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Disana mungkin banyak <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNodes</span></code> dalam cetakan yang diberikan, jadi kami butuh berhati-hati tidak megnkritik informasi keadaan node lainnya. Cara termudah melakukan ini adalah selalu menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> sebagai kunci kedalam <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Jika anda sedang menjaga jalur dari beberapa variabel keadaan, buat <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context[self]</span></code> sebuah kamus.</p>\n</aside>\n</section>\n<section id=\"registering-the-tag\">\n<h3>Mendaftarkan etiket<a class=\"heading-anchor\" href=\"#registering-the-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Akhirnya, daftar etiket dengan instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Library</span></code> modul anda, seperti dijelaskan dalam <a class=\"reference internal\" href=\"#howto-writing-custom-template-tags\"><span class=\"std std-ref\">writing custom template tags</span></a> diatas. Contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;current_time&#39;</span><span class=\"p\">,</span> <span class=\"n\">do_current_time</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cara <code class=\"docutils literal notranslate\"><span class=\"pre\">tag()</span></code> mengambil dua argumen:</p>\n<ol class=\"arabic simple\">\n<li><p>Nama dari cetakan etiket -- sebuah deretan karakter. Jika ini dihilangkan dari fungsi penyusunan akan digunakan.</p></li>\n<li><p>Fungsi himpunan -- Sebuah fungsi Python (bukan nama fungsi sebagai deretan karakter).</p></li>\n</ol>\n<p>Dengan pendaftaran penyaring, dia juga memungkinkan menggunakan ini sebagai decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">tag</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;current_time&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">shout</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Jika anda meninggalkan argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code>, seperti dalam contoh kedud diatas, Django akan menggunakan nama fungsi sebagai nama etiket.</p>\n</section>\n<section id=\"passing-template-variables-to-the-tag\">\n<h3>Melewatkan variabel cetakan ke etiket<a class=\"heading-anchor\" href=\"#passing-template-variables-to-the-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Meskipun anda dapat melewatkan angka apapun dari argumen ke etiket cetakan menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code>, argumen semua tidak dipaketkan sebagai harfiah string. Sedikit kerja lebih diwajibkan untuk melewatkan isi dinamis (variabel cetakan) ke etiket cetakan sebagai sebuah argumen.</p>\n<p>Selagi contoh sebelumnya telah membentuk waktu saat ini ke dalam string dan mengembalikan string, misalkan anda ingin melewatkan di <a class=\"reference internal\" href=\"/id/3.2/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateTimeField</span></code></a> dari sebuah obyek dan mempunyai bentuk etiket cetakan yang tanggal-waktu:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>This post was last updated at <span class=\"cp\">{%</span> <span class=\"k\">format_time</span> <span class=\"nv\">blog_entry.date_updated</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Mulanya, <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code> akan mengembalikan tiga nilai:</p>\n<ol class=\"arabic simple\">\n<li><p>Nama etiket <code class=\"docutils literal notranslate\"><span class=\"pre\">format_time</span></code>.</p></li>\n<li><p>String <code class=\"docutils literal notranslate\"><span class=\"pre\">'blog_entry.date_updated'</span></code> (tanpa dikelilingi kutip).</p></li>\n<li><p>Pembentukan deretan karakter <code class=\"docutils literal notranslate\"><span class=\"pre\">'&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;'</span></code>. Mengembalikan nilai dari <code class=\"docutils literal notranslate\"><span class=\"pre\">split_contents()</span></code> akan menyertakan kutipan awal dan akhir untuk deretan karakter persis seperti ini.</p></li>\n</ol>\n<p>Sekarang etiket anda harus kelihatan seperti ini:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_format_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># split_contents() knows not to split quoted strings.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">split_contents</span><span class=\"p\">()</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires exactly two arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">FormatTimeNode</span><span class=\"p\">(</span><span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Anda juga mempunyai kesemparan pembangun untuk mengambil isi sebenarnya dari sifat <code class=\"docutils literal notranslate\"><span class=\"pre\">date_updated</span></code> dari obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">blog_entry</span></code>. Ini dapat diselesaikan dengan menggunakan kelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Variable()</span></code> dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template</span></code>.</p>\n<p>Untuk menggunakan kelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Variable</span></code>, instansiasikan itu dengan nama dari variabel untuk diselesaikan, dan panggil <code class=\"docutils literal notranslate\"><span class=\"pre\">variable.resolve(context)</span></code>. Jadi, sebagai contoh:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">FormatTimeNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">date_to_be_formatted</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">date_to_be_formatted</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"n\">actual_date</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">date_to_be_formatted</span><span class=\"o\">.</span><span class=\"n\">resolve</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n            <span class=\"k\">return</span> <span class=\"n\">actual_date</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">VariableDoesNotExist</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>Keputusan variabel akan melempar sebuah pengecualian <code class=\"docutils literal notranslate\"><span class=\"pre\">VariableDoesNotExist</span></code> jika dia tidak dapat menyelesaikan deretan karakter dilewatkan ke dia dalam konteks saat ini dari halaman.</p>\n</section>\n<section id=\"setting-a-variable-in-the-context\">\n<h3>Menyetel sebuah variabel di konteks<a class=\"heading-anchor\" href=\"#setting-a-variable-in-the-context\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Contoh diatas mengengeluarkan nilai. Umumnya, itu lebih fleksibel jika etiket cetakan anda mensetel variabel cetakan daripada mengeluarkan nilai. Cara itu, penulis cetakan dapat menggunakan kembali nilai yang etiket cetakan anda buat.</p>\n<p>To set a variable in the context, use dictionary assignment on the context\nobject in the <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> method. Here's an updated version of\n<code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code> that sets a template variable <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> instead of\noutputting it:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode2</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;current_time&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>Catat bahwa <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> mengembalikan deretan karakter kosong. <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span> <span class=\"pre\">harus</span> <span class=\"pre\">selalu</span> <span class=\"pre\">mengembalikan</span> <span class=\"pre\">keluaran</span> <span class=\"pre\">deretan</span> <span class=\"pre\">karakter.</span> <span class=\"pre\">Jika</span> <span class=\"pre\">semua</span> <span class=\"pre\">cetakan</span> <span class=\"pre\">etiket</span> <span class=\"pre\">disetel</span> <span class=\"pre\">variabel,</span> <span class=\"pre\">``render()</span></code> harus mengembalikan deretan karakter kosong.</p>\n<p>Ini adalah bagaimana anda akan menggunakan versi baru dari etiket:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{{</span> <span class=\"nv\">current_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-variable-scope-in-context admonition\">\n<p class=\"admonition-title\">Lingkup variabel di konteks</p>\n<p>Apapun kumpulan variabel dalam konteks akan hanya tersedua dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">block</span></code> yang sama dari cetakan dimana dia ditetapkan. Perilaku ini adalah disengaja; dia menyediakan cakupan untuk variabel sehingga mereka tidak bertentangan dengan konteks di blok lainnya.</p>\n</aside>\n<p>Tetapi, ada masalah dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode2</span></code>: Nama variabel <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> adalah dikode keraskan. Ini berarti anda akan butuh untuk memastikan cetakan anda tidak menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">current_time</span> <span class=\"pre\">}}</span></code> dimanapun juga, karena <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">current_time</span> <span class=\"pre\">%}</span></code> akan membabi buta meniban nilai variabel itu. Sebuah solusi pembersih adalah membuat cetakan etiket menentukan nama dari variabel keluaran, seperti begitu:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"k\">as</span> <span class=\"nv\">my_current_time</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The current time is <span class=\"cp\">{{</span> <span class=\"nv\">my_current_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Untuk melakukannya, anda akan butuh me refaktor kedua fungsi penyusun dan kelas <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>, seperti begitu:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">re</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode3</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">,</span> <span class=\"n\">var_name</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">var_name</span> <span class=\"o\">=</span> <span class=\"n\">var_name</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">var_name</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This version uses a regular expression to parse tag contents.</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Splitting by None == splitting by spaces.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">arg</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">search</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;(.*?) as (\\w+)&#39;</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">m</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag had invalid arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span><span class=\"p\">)</span>\n    <span class=\"n\">format_string</span><span class=\"p\">,</span> <span class=\"n\">var_name</span> <span class=\"o\">=</span> <span class=\"n\">m</span><span class=\"o\">.</span><span class=\"n\">groups</span><span class=\"p\">()</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">CurrentTimeNode3</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">var_name</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Perbedaan disini adalah bahwa <code class=\"docutils literal notranslate\"><span class=\"pre\">do_current_time()</span></code> mengambil bentuk deretan karakter dan nama variabel, melewatkan keduanya ke <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode3</span></code>.</p>\n<p>Akhirnya, jika anda hanya butuh mempunyai sintaksis sederhana untuk penyesuaian pembaharuan-konteks cetakan etiket, pertimbangkan menggunakan jalan pintas <a class=\"reference internal\" href=\"#django.template.Library.simple_tag\" title=\"django.template.Library.simple_tag\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">simple_tag()</span></code></a>, yang mendukung menetapkan hasil etiket ke cetakan variabel.</p>\n</section>\n<section id=\"parsing-until-another-block-tag\">\n<h3>Menguraikan sampai blok etiket lain<a class=\"heading-anchor\" href=\"#parsing-until-another-block-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Cetakan etiket dapat bekerja dalam berduaan. Sebagai contoh, standar etiket <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-comment\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code></a> menyembunyikan semua sampai <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>. Untuk membuat sebuah cetakan etiket seperti ini, gunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> dalam fungsi penyusun anda</p>\n<p>Ini adalah bagaimana menyederhanakan etiket <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> mungkin diterapkan:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_comment</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">parse</span><span class=\"p\">((</span><span class=\"s1\">&#39;endcomment&#39;</span><span class=\"p\">,))</span>\n    <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">delete_first_token</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">CommentNode</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CommentNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Catatan</p>\n<p>Penerapan sebenarnya dari <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-comment\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code></a> adalah sedikit berbeda dalam memungkinkan merusak cetakan etiket untuk muncul diantara <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>. Dia melakukannya dengan memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.skip_past('endcomment')</span></code> daripada <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse(('endcomment',))</span></code> diikuti oleh <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.delete_first_token()</span></code>, jadi menghindari generasi dari sebuah daftar node.</p>\n</aside>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> mengambil sebuah tuple dari nama dari blok etiket &quot;untuk diurai sampai&quot;. Dia mengembalikan sebuah contoh dari <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.NodeList</span></code>, yaitu sebuah daftar dari semua obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> yang pengurai jumpai &quot;sebelum&quot; dia menjumpai etiket dinamai apapun dalam tuple.</p>\n<p>Dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;nodelist</span> <span class=\"pre\">=</span> <span class=\"pre\">parser.parse(('endcomment',))&quot;</span></code> di contoh atas, <code class=\"docutils literal notranslate\"><span class=\"pre\">nodelist</span></code> adalah sebuah daftar dari semua node diantara <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>, bukan menghitung <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code> mereka sendiri.</p>\n<p>Setelah <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> dipanggil, pengurai belum &quot;mengkonsumsi&quot; etiket <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>, jadi kode butuh  secara eksplisit memanggil <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.delete_first_token()</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">CommentNode.render()</span></code> mengembalikan string kosong. Apapun diantara <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code> diabaikan.</p>\n</section>\n<section id=\"parsing-until-another-block-tag-and-saving-contents\">\n<h3>Mengurai sampai blok etiket lainnya, dan menyimpan isi<a class=\"heading-anchor\" href=\"#parsing-until-another-block-tag-and-saving-contents\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Di contoh sebelumnya, <code class=\"docutils literal notranslate\"><span class=\"pre\">do_comment()</span></code> menyingkirkan apapun diantara <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>. Daripada melakukan itu, dimungkinkan untuk melakukan sesuatu dengan kode diantara blok etiket.</p>\n<p>Sebagai contoh, ini adalah penyesuaian cetakan etiket, <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">upper</span> <span class=\"pre\">%}</span></code>, yang menghuruf besarkan semuanya diantara dia sendiri dan <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endupper</span> <span class=\"pre\">%}</span></code>.</p>\n<p>Penggunaan:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">upper</span> <span class=\"cp\">%}</span>This will appear in uppercase, <span class=\"cp\">{{</span> <span class=\"nv\">your_name</span> <span class=\"cp\">}}</span>.<span class=\"cp\">{%</span> <span class=\"k\">endupper</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Seperti di contoh sebelumnya, kami akan menggunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code>. Tetapi kali ini, kami melewatkan hasil <code class=\"docutils literal notranslate\"><span class=\"pre\">nodelist</span></code> ke <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_upper</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">parse</span><span class=\"p\">((</span><span class=\"s1\">&#39;endupper&#39;</span><span class=\"p\">,))</span>\n    <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">delete_first_token</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">UpperNode</span><span class=\"p\">(</span><span class=\"n\">nodelist</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UpperNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">nodelist</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">nodelist</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nodelist</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">output</span><span class=\"o\">.</span><span class=\"n\">upper</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Satu-satunya konsep disini adalah <code class=\"docutils literal notranslate\"><span class=\"pre\">self.nodelist.render(context)</span></code> dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">UpperNode.render()</span></code>.</p>\n<p>Untuk lebih contoh dari pembangunan rumit, lihat kode sumber dari <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">%}</span></code></a> dalam <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/defaulttags.py</span></code> dan <a class=\"reference internal\" href=\"/id/3.2/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">if</span> <span class=\"pre\">%}</span></code></a> di <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/smartif.py</span></code>.</p>\n</section>\n</section>","rootId":"custom-template-tags-and-filters","toc":[{"title":"Tata letak kode","anchor":"code-layout","children":[]},{"title":"Menulis saringan cetakan penyesuaian","anchor":"writing-custom-template-filters","children":[{"title":"Mendaftarkan saringan penyesuaian","anchor":"registering-custom-filters","children":[]},{"title":"Cetakan penyaring yang mengharapkan deretan karakter","anchor":"template-filters-that-expect-strings","children":[]},{"title":"Penyaring dan pelolosan otomatis","anchor":"filters-and-auto-escaping","children":[]},{"title":"Saringan dan zona waktu","anchor":"filters-and-time-zones","children":[]}]},{"title":"Menulis etiket cetakan penyesuaian","anchor":"writing-custom-template-tags","children":[{"title":"Etiket sederhana","anchor":"simple-tags","children":[]},{"title":"Penyertaaan etiket","anchor":"inclusion-tags","children":[]},{"title":"Etiket cetakan penyesuaian tingkat lanjut","anchor":"advanced-custom-template-tags","children":[]},{"title":"Ikhtisar cepat","anchor":"a-quick-overview","children":[]},{"title":"Menulis fungsi himpunan","anchor":"writing-the-compilation-function","children":[]},{"title":"Menulis pembangun","anchor":"writing-the-renderer","children":[]},{"title":"Pertimbangan pelolosan otomatis","anchor":"auto-escaping-considerations","children":[]},{"title":"Pertimbangan Thread-safety","anchor":"thread-safety-considerations","children":[]},{"title":"Mendaftarkan etiket","anchor":"registering-the-tag","children":[]},{"title":"Melewatkan variabel cetakan ke etiket","anchor":"passing-template-variables-to-the-tag","children":[]},{"title":"Menyetel sebuah variabel di konteks","anchor":"setting-a-variable-in-the-context","children":[]},{"title":"Menguraikan sampai blok etiket lain","anchor":"parsing-until-another-block-tag","children":[]},{"title":"Mengurai sampai blok etiket lainnya, dan menyimpan isi","anchor":"parsing-until-another-block-tag-and-saving-contents","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"Panduan \"Bagaimana\"","url":"/id/3.2/howto/"}],"prev":{"docname":"howto/custom-template-backend","title":"Custom template backend","url":"/id/3.2/howto/custom-template-backend/"},"next":{"docname":"howto/custom-file-storage","title":"Menulis sistem penyimpanan disesuaikan","url":"/id/3.2/howto/custom-file-storage/"},"formats":{"html":"/id/3.2/howto/custom-template-tags/","markdown":"/id/3.2/howto/custom-template-tags.md","json":"/id/3.2/howto/custom-template-tags.json"},"source":"https://github.com/django/django/blob/stable/3.2.x/docs/howto/custom-template-tags.txt","official":"https://docs.djangoproject.com/id/3.2/howto/custom-template-tags/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}