Ongoing Project — My Article Memo
--
The goal of this project is to construct a website where one can store URLs with brief comments to be referred back to when necessary. I will be expanding this project as I continue my studies, and my weekly updates will be posted below.
Week 1 — HTML, CSS, and JavaScript Foundation
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1"
aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never
share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control"
id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-check">
<input type="checkbox" class="form-check-input"
id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">Check me
out</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Form HTML Bootstrap Source: https://getbootstrap.com/docs/4.0/components/forms/
<div class="card-columns">
<div class="card">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title that wraps to a new
line</h5>
<p class="card-text">This is a longer card with supporting
text below as a natural lead-in to additional content.
This content is a little bit longer.</p>
</div>
</div>
</div>
255x160 Card Column HTML Bootstrap Source: https://getbootstrap.com/docs/4.0/components/card/
<!doctype html>
<html lang="en"><head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-
scale=1, shrink-to-fit=no">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com"
crossorigin>
<link href="https://fonts.googleapis.com/css2?
family=Bree+Serif&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/
4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh
0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/
jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper
.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/
ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/
js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSf
FWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous">
</script> <title>My Memo</title> <style>
*{
font-family: 'Bree Serif', serif;
}
.wrap {
width: 900px;
margin: auto
}
.card-title {
color: dodgerblue;
font-size: 20px;
}
.form{
width: 900px;
margin: auto; border: 3px dashed grey;
border-radius: 10px;
margin-bottom:30px;
padding: 30px 30px 30px 30px;
}
</style>
<script>
function posted() {
alert('Posted!');
}
</script>
</head><body>
<div class="wrap">
<div class="jumbotron">
<h1 class="display-4">My Memo</h1>
<p class="lead">A place where you can keep important
notes and visit anytime you need.</p>
<hr class="my-4">
<p class="lead">
<p class="btn btn-primary btn-lg"
role="button">Open Posting Box</p>
</p>
</div>
<div class="form">
<div class="form-group">
<label for="exampleInputEmail1">Article URL</label>
<input type="email" class="form-control"id="example
InputEmail1" aria-describedby=emailHelp"
placeholder="">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Brief
Comment</label>
<textarea class="form-control"id="exampleForm
ControlTextarea1" rows="3"></textarea>
</div>
<button onclick="posted()"type="submit" class="btn btn-
primary">Save</button>
</div>
<div class="card-columns">
<div class="card">
<img class="card-img-top"src="https://tourdragon.com
/images/ tour_images/HERO_UltimateRome_Hero_shutter
stock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.
com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna
aliqua.</p>
<a class="comment" href="https://www.naver.
com/">Comments</a>
</div>
</div>
</div>
</body></html>
The bolded part of the code has been adopted from the source and modified for aesthetic and functional enhancement. The outcome looks like this:
- HTML: used in formatting the overall structure.
- CSS: input group bootstraps obtained from https://getbootstrap.com/ for information gathering.
- Javascript: “Posted!” alert activating upon pressing the “Save” button.
Next week, I hope to add various jQuery functions to reveal/hide the posting box upon and “add new cards”
Week 2 — jQuery Functions
<script>
function posted() {
alert('Posted!');
}
function openclose() {
let status = $(`#post-box`).css('display');
if (status == 'block') {
$(`#post-box`).hide()
} else {
$(`#post-box`).show();
}
}
</script>
We want the button to read “Close Posting Box” when the posting box is open, and “Open Posting Box” when it is closed. To do that, we assign an ID to the button and use an IF statement to display a certain text within the ID-ed button in a corresponding situation. Let the ID be #btn-posting-box:
div class="jumbotron">
<h1 class="display-4">My Article Memo</h1>
<p class="lead">A place where you can keep important articles and visit anytime you need.</p>
<hr class="my-4">
<p class="lead">
<p onclick="openclose()" id="btn-posting-box" class="btn btn-primary btn-lg" role="button">Open Posting Box</p>
</p>
</p>
</div>
Then we write the following functions:
<script>
function posted() {
alert('Posted!');
}
function openclose() {
let status = $(`#post-box`).css('display');
if (status == 'block') {
$(`#post-box`).hide()
$(`#btn-posting-box`).text('Open Posting Box')
} else {
$(`#post-box`).show()
$(`#btn-posting-box`).text('Close Posting Box');
}
}
</script>
Then, the following change is implemented:
Finally, we want the posting box to be initially closed. This simple change can be made in the CSS section as follows, and our mission’s complete.
<style>
*{
font-family: 'Bree Serif', serif;
}
.wrap {
width: 900px;
margin: auto
}
.card-title {
color: dodgerblue;
font-size: 20px;
}
.posting-box{
width: 900px;
margin: auto;
border: 3px dashed grey;
border-radius: 10px;
margin-bottom:30px;
padding: 30px 30px 30px 30px;
display: none;
}
</style>
Therefore, our new code presents itself as:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bree+Serif&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<title>My Article Memo | jQuery</title>
<style>
*{
font-family: 'Bree Serif', serif;
}
.wrap {
width: 900px;
margin: auto
}
.card-title {
color: dodgerblue;
font-size: 20px;
}
.posting-box{
width: 900px;
margin: auto;
border: 3px dashed grey;
border-radius: 10px;
margin-bottom:30px;
padding: 30px 30px 30px 30px;
display: none;
}
</style>
<script>
function posted() {
alert('Posted!');
}
function openclose() {
let status = $(`#post-box`).css('display');
if (status == 'block') {
$(`#post-box`).hide()
$(`#btn-posting-box`).text('Open Posting Box')
} else {
$(`#post-box`).show()
$(`#btn-posting-box`).text('Close Posting Box');
}
}
</script>
</head>
<body>
<div class="wrap">
<div class="jumbotron">
<h1 class="display-4">My Article Memo</h1>
<p class="lead">A place where you can keep important articles and visit anytime you need.</p>
<hr class="my-4">
<p class="lead">
<p onclick="openclose()" id="btn-posting-box" class="btn btn-primary btn-lg" role="button">Open Posting Box</p>
</p>
</p>
</div>
<div class="posting-box" id="post-box">
<div class="form-group">
<label for="article-url">Article URL</label>
<input type="email" class="form-control" id="article-url" aria-describedby="emailHelp"
placeholder="">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Brief Comment</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<button onclick="posted()" class="btn btn-primary btn-lg" role="button"type="submit" class="btn btn-primary">Save</button>
</div>
<div class="card-columns">
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
<div class="card">
<img class="card-img-top" src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg" alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<a class="comment" href="https://www.naver.com/">Comments</a>
</div>
</div>
</div>
</body>
</html>
Wow, jQuery is powerful, indeed. What would be our next challenge?
Week 3 — Importing Naver Movie with Ajax
I will be importing a set of data from Naver Movies (South Korea’s biggest movies information website) to the My Memo Project so that each card displays a certain set of information for a movie. I obtained the OpenAPI from the Sparta Coding Club, a programming community I am a member of.
<script>
$(document).ready(function () {
listing();
}); function listing() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/post",
data: {},
success: function (response) {
let rows = response['articles']
for (let i = 0; i < rows.length; i++) {
let comment = rows[i]['comment']
let desc = rows[i]['desc']
let image = rows[i]['image']
let title = rows[i]['title']
let url = rows[i]['url'] let temp_html = `<div class="card">
<img class="card-img-top"
src="${image}"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="${url}">${title}</a>
<p class="card-text">${desc}</p>
<p class="card-comment">${comment}</p>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
}) }
.
.
.
</script>
Above is the final product, where the .ready() function initiates the entire process as soon as the webpage refreshes. Most of the functions have been covered before, so they should be intuitive! This way, the webpage will import from the OpenAPI comments, descriptions, images, titles, and URLs for the movies listed in the website.
So we can obtain the final product as shown below:
<!doctype html>
<html lang="en"><head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bree+Serif&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script> <title>My Article Memo | jQuery</title> <style>
* {
font-family: 'Bree Serif', serif;
} .wrap {
width: 900px;
margin: auto
} .card-title {
color: dodgerblue;
font-size: 20px;
} .posting-box {
width: 900px;
margin: auto; border: 3px dashed grey;
border-radius: 10px;
margin-bottom: 30px;
padding: 30px 30px 30px 30px; display: none;
}
</style>
<script>
$(document).ready(function () {
$('#cards-box').empty()
listing();
}); function listing() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/post",
data: {},
success: function (response) {
let rows = response['articles']
for (let i = 0; i < rows.length; i++) {
let comment = rows[i]['comment']
let desc = rows[i]['desc']
let image = rows[i]['image']
let title = rows[i]['title']
let url = rows[i]['url'] let temp_html = `<div class="card">
<img class="card-img-top"
src="${image}"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="${url}">${title}</a>
<p class="card-text">${desc}</p>
<p class="card-comment">${comment}</p>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
}) } function posted() {
alert('Posted!');
} function openclose() {
let status = $(`#post-box`).css('display');
if (status == 'block') {
$(`#post-box`).hide()
$(`#btn-posting-box`).text('Open Posting Box')
} else {
$(`#post-box`).show()
$(`#btn-posting-box`).text('Close Posting Box');
}
}
</script>
</head><body>
<div class="wrap">
<div class="jumbotron">
<h1 class="display-4">My Article Memo</h1>
<p class="lead">A place where you can keep important articles and visit anytime you need.</p>
<hr class="my-4">
<p class="lead">
<p onclick="openclose()" id="btn-posting-box" class="btn btn-primary btn-lg" role="button">Open Posting Box</p>
</p>
</p>
</div>
<div class="posting-box" id="post-box">
<div class="form-group">
<label for="article-url">Article URL</label>
<input type="email" class="form-control" id="article-url" aria-describedby="emailHelp"
placeholder="">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Brief Comment</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<button onclick="posted()" class="btn btn-primary btn-lg" role="button" type="submit" class="btn btn-primary">
Save
</button>
</div>
<div class="card-columns" id="cards-box">
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
<div class="card">
<img class="card-img-top"
src="https://tourdragon.com/images/tour_images/HERO_UltimateRome_Hero_shutterstock789412159.jpg"
alt="Card image cap">
<div class="card-body">
<a class="card-title" href="https://www.naver.com/">Your title goes here</a>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt
ut labore et dolore magna aliqua.</p>
<p class="comment">Comments</p>
</div>
</div>
</body>
</html>
And the webpage finally looks like this:
Week 4 — Connecting to a Server with FLASK
HTML File — “index.html”
<!Doctype html>
<html lang="ko">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<!-- JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Bree+Serif&display=swap" rel="stylesheet">
<title>My Article Memo</title>
<!-- style -->
<style type="text/css">
* {
font-family: "Bree Serif", serif;
}
.wrap {
width: 900px;
margin: auto;
}
.comment {
color: dodgerblue;
font-weight: bold;
}
#post-box {
width: 900px;
margin: auto;
border: 3px dashed grey;
border-radius: 10px;
margin-bottom: 30px;
padding: 30px 30px 30px 30px;
}
</style>
<script>
$(document).ready(function () {
showArticles();
});
function openClose() {
if ($("#post-box").css("display") == "block") {
$("#post-box").hide();
$("#btn-post-box").text("Open Posting Box");
} else {
$("#post-box").show();
$("#btn-post-box").text("Close Posting Box");
}
}
function postArticle() {
let url = $('#post-url').val()
let comment = $('#post-comment').val()
$.ajax({
type: "POST",
url: "/memo",
data: {url_give:url, comment_give:comment},
success: function (response) { // if successful
alert(response["msg"]);
window.location.reload()
}
})
}
function showArticles() {
$.ajax({
type: "GET",
url: "/memo",
data: {},
success: function (response) {
let articles = response['all_articles']
for (let i = 0; i < articles.length; i++) {
let title = articles[i]['title']
let image = articles[i]['image']
let url = articles[i]['url']
let desc = articles[i]['desc']
let comment = articles[i]['comment']
let temp_html = `<div class="card">
<img class="card-img-top"
src="${image}"
alt="Card image cap">
<div class="card-body">
<a target="_blank" href="${url}" class="card-title">${title}</a>
<p class="card-text">${desc}</p>
<p class="card-text comment">${comment}</p>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
})
}
</script>
</head>
<body>
<div class="wrap">
<div class="jumbotron">
<h1 class="display-4">My Article Memo</h1>
<p class="lead">A place where you can keep important articles and visit anytime you need.</p>
<hr class="my-4">
<p class="lead">
<button onclick="openClose()" id="btn-post-box" type="button" class="btn btn-primary">Open Posting Box
</button>
</p>
</div>
<div id="post-box" class="form-post" style="display:none">
<div>
<div class="form-group">
<label for="post-url">Article URL</label>
<input id="post-url" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="post-comment">Brief Comment</label>
<textarea id="post-comment" class="form-control" rows="2"></textarea>
</div>
<button type="button" class="btn btn-primary" onclick="postArticle()">Save</button>
</div>
</div>
<div id="cards-box" class="card-columns">
</div>
</div>
</body>
</html>
Server — “app.py”
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
## HTML
@app.route('/')
def home():
return render_template('index.html')
@app.route('/memo', methods=['GET'])
def listing():
articles = list(db.articles.find({}, {'_id': False}))
return jsonify({'all_articles':articles})
## API
@app.route('/memo', methods=['POST'])
def saving():
url_receive = request.form['url_give']
comment_receive = request.form['comment_give']
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url_receive, headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
title = soup.select_one('meta[property="og:title"]')['content']
image = soup.select_one('meta[property="og:image"]')['content']
desc = soup.select_one('meta[property="og:description"]')['content']
doc = {
'title':title,
'image':image,
'desc':desc,
'url':url_receive,
'comment':comment_receive
}
db.articles.insert_one(doc)
return jsonify({'msg':'Saved!'})
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)