Djangoのテンプレートのレンダリング、継承
まず、文法
二つの特殊記号:
{{}}と{%}%
{{}}論理{%}%関連の変数に関連するロジックと変数。
第二に、変数
{{変数名}}:で使用Djangoのテンプレート言語の構文をクリックします
テンプレートエンジンが変数に遭遇すると、変数を計算し、その結果自分自身でそれを置き換えます。名前付き変数は任意の英数字とアンダースコア(「_」)の組み合わせが含まれます。変数名にはスペースや句読点を含めることはできません
urls.py 先配置路径:
url(r'^index/', views.index),
views.py
from django.shortcuts import render,HttpResponse,redirect
def index(request):
num = 100
name = 'alex'
food_list = ['蒸熊掌','烧花鸭','烧子鹅']
dic = {'year':2019,'month':7,'day':17}
class Animal:
def __init__(self):
self.kind = 'dog'
def color(self):
return 'black'
a = Animal()
return render(request,'index.html',{'num':num,'name':name,'food_list':food_list,'dic':dic,'a':a})
# 通过字典的形式传把值给html文件
return render(request,'index.html',locals())
# locals() 获取函数内部所有变量的值,并加工成{'变量名':'变量值'....}这样一个字典
index.html
<p>{{ num }}</p>
<p>{{ name }}</p>
<p>{{ food_list }}</p>
<p>{{ dic }}</p>
<p>{{ a }}</p>
<p>{{ a.kind }}</p>
<p>{{ a.color }}</p>
注意:
- ビュー:このメソッドは、内部機能、簡単な方法のすべての変数の値を取得することができます)(地元の人々程度のため、それを使用することができますが、多くの不要な変数が、非効率に送信され、
- HTMLで:メソッド内のオブジェクトを呼び出すブラケットが実行する書き込みをする必要がない場合、およびこの方法のみが伝送パラメータを必要とする場合、テンプレートの言語がサポートされていないので、パラメータを渡していないメソッドを実行することができ、あなたがレンダリングを助けることができません
第三に、フィルタ
変数の表示を変更するには、フィルタを使用して、Djangoテンプレート言語では。
フィルタの構文:{{値|メソッド名:パラメータ}}パイプを使用し、「|」フィルタを適用した、コロン「:」接続パラメータに
Djangoテンプレート言語は約60ビルトインフィルタを提供します
長さ
获取数据长度,没参数,作用于字符串和列表 {{ value|length }}
<p>{{ food_list|length }}</p>
デフォルト
默认值,有参数,如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值
<p>{{ xx|default:'啥也没有' }}</p> # views若没有传过来xx的值,所以就会显示设置的默认值
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)
# 比如在views中 size = 123456
<p>{{ size|filesizeformat }}</p> # 此时格式转换成 120.6 KB
スライス
切片 ,跟字符串、列表的切片方法一样 {{value|slice:"2:-1"}}
<p>{{ name|slice:':3' }}</p> # 0可省略
日付
时间格式化显示
# 比如在views中 ntime = datetime.datetime.now()
<p>{{ ntime|date }}</p> # July 17, 2019
<p>{{ ntime|date:"Y-m-d H:i:s"}}</p> # 2019-07-17 16:27:55
truncatechars
字符截断 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。 参数:截断的字符数
# 比如在views中 name = 'alexdsb'
<p>{{ name|truncatechars:7 }}</p> # alex...
#注意:最后那三个省略号也是7个字符里面的,也就是这个7截断出来的是4个字符+3个省略号
truncatewords
单词截断 在一定数量的字后截断字符串,是截多少个单词
# 比如在views中 word = 'hello girl hi baby yue ma'
<p>{{ word|truncatewords:4 }}</p> # hello girl hi baby ...
# 单词截断,截的是多少个单词,省略号不算
カット
移除value中所有的与给出的变量相同的字符串
# 比如在views中 word = 'hello girl hi baby yue ma'
<p>{{ words|cut:'i' }}</p> # hello grl h baby yue ma
加わります
使用字符串连接列表,{{ list|join:', ' }},就像Python的str.join(list)
# 比如在views中 food_list = ['蒸熊掌','烧花鸭','烧子鹅']
<p>{{ food_list|join:'+' }}</p> # 蒸熊掌+烧花鸭+烧子鹅
安全
将 字符串识别成标签
私は、ユーザーのコメントでjsのコードを書いた場合は逃れられない場合とき、jsのコードが実行され、ブラウザがポップアップ表示されますというように、これはXSS攻撃と呼ばれています。時間を演出テンプレート中にDjangoのテンプレートは、安全のために、そのような文法やJSタグなどのタグが自動的にエスケープHTMLます。「|安全」Djangoのコードを指示する方法安全な逃避である必要はありません、それは我々がフィルターを通過することができます単一の変数であれば、二つの方法でエスケープは、Djangoの自動HTMLをオフにします。
# 比如在views中 tag = '<a href="http://www.baidu.com">百度</a>'
<p>{{ tag }}</p> # <a href="http://www.baidu.com">百度</a> 只会当成字符串
<p>{{ tag|safe }}</p> # 显示了一个百度的a标签
第四に、ラベル・タグ
タグは次のようになります。{%タグ%}
または論理ループを通る流れを制御するために、いくつかの変数は、テンプレートに追加情報をロードすることによって続きます。
いくつかのタグは開始タグと終了タグを必要とする(例えば、{%タグ%} ...タグコンテンツ... {%のENDTAGの%})。
ループラベル用
ループのための一般的な方法
循环一个字典:
views
dic = {'year':2019,'month':7,'day':17}
html
{% for key,value in dic.items %}
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
循环一个列表:
views
food_list = ['蒸熊掌','烧花鸭','烧子鹅']
html
<ul>
{% for food in food_list %}
<li>{{ food }}</li>
{% endfor %}
</ul>
# 利用 reversed 反向完成循环
<ul>
{% for food in food_list reversed %}
<li>{{ food }}</li>
{% endfor %}
</ul>
リサイクルのための他の方法
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等,比如:forloop.parentloop.counter
注:サイクル数を表示することができる{{forloop}}、ループ内で使用しなければなりません
{% for key,value in dic.items %}
{{ forloop.counter }} # 从1开始计数,比如dic有3个键值对,就1,2,3
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
{% for key,value in dic.items %}
{{ forloop.counter0 }} # 从0开始计数,比如dic有3个键值对,就0,1,2
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
{% for key,value in dic.items %}
{{ forloop.revcounter }} # 倒序直到1计数,比如dic有3个键值对,就3,2,1
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
{% for key,value in dic.items %}
{{ forloop.revcounter0 }} # 倒序直到0计数,比如dic有3个键值对,就2,1,0
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
{% for key,value in dic.items %}
{{ forloop.first }} # 判断是不是第一次循环,显示bool值
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
{% for key,value in dic.items %}
{{ forloop.last }} # 判断是不是第一次循环,显示bool值
<li>{{ key }} -- {{ value }}</li>
{% endfor %}
forloop.parentloop示例:
循环views中的列表 d1 = [['春天','夏天','秋天','冬天'],['雨水','清明']]
{% for dd1 in d1 %}
{% for ddd1 in dd1 %}
{{ forloop.parentloop.counter }}
{{ forloop.counter }}
<div>{{ ddd1 }}</div>
{% endfor %}
{% endfor %}
1 1 父辈的循环计数是1,自己的循环计数是1
春天
1 2 父辈的循环计数是1,自己的循环计数是2
夏天
1 3 父辈的循环计数是1,自己的循环计数是3
秋天
1 4 父辈的循环计数是1,自己的循环计数是4
冬天
2 1 父辈的循环计数是2,自己的循环计数是1
雨水
2 2 父辈的循环计数是2,自己的循环计数是2
清明
以下のために....空
空にするか、見つからないために記載任意{%空%}句とラベルの、操作があってもよいです。
比如在views中并没有给出 person_list,此时html中
{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>sorry,no person here</p>
{% endfor %}
因为没有找到这个列表,页面就会显示empty中的内容 sorry,no person here
如果有 person_list = [{'name':'dazhuang'},{'name':'taibai'},{'name':'alex'}]
此时页面就会显示:dazhuang、taibai、alex
ラベルの場合
文がサポートした場合、または、==、>、<,! =、<=、> =、いないで、で、で、判断両側のスペース上の条件に注意を払うようにされていません
注意:
- Djangoテンプレート言語は、連続決意をサポートしていない、すなわち、以下の文言をサポートしていません:
{%をIF A> B> Cの%}
...
{%} ENDIF% より高い優先度のプロセス属性有するDjangoテンプレート言語(こちら)
DEF XX(要求):
D = { "" :. 1、 "B":2、 "C" :. 3、 "アイテム": "100"}
戻りレンダリング(リクエスト、「xx.html」、 {「データ」:D})は
、我々は、ページをレンダリングするレンダリング方法を使用する場合、パス・キー)Dと、デフォルトd.items(辞書項目である、上記方法、ケースにテンプレート言語:{{data.items}}、デフォルトで、すなわち、むしろアイテム方法を実行するよりも、キー項目は、キー項目100 Dに対応する値を取るd値をとります{%NUM場合> 100またはNUM <0%}
どのような地獄
{%のELIFのNUM> = 80とNUM <= 100%}
本当に激しいギャング
{%他%}
港区は、それを生きます
{%ENDIF%}ビューは、NUM = 100、ページ表示兄ウーリー上を通過した場合
ラベル付き
等号の前後にスペースを注意しない、複雑な変数のエイリアスに使用されている複雑な変数をキャッシュ単純な名前を使用します
假如views中有这样一个列表 person_list = [{'name':'dazhuang'},{'name':'taibai'},{'name':'alex'}],我想把 alex 取出来
两种方式:
方式一:
{% with name=person_list.2.name %} # 注意等号两边没有空格
{{ name }} # 只能在with语句体内用,外边就不好使了
{% endwith %}
方式二:
{% with person_list.2.name as name %}
{{ name }}
{% endwith %}
csrf_tokenラベル
当以post提交表单的时候,会报错,我们之前的解决办法是在settings里面的中间件配置里面把一个csrf的防御机制给注销了 ,而本身是不应该注销的,不让自己的操作被forbiden,通过csrf_token标签就能搞定。
这个标签用于跨站请求伪造保护
在页面的form表单里面(注意是在form表单里面)任何位置写上{% csrf_token %},这个东西模板渲染的时候替换成了<input type="hidden" name="csrfmiddlewaretoken" value="8J4z1wiUEXt0gJSN59dLMnktrXFW0hv7m4d40Mtl37D7vJZfrxLir9L3jSTDjtG8">,隐藏的,这个标签的值是个随机字符串,提交的时候,这个东西也被提交了,首先这个东西是我们后端渲染的时候给页面加上的,那么当你通过我给你的form表单提交数据的时候,你带着这个内容我就认识你,不带着,我就禁止你,因为后台我们django也存着这个东西,和你这个值相同的一个值,可以做对应验证是不是我给你的token,就像一个我们后台给这个用户的一个通行证,如果你用户没有按照我给你的这个正常的页面来post提交表单数据,或者说你没有先去请求我这个登陆页面,而是直接模拟请求来提交数据,那么我就能知道,你这个请求是非法的。
例えば:
views:
def index(request):
if request.method == 'GET':
return render(request,'index.html')
else:
return HttpResponse('成功了呢!!!')
index.html:
<form action="" method="post">
内容:<input type="text">
<button>提交</button>
</form>
# 此时,我们没有加{% csrf_token %},也没注销settings里的防御机制,则网页会报错操作被forbiden
プラス{%csrf_token%}試してみてください。
views:
def index(request):
if request.method == 'GET':
return render(request,'index.html')
else:
return HttpResponse('成功了呢!!!')
index.html:
<form action="" method="post">
{% csrf_token %}
内容:<input type="text">
<button>提交</button>
</form>
# 此时,我们就可以正常的拿到post请求后执行的页面了
第五に、テンプレートの継承
语法: {% extends 'base.html' %} ,可预留钩子block
模版继承就是创建一个基本的“骨架”模版,它包含站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
当我们写许多网页的时候,发现部分网页里面的许多内容都很类似,这样我们就把相似的内容都拿出来,制作成一个母版,需要的页面来继承,这样就会节省许多的重复代码。
制作这样一个界面,输入127.0.0.1:8000/home/,访问首页,显示右边内容是home页面;点击菜单1时,跳转到menu1界面,右边显示menu1;菜单2和3同理;
パスのURLを設定します。
django.conf.urlsインポートURLから
app01インポートビューから
ホーム構成されたパスホーム/、および3つのメニューパスurlpatterns = [ url(r'^home/', views.home), url(r'^menu1/', views.menu1), url(r'^menu2/', views.menu2), url(r'^menu3/', views.menu3), ]
ビュー機能ビュー:
レンダリングdjango.shortcutsからのインポート
ビュー関数と3つのメニューホームを書きますdef home(request): return render(request,'home.html') def menu1(request): return render(request, 'menu1.html') def menu2(request): return render(request, 'menu2.html') def menu3(request): return render(request, 'menu3.html')
HTMLホームページhome.html、および3つのメニュー:私たちは、4つのhtmlファイルを構築する必要がある
ナビゲーションバーとメニューバーが同じ4つの文書なので、コードの4つのファイルであるため、我々はテンプレートメソッドを継承していないとき繰り返し符号のあまりのように、ほとんどの
例えば、同じ3つの基本メニュー、ホーム自宅で<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>模板继承</title> <style> body{ margin: 0; padding: 0; } .nav{ background-color: black; height: 40px; line-height: 40px; } .nav a{ color: white; text-decoration: none; padding: 0 50px; } .left-menu{ background-color: gray; color: white; height: 600px; width: 20%; float: left; } .left-menu a{ color: white; text-decoration: none; } ul{ margin: 0; padding: 0; } li{ padding-left: 75px; height: 50px; line-height: 50px; border: 1px solid black; } .content{ width: 80%; float: right; } .clearfix{ content: ''; display: block; clear: both; } </style> </head> <body> <div class="nav"> <a href="">外设首页</a> <a href="">鼠标专卖</a> <a href="">键盘专卖</a> <a href="">耳麦专卖</a> <input type="text"><button>搜索</button> </div> <div class="clearfix"> <div class="left-menu"> <ul type="none"> <li><a href="/menu1/">菜单1</a></li> <li><a href="/menu2/">菜单2</a></li> <li><a href="/menu3/">菜单3</a></li> </ul> </div> <div class="content"> home页面 只需要改这里,改成其他三个菜单对应的内容 </div> </div> </body> </html>
終了するテンプレートの継承
最初に同じコンテンツを置くために、マスタファイルbase.htmlを作成する
<!DOCTYPE HTML>
模板继承
</head> <body> <div class="nav"> <a href="">外设首页</a> <a href="">鼠标专卖</a> <a href="">键盘专卖</a> <a href="">耳麦专卖</a> <input type="text"><button>搜索</button> </div> <div class="clearfix"> <div class="left-menu"> <ul type="none"> <li><a href="/menu1/">菜单1</a></li> <li><a href="/menu2/">菜单2</a></li> <li><a href="/menu3/">菜单3</a></li> </ul> </div> <div class="content"> {% block content %} 这就是钩子 母版页面 {% endblock content %} </div> </div> </body> </html>
ホームhome.html(共感のHTMLファイル三つの追加メニュー):
{%延び「base.html」%}継承構文{% block content %} 钩子,写自己的的内容,去替换母版钩子的内容 首页页面 {% endblock content %}
したがって、同様の効果を前に完了し、コードの多くを節約することができます
注意的点:
- テンプレート内のタグ{%は%を拡張}使用し、それは、テンプレートの最初のタグでなければなりません。レンダリングテンプレートは、あなたがやっているかわからないDjangoのとき、他の状況下では、テンプレートの継承は、動作しません。
- できるだけ基地{%ブロック%}タグに設けられた複数のテンプレート、必要なすべての親は、テンプレートブロック内のサブテンプレートを定義するために(典型的には少なくとも3つのフック、HTMLページ、CSSを定義するには、A JS)ができるようにほとんどのブロックで、合理的なデフォルトの内容物を充填し、その後、必要なだけの定義
- 保持しつつ、コンテンツやサブページは、マスターブロック内の内容を継承する
{%ブロックのタイトル%}
の内容{{}}#のblock.superマスター表示を
XXX#はあなたのコンテンツを表示する
{%エンドブロックタイトル%を} - 読みやすくするため、また、あなたの{%の末端ブロック%}タグ名与えることができます
{%ブロックのタイトル%}
XXX
{%エンドブロック%}タイトルを - 同じ名前の複数のブロック・タグ・テンプレートで定義することができません。
6つのコンポーネント
構文:{%が 'navbar.html' %含みます}
ページのコンテンツが別のファイルに格納され、ナビゲーション、フッター情報成分として、使用され、その後、必要な場合に使用されてもよく、次の構文により、ファイル内のどこにでも導入することができます。
たとえば:ナビゲーションバーがファイルnav.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 40px;
}
</style>
</head>
<body>
<div class="c1">
<div>
<a href="">xx</a>
<a href="">dd</a>
</div>
</div>
</body>
</html>
この時点で、ナビゲーションバー上のページに直接埋め込まtest.htmlというファイルがあり、
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% include 'nav.html' %} 组件的语法
<h1>xxxxxxxxxx</h1>
</body>
</html>
このようなtest.htmlというファイルには、コードのナビゲーションバーを記述する必要がありますが、それでもナビゲーションバーを持っていません
単純コンポーネントとプラグインとの間の差
组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等。
而插件更倾向封闭某一功能方法的函数。
这两者的区别在 Javascript 里区别很小,组件这个名词用得不多,一般统称插件。
七、カスタムタグやフィルタ
カスタムフィルタ
- アプリのtemplatetagsアプリケーションファイルにフォルダを作成し、フォルダの名前でなければなりません
- xx.pyファイルを作成するtemplatetagsファイルは、ファイルの名前がコールmy_tags.pyとして、アイテム課金などすることができ
my_tags.pyファイル内のカスタムフィルタを作成
ジャンゴインポートテンプレート#からは、最初のテンプレートをインポートregister = template.Library() # register相当于一个注册器,名字是固定的,不可改变 @register.filter # 这样使用注册器,注意filter后不加括号 def my_filter(v1): # 不带参数的过滤器 s = v1 + '你真好' return s @register.filter # 这样使用注册器,注意filter后不加括号 def my_filter(v1,v2): # 带参数的过滤器(最多传递一个参数) s = v1 + '你真好' + v2 return s
パス構成されたURL、ビュービュー機能書き込まれ
たURL:
URL(R&LT 'インデックス^ /'、views.index)views: def index(request): name = 'alex' return render(request,'test.html',{'name':name})
あなたが導入して使用することができますテンプレートファイルのテンプレートで作成したtest.htmlというファイル、
{%負荷my_tags%}
{{nameは| My_Filter}}のページが表示さ:あなたのアレックス素敵な{% load my_tags %} {{ name|my_filter:'呵呵' }} 页面显示:alex你真好呵呵
注意:フィルタのみ定義されたパラメータまで渡すことができるので、複数のパラメータには、カスタムラベルとみなすことができます
カスタムラベル
- Templatetagsはまだファイル内のファイルを作成し、アプリ内のフォルダを作成することですxx.py
- カスタムラベルを作成します
@ register.simple_tag
DEF my_tag(V1、V2、V3):#は、複数のパラメータ渡すことができます
+ V2 + V3 'のようなさんの= v1の+
リターンSを - カスタムタグを使用してHTMLファイル:
{%のmy_tag名「バーベキュー」「ハビール」%}のページが表示されます。アレックスはバーベキューハビールを食べるのが好き
inclusion_tag
リターンHTMLスニペットのために使用されるHTMLは、あなたがこのタグを使用する場所に、コンポーネントとして完成し、htmlファイルをレンダリングする、最初のテンプレートのレンダリングを提出することができ
- Templatetagsはまだファイル内のファイルを作成し、アプリ内のフォルダを作成することですxx.py
カスタムinclusion_tagの作成
の@ register.inclusion_tag( 'test02.html')
DEF FUNC(V1)を:
test02.htmがこの場所を呼び出すFUNCを生成するために、ユニットとして良いレンダリングされます後にデータをレンダリングするためのテンプレートとしてtest02.htmlを通過した戻りデータのFUNC、return {'data':v1} 此时v1接收的 l1 = [11,22,33]
成分はに対応し、機能の一部をカプセル化する、test02.htmlを確立します
- {{D}}
{データ%でDに対する%}
{%ENDFOR%}
このとき、test.htmlというに、別のHTMLファイルは、例えば、に導入TEST02コンポーネント参照されたページと同様とすることができる移動:
{my_tag%の負荷%}
{%}%FUNC L1 L1が機能ビュー上を通過しますが、今回はFUNCに渡します
八個の静的構成ファイル
JS、CSS、IMGなどの静的ファイルと呼ばれ、その後、ジャンゴ静的ファイルの設定、我々は内部のコンフィギュレーションファイルの内容でいくつかの設定を構成する必要があります
- そのようなコールjingtaiwenjianとして、プロジェクトのフォルダ内の静的ファイルを置くために専用のフォルダを作成します。
:構成設定で
STATIC_URL =「/静的/」#エイリアス指定されたパスSTATICFILES_DIRS = [ os.path.join(BASE_DIR,'jingtaiwenjian'), ]
静的ファイルを呼び出します:
htmlファイルで、CSSスタイルに参加したい、静的ファイルを導入する方法があります。
別名静的な利点:方式一: <link rel="stylesheet" href="/jingtaiwenjian/mycss.css"> 这样写是不对的,要用别名static <link rel="stylesheet" href="/static/mycss.css"> 方式二: {% load static %} <link rel="stylesheet" href="{% static 'mycss.css' %}"> 方式三: <link rel="stylesheet" href="{% get_static_prefix %}mycss.css">
- エイリアスは、あなたが見ることができる試運転段階を経ても、ブラウザ上の安全機構であることは他の人があなたが静的フォルダの名前を知ることができないように、エイリアス名でセキュリティを向上させ、または他の誰かがこのフォルダのパスを通してことができるようになります攻撃。
- ときメンテナンスアップデートと、それはスケーラビリティの向上に影響を与えないように、エイリアスを使用するので、静的フォルダの名前を変更した場合
- エイリアスも変更することができる場合であっても、別名マッピングの方法によって静的ファイルパスを取得するために、静的エイリアス負荷を通る経路を見つけるために時間を使います
{%静的%}
引入一张图片:
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
引用JS文件时使用:
{% load static %}
<script src="{% static "mytest.js" %}"></script>
某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
プレフィックスを取得{%Get_static_prefixの%}エイリアス
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
或者,用别名:
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />