Flask 프레임워크에서 사용하는 템플릿 언어
'템플릿'이 되는 HTML 문서에 데이터가 들어갈 곳을 표시해놓는 역할
html에서만 사용 가능
# 서버에서 name 이라는 이름으로 값 보내줌
@app.route('/')
def main():
myname = "sparta"
return render_template("index.html", name=myname)
# html 파일에서 이 값이 들어갈 자리를 표시
<h3>Hello, {{ name }}!</h3>
# for ,if 문
{% for row in rows %}
{% set gu_name = row.MSRSTE_NM %}
{% set gu_mise = row.IDEX_MVL %}
{% if gu_mise >= 80 %}
<li>{{ gu_name }}: {{ gu_mise }}</li>
{% endif %}
{% endfor %}
# Owlbot API 요청 코드
let word = '{{ word }}' # keyword로 받아온 변수 word
$(document).ready(function () {
get_definitions()
})
function get_definitions() {
$.ajax({
type: "GET",
url: `https://owlbot.info/api/v4/dictionary/${word}`,
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Token [내토큰]");
},
data: {},
error: function (xhr, status, error) {
alert("에러 발생!");
},
success: function (response) {
console.log(response)
# API에서 받은 값들을 해당 태그에 넣어주기
# id=word의 값을 받아온 값의 word로 바꿔서 보여줌.
$("#word").text(response["word"]) # id=word의 값이 name 으로
$("#pronunciation").text(`/${response["pronunciation"]}/`)
$("#definitions").empty()
let definitions = response["definitions"] # dic 형태
for (let i=0;i<definitions.length;i++) {
let definition = definitions[i]
let html_temp = `<div style="padding:10px">
<i>${definition["type"]}</i>
<br>${definition["definition"]}<br>
<span class="example">${definition["example"]}</span>
</div>`
$("#definitions").append(html_temp)
}
}
})
}
# ------------- 발음이 null 이라면 ----------------------
if (response["pronunciation"]==null) {
$("#pronunciation").text("")
} else {
$("#pronunciation").text(`/${response["pronunciation"]}/`)
}
# -------------- 예문이 null이라면 ----------------------
let html_temp = ``
if (definition["example"]!=null) {
html_temp = `<div style="padding:10px">
<i>${definition["type"]}</i>
<br>${definition["definition"]}<br>
<span class="example">${definition["example"]}</span>
</div>`
} else {
html_temp = `<div style="padding:10px">
<i>${definition["type"]}</i>
<br>${definition["definition"]}<br>
</div>`
}
$("#definitions").append(html_temp)
# app.py에서 요청을 보내 받은 응답을 보여줌
@app.route('/detail/<keyword>')
def detail(keyword):
r = requests.get(f"https://owlbot.info/api/v4/dictionary/{keyword}",\
headers={"Authorization": "Token [내토큰]"})
result = r.json()
print(result)
return render_template("detail.html", word=keyword, result=result)
# detail.html의 원래 div에 변형
<div id="definitions">
{% for definition in result.definitions %}
<div style="padding:10px">
<i>{{ definition.type }}</i> {{ definition['type'] }} 도 가능
<br>{{ definition.definition }}<br>
<span class="example">{{ definition.example }}</span>
</div>
{% endfor %}
</div>
# 1. example 이 none 일 때
{% if definition.example != None %}
<span class="example">{{ definition.example }}</span>
{% endif %} # {% if definition.example %} 도 가능
# 2. 예문에 html 태그가 있을 때
<span class="example">{{ definition.example|safe }}</span>
# 3. 예문에서 깨진 문자나 기호가 있을 때
{{ definition.example.encode('ascii', 'ignore').decode('utf-8') }}
# (인코드할 때, ascii 문자를 무시하고, 다시 문자로 인식하기)
# 최종 div 변형
<div id="definitions">
{% for definition in result.definitions %}
<div style="padding:10px">
<i>{{ definition.type }}</i>
<br>{{ definition.definition.encode('ascii', 'ignore').decode('utf-8') }}<br>
{% if definition.example %}
<span class="example">{{ definition.example.\
encode('ascii', 'ignore').decode('utf-8')|safe }}</span>
{% endif %}
</div>
{% endfor %}
</div>
# css
.wrap {
background-color: RGBA(232, 52, 78, 0.2);
min-height: 100vh;
padding-bottom: 50px;
}
.banner {
width: 100%;
height: 200px;
background-color: white;
background-image: url('{{ url_for("static", filename="logo_red.png") }}');
background-position: center;
background-size: contain;
background-repeat: no-repeat;
cursor: pointer;
}
# html
<div class="wrap">
<div class="banner" onclick="window.location.href='/'">
</div>
# head 위쪽에
<meta property="og:title" content="Sparta Vocabulary Notebook"/>
<meta property="og:description" content="mini project for Web Plus"/>
<meta property="og:image" content="{{ url_for('static', filename='logo_red.png') }}"/>
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
# 브라우저에 해당 API로 요청 보내기
http://localhost:5000/detail?word_give=hello
# 서버에서 파라미터 값을 받아 html로 넘겨주기;
@app.route('/detail')
def detail():
word_receive = request.args.get("word_give")
return render_template("detail.html", word=word_receive)
# html에서 word라는 변수에 저장된 값 나타내기
받은 단어는 {{ word }}
# flask 프레임워크에서는 url의 일부를 변수로 받을 수도 있음
@app.route('/detail/<keyword>')
def detail(keyword):
return render_template("detail.html", word=keyword)
# 파이썬의 app.py에서
r = requests.get("https://owlbot.info/api/v4/dictionary/owl", headers={"Authorization": "Token [내토큰]"})
result = r.json()
print(result)
# html의 Ajax 코드로
$.ajax({
type: "GET",
url: "https://owlbot.info/api/v4/dictionary/owl",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Token [내토큰]");
},
data: {},b
error: function (xhr, status, error) {
alert("에러 발생!");
},
success: function (response) {
console.log(response)
}
})
# status_receive 추가
@app.route('/detail/<keyword>')
def detail(keyword):
status_receive = request.args.get('status_give')
# API에서 단어 뜻 찾아서 결과 보내기
r = requests.get(f"https://owlbot.info/api/v4/dictionary/{keyword}", headers={"Authorization": "Token 23b152dbd0945a866144590f5aa4c6a2c8df3db3"})
result = r.json()
print(result)
return render_template("detail.html", word=keyword, result=result, status=status_receive)
# app.py
@app.route('/')
def main():
# DB에서 저장된 단어 찾아서 HTML에 나타내기
words = list(db.words.find({}, {'_id': False}))
return render_template("index.html", words=words)
# html
<script> # words가 리스트 형식이라 ""를 인식못해서 tojson 으로 문자로 인식하게 해주기
let words = {{ words|tojson }};
let word_list = [];
for (let i=0; i<words.length; i++) {
word_list.push(words[i]['word'])
}
console.log(word_list)
</script>
# 단어를 하이라이트하고 스크롤해서 그 자리를 찾아가게 해라
# (형제들은 클래스에서 빼버려라, 하나만 하이라이트 되게)
$(`#word-${word}`).addClass("highlight")
$(`#word-${word}`).siblings().removeClass("highlight")
$(`#word-${word}`)[0].scrollIntoView()
function get_examples() {
$("#example-list").empty()
$.ajax({
type: "GET",
url: `/api/get_exs?word_give=${word}`,
data: {},
success: function (response) {
console.log(response)
let examples = response['examples']
for (let i=0; i < examples.length; i++) {
let example = examples[i]
let temp_html = `<li id="ex-${i}}">${example['example']} <a
href="javascript:delete_ex(${i})">delete</a></li>`
$('#example-list').append(temp_html)
}
}
});
}
function add_ex() {
let new_ex = $('#new-example').val();
if (!new_ex.toLowerCase().includes(word)) {
alert(`the word '${word}' is not included.`);
return;
}
console.log(new_ex)
$.ajax({
type: "POST",
url: `/api/save_ex`,
data: {
word_give: word,
example_give: new_ex
},
success: function (response) {
get_examples();
$('#new-example').val("");
}
});
}
function delete_ex(i) {
console.log("deleting", i)
$.ajax({
type: "POST",
url: `/api/delete_ex`,
data: {
word_give: word,
number_give: i
},
success: function (response) {
get_examples()
}
});
}
@app.route('/api/get_exs', methods=['GET'])
def get_exs():
# 예문 가져오기
word_receive = request.args.get('word_give')
result = list(db.examples.find({'word': word_receive}, {'_id': False}))
return jsonify({'result': 'success', 'examples': result})
@app.route('/api/save_ex', methods=['POST'])
def save_ex():
word_receive = request.form['word_give']
example_receive = request.form['example_give']
doc = {
'word': word_receive,
'example': example_receive
}
db.examples.insert_one(doc)
return jsonify({'result': 'success', 'msg': '예문 저장'})
@app.route('/api/delete_ex', methods=['POST'])
def delete_ex():
# 예문 삭제하기
word_receive = request.form['word_give']
number_receive = int(request.form["number_give"])
example = list(db.examples.find({"word": word_receive}))[number_receive]["example"]
db.examples.delete_one({"word": word_receive, "example": example})
return jsonify({'result': 'success'})