Introduction#

getting started with tailwindcss, demo here

  • setup tailwind
  • setup flask
  • create a grid of book
  • print rendered_template to html
  • amplify hosting the static html file
review-books

Without Tailwind#

Let build a simple book store without using tailwind demo

Here is detai code

<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
:root {
box-sizing: border-box;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
}
*,
::before,
::after {
box-sizing: inherit;
}
body {
margin: 0px;
}
.book-card {
background-color: antiquewhite;
padding: 10px 10px;
}
.book-grid {
display: grid;
gap: 10px;
}
@media (min-width: 800px) {
.book-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
<body>
<div style="background-color: #22c55e; padding: 20px 10px">
<div style="max-width: 800px; margin: auto">
<nav style="display: flex">
<a
href="#"
target="_blank"
style="text-decoration: none; font-size: larger; color: black"
>Logo</a
>
<ul
style="
list-style: none;
display: flex;
padding: 0px;
margin: auto;
width: 100%;
"
>
<li style="margin-left: auto">
<a
href="#"
target="_blank"
style="text-decoration: none; color: black"
>About Us</a
>
</li>
</ul>
</nav>
</div>
</div>
<div style="max-width: 800px; margin: auto; padding: 10px 10px">
<div class="book-grid">
<div style="background-color: antiquewhite; padding: 10px 10px">
<h4>Title 1</h4>
<div
style="
height: 200px;
width: 150px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
background-color: #d1d5db;
"
>
Image
</div>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sequi
deserunt corrupti est minus totam. Aliquam maxime explicabo
molestiae itaque saepe, reiciendis magni, architecto, aliquid totam
deleniti obcaecati asperiores natus! Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Odio doloremque aperiam, commodi quos
laboriosam, aliquam necessitatibus fuga, iusto facilis culpa
corrupti vel animi quo deleniti officiis et expedita explicabo modi.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
velit saepe nisi eum autem nobis? Distinctio id natus qui quia nihil
excepturi quas similique, commodi consequatur explicabo magnam earum
neque?
</p>
</div>
<div style="background-color: antiquewhite; padding: 10px 10px">
<h4>Title 2</h4>
<div
style="
height: 200px;
width: 150px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
background-color: #d1d5db;
"
>
Image
</div>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sequi
deserunt corrupti est minus totam. Aliquam maxime explicabo
molestiae itaque saepe, reiciendis magni, architecto, aliquid totam
deleniti obcaecati asperiores natus! Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Odio doloremque aperiam, commodi quos
laboriosam, aliquam necessitatibus fuga, iusto facilis culpa
corrupti vel animi quo deleniti officiis et expedita explicabo modi.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
velit saepe nisi eum autem nobis? Distinctio id natus qui quia nihil
excepturi quas similique, commodi consequatur explicabo magnam earum
neque?
</p>
</div>
<div style="background-color: antiquewhite; padding: 10px 10px">
<h4>Title 3</h4>
<div
style="
height: 200px;
width: 150px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
background-color: #d1d5db;
"
>
Image
</div>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sequi
deserunt corrupti est minus totam. Aliquam maxime explicabo
molestiae itaque saepe, reiciendis magni, architecto, aliquid totam
deleniti obcaecati asperiores natus! Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Odio doloremque aperiam, commodi quos
laboriosam, aliquam necessitatibus fuga, iusto facilis culpa
corrupti vel animi quo deleniti officiis et expedita explicabo modi.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
velit saepe nisi eum autem nobis? Distinctio id natus qui quia nihil
excepturi quas similique, commodi consequatur explicabo magnam earum
neque?
</p>
</div>
<div style="background-color: antiquewhite; padding: 10px 10px">
<h4>Title 4</h4>
<div
style="
height: 200px;
width: 150px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
background-color: #d1d5db;
"
>
Image
</div>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sequi
deserunt corrupti est minus totam. Aliquam maxime explicabo
molestiae itaque saepe, reiciendis magni, architecto, aliquid totam
deleniti obcaecati asperiores natus! Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Odio doloremque aperiam, commodi quos
laboriosam, aliquam necessitatibus fuga, iusto facilis culpa
corrupti vel animi quo deleniti officiis et expedita explicabo modi.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
velit saepe nisi eum autem nobis? Distinctio id natus qui quia nihil
excepturi quas similique, commodi consequatur explicabo magnam earum
neque?
</p>
</div>
</div>
</div>
<footer
style="
/* position: absolute; */
/* bottom: 0px; */
/* left: 0px; */
padding: 10px 10px;
width: 100%;
background-color: #d1d5db;
display: flex;
"
>
<div style="margin: auto">Copyright &copy; 2024 Developer, Inc</div>
</footer>
</body>
</html>

Setup Tailwind#

npm install -D tailwindcss
npx tailwindcss init

Assume that npm and tailwind cli already installed, then create a tailwind.confg.js file as

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
extend: {}
},
plugins: []
}

