나만의 단어장 만들기 2 - Jinja2
<tbody id="tbody-box">
{% for word in words %}
<tr id="word-{{ word.word }}">
<td><a href="/detail/{{ word.word }}?status_give=old">{{ word.word }}</a></td>
<td>
{{ word.definition }}
</td>
</tr>
{% endfor %}
</tbody>
배경과 배너 등 디자인 요소가 겹치므로 CSS 파일을 분리하여 링크로 넣어주면 같은 CSS를 적용해줄 수 있음!
static 폴더에 mystyle.css 파일을 만들고 공통 요소에 대한 CSS를 잘라내어 붙여넣는다
배너 이미지는 같은 폴더에 있으니 바꿔주깅
background-image: url('logo_red.png');
index, detail 두 html 파일안에 아래 코드를 넣는다.
의미는 진자 템플릿 언어를 이용해 static 폴더 안에 mystyle.css에 해당하는 url을 만들어줘! ㄹㅏ고 하는 url_for 사용
<link href='{{ url_for("static", filename="mystyle.css") }}' rel="stylesheet">
DB에 저장된 단어 찾아서 HTML에 나타내기
_id가 mongoDB에서 자동으로 넣어주는 값인데 render_template에 넣어주면 이해를 못해서 에러가 나기때문에
_id에 해당하는 열은 꼭 빼주고 넣어줘야함
@app.route('/')
def main():
# DB에서 저장된 단어 찾아서 HTML에 나타내기
words = list(db.words.find({}, {"_id": False}))
return render_template("index.html", words=words)
우선 tbody 안에 tr을 반복할 것이기 때문에
<tbody id="tbody-box">
{% for word in words %}
<tr id="word-word">
<td><a href="#">word</a></td>
<td></td>
</tr>
{% endfor %}
</tbody>
<tbody id="tbody-box">
{% for word in words %}
<tr id="word-{{ word.word }}">
<td><a href="/detail/{{ word.word }}?status_give=old">{{ word.word }}</a></td>
<td>
{{ word.definition }}
</td>
</tr>
{% endfor %}
</tbody>
이제 리스트에 있는 단어 불러와보자!
스크립트 안에, words를 json형태로 받고 반복문으로 불러온다
(단어를 검색했을 때 이미 저장된 단어인지 알기 위해서 있는 단어 리스트)
let words={{ words|tojson }};
let word_list=[];
for (let i=0; i<words.length;i++){
word_list.push(words[i]["word"])
}
이제 검색 기능 구현~
function find_word(){
let word=$("#input-word").val() //input-word에 값을 받아주면 word에 저장됨
if (word_list.includes(word)) { //word_list 안에 word가 있다면
//리스트에 있으면 하이라이트
$(`#word-${word}`).addClass("highlight")
$(`#word-${word}`)[0].scrollIntoView() //#word-${word} 에 맞는 첫번째 요소를 찾아 스크롤하라
}else{ //리스트에 없으면 새 단어 위한 상세페이지로
window.location.href=`/detail/${word}?status_give=new`
}
}
하이라이트 빨강색 주기
tr 안에 있는 td 안에다가 스타일을 주라는 의미
tr.highlight > td{
background-color: #e8344e;
}
단어는 a태그라 검정색이 되네..
그래서 하얀색 되도록 또 스타일 만들어줌
tr.highlight > td > a {
color: white;
}
아무것도 입력 안하고 검색했을때를 위해 코드 추가
function find_word(){
let word=$("#input-word").val() //input-word에 값을 받아주면 word에 저장됨
if (word==""){ // ******아무것도 입력 안하고 검색했을 때
alert("값을 입력해주세요!")
return
}
if (word_list.includes(word)) { //word_list 안에 word가 있다면
//리스트에 있으면 하이라이트
$(`#word-${word}`).addClass("highlight")
$(`#word-${word}`)[0].scrollIntoView() //#word-${word} 에 맞는 첫번째 요소를 찾아 스크롤하라
}else{ //리스트에 없으면 새 단어 위한 상세페이지로
window.location.href=`/detail/${word}?status_give=new`
}
}
리스트에 검색했을 때 빨간색이 되는 것이 계속 남아있다.
tbody는 td들의 부모이고, td들은 형제이기 때문에
td들 중 한명이 검색됐을 때 다른 애들은 하이라이트 기능이 없어지도록 해보장
function find_word()에다가,
형제들을 찾아서 하이라이트 클래스를 없애줘 라는 의미의 코드 추가!
$(`#word-${word}`).siblings().removeClass("highlight")
대문자와 소문자는 같은 단어야! 라고 인식하도록 해보장
무조건 소문자로 input-word를 받자!
let word=$("#input-word").val().toLowerCase()
요상한 단어를 검색했을 때, 그냥 홈으로 돌아오도록 하게 하자
redirect는 현재 요청된 연결을 다른 주소로 연결,
(값을 잘 받아왔을 때 상태 코드가 200이므로 200이 아닐 때 main으로 리다이렉팅)
render_template는 템플릿을 렌더링하는 것
@app.route('/detail/<keyword>') #주소 URL의 일부(앞부분만)받아
def detail(keyword):
status_receive=request.args.get("status_give")
#keyword 라는 변수로 저장을 해서 요청을 보내는 URL뒤에 넣어준 뒤, header 정보 안에 내 토큰을 넣어준다
r = requests.get(f"https://owlbot.info/api/v4/dictionary/{keyword}", headers={"Authorization": "Token ed4c16e8cab27f9cf2587dcba3c60d9a2a89a0ee"})
if r.status_code!=200:
return redirect(url_for("main", msg="단어가 이상합니다!")) #현재 요청된 연결을 특정 주소로 재연결
result = r.json()
print(result)
return render_template("detail.html", word=keyword,result=result,status=status_receive) #detail/ 뒤에 오는 단어를 word로 보냄
detail에서 온 메시지를(status) alert로
{% if msg %}
alert("{{ msg }}")
{% endif %}
완성도를 위해 og태그를 넣자!(공유했을 때 예쁜 이미지가 나오게..)
favicon도 넣어보자~(상단 탭의 왼쪽 모양)
<title>아래에다가 아래 코드 붙여넣고,
파비콘 이미지와 og 이미지 static에 넣어준다
<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='lee.jpg') }}"/>
<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">