project structure

day-1
|--dist
|--output.css
|--src
|--input.css
|--index.html
|--tailwind.config.js
|--readme.md

Setup Flask#

Modify the project structure as the following

|--src
|--input.css
|--static
|--output.css
|--book.json
|--templates
|--index.html
|--review-books.html
|--requierments.txt
|--tailwind.config.js
|--app.py

Modify the complile command of tailwind as

npx tailwindcss -i ./src/input.css -o ./static/output.css --watch

To export the Flask page to html, consider the following code

def gen_static_web():
with app.app_context():
rendered = render_template(
"index.html", books=books, nrow=len(books)
)
print(rendered)
if __name__ == "__main__":
# app.run(host="0.0.0.0", port=8080, debug=True)
gen_static_web()

generate a static review-books.html page from the Flask app

python3 -m app.py > review-books.html

Home Page#

navigation bar

<div class="bg-green-400 py-3">
<nav class="flex mx-auto max-w-5xl justify-between">
<a href="#" class="font-bold text-2xl"> Entest </a>
<ul class="hidden md:flex gap-x-3">
<li
class="bg-white hover:bg-green-600 hover:text-white px-3 py-1 rounded-sm"
>
<a href="https://cdk.entest.io/" target="_blank">About Me</a>
</li>
</ul>
</nav>
</div>

hero section

<div
class="bg-[url('https://d2cvlmmg8c0xrp.cloudfront.net/web-css/singapore.jpg')] bg-no-repeat bg-cover"
>
<div class="mx-auto max-w-5xl pt-20 pb-48 pr-48 mb-10 text-right">
<h2 class="invisible md:visible text-3xl font-bold mb-8">
Good Books about AWS Cloud Computing
</h2>
</div>
</div>

the book grid section

<div class="mx-auto max-w-5xl">
{% for row in range(0,nrow,2) %}
<div class="md:flex gap-x-5 flex-row mb-8">
<div class="ml-4 bg-white flex-auto w-full">
<h4 class="font-bold mb-8">{{ books[row].title }}</h4>
<div>
<img
src="{{ books[row].image }}"
class="float-left h-auto w-64 mr-6"
alt="book-image"
/>
</div>
<p>{{ books[row].description}}</p>
<a href="{{ books[row].amazon }}" target="_blank">
<button
class="bg-orange-300 px-14 py-3 rounded-md shadow-md hover:bg-orange-400"
>
Amazon
</button>
</a>
</div>
<div class="ml-4 bg-white flex-auto w-full">
<h4 class="font-bold mb-8">{{ books[row+1].title }}</h4>
<div>
<img
src="{{ books[row+1].image }}"
class="float-left h-auto w-64 mr-6"
alt="book-image"
/>
</div>
<p></p>
<p>{{ books[row+1].description }}</p>
<a href="{{ books[row+1].amazon }}" target="_blank">
<button
class="bg-orange-300 px-14 py-3 rounded-md shadow-md hover:bg-orange-400"
>
Amazon
</button>
</a>
</div>
</div>
{% endfor %}
</div>

footer section

<footer class="bg-gray-200 mt-12 text-gray-00 py-4">
<div class="mx-auto max-w-5xl text-center text-base">
Copyright &copy; 2023 entest, Inc
</div>
</footer>