mirror of
https://github.com/CoolnsX/my-website.git
synced 2025-12-20 07:15:19 +05:30
feat:First Blog
This commit is contained in:
34
config.toml
34
config.toml
@@ -4,8 +4,20 @@ base_url = "https://coolans.dev"
|
|||||||
# Whether to automatically compile all Sass files in the sass directory
|
# Whether to automatically compile all Sass files in the sass directory
|
||||||
compile_sass = false
|
compile_sass = false
|
||||||
|
|
||||||
|
# When set to "true", the generated HTML files are minified.
|
||||||
|
minify_html = false
|
||||||
|
|
||||||
|
# When set to "true", a search index is built from the pages and section
|
||||||
|
# content for `default_language`.
|
||||||
build_search_index = true
|
build_search_index = true
|
||||||
|
|
||||||
|
# When set to "true", a feed is automatically generated.
|
||||||
|
generate_feeds = true
|
||||||
|
feed_filenames = ['rss.xml']
|
||||||
|
|
||||||
|
# The default author for pages
|
||||||
|
author = "Coolans"
|
||||||
|
|
||||||
[markdown]
|
[markdown]
|
||||||
highlight_code = true
|
highlight_code = true
|
||||||
|
|
||||||
@@ -13,5 +25,27 @@ highlight_code = true
|
|||||||
# If this is true, a `rel="noopener"` will always automatically be added for security reasons
|
# If this is true, a `rel="noopener"` will always automatically be added for security reasons
|
||||||
external_links_target_blank = true
|
external_links_target_blank = true
|
||||||
|
|
||||||
|
# Whether to set decoding="async" and loading="lazy" for all images
|
||||||
|
# When turned on, the alt text must be plain text.
|
||||||
|
# For example, `` is ok but `` isn’t ok
|
||||||
|
lazy_async_image = true
|
||||||
|
|
||||||
|
# When set to "true", emoji aliases translated to their corresponding
|
||||||
|
# Unicode emoji equivalent in the rendered Markdown files. (e.g.: :smile: => 😄)
|
||||||
|
render_emoji = true
|
||||||
|
|
||||||
|
[search]
|
||||||
|
# Whether to include the title of the page/section in the index
|
||||||
|
include_title = true
|
||||||
|
# Whether to include the description of the page/section in the index
|
||||||
|
include_description = true
|
||||||
|
# Whether to include the RFC3339 datetime of the page in the search index
|
||||||
|
include_date = true
|
||||||
|
# Whether to include the rendered content of the page/section in the index
|
||||||
|
include_content = true
|
||||||
|
# At which code point to truncate the content to. Useful if you have a lot of pages and the index would
|
||||||
|
# become too big to load on the site. Defaults to not being set.
|
||||||
|
truncate_content_length = 100
|
||||||
|
|
||||||
[extra]
|
[extra]
|
||||||
# Put all your custom variables here
|
# Put all your custom variables here
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
+++
|
+++
|
||||||
title = "Coming Soon"
|
title = "Blog Posts"
|
||||||
sort_by = "date"
|
sort_by = "date"
|
||||||
template = "blog.html"
|
template = "blog.html"
|
||||||
page_template = "blog-page.html"
|
page_template = "blog-page.html"
|
||||||
|
|||||||
28
content/blog/hello-world.md
Normal file
28
content/blog/hello-world.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
+++
|
||||||
|
title = "Hello World"
|
||||||
|
date = 2025-06-15
|
||||||
|
extra.image = "assets/hello_world.webp"
|
||||||
|
description = "My First Blog."
|
||||||
|
+++
|
||||||
|
|
||||||
|
**Welcome to my blog — and thanks for stopping by!**
|
||||||
|
|
||||||
|
{% paragraph(class="m-8") %}
|
||||||
|
This is my very first post, and I thought a simple "Hello World" would be a fitting way to kick things off. I'm Tanveer, a Full Stack Developer and self-taught SysAdmin. I spend most of my time building web applications with **Laravel**, and managing the systems that host them using tools like **NGINX** as webserver, **Docker** for containers.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
{% paragraph(class="m-8") %}
|
||||||
|
Through this blog, I plan to share my experiences, insights, and the occasional troubleshooting war story from both development and server-side adventures. Whether it's code patterns, deployment pipelines, or server optimizations, you'll find it here.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
{% paragraph(class="m-8") %}
|
||||||
|
This blog isn't just a showcase — it's a reflection of my journey. I'm a strong believer in learning by doing, and everything I know has been shaped by building, breaking, and fixing things on my own.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
{% paragraph(class="m-8") %}
|
||||||
|
Expect more posts soon on Laravel internals, secure deployments, performance tuning, and anything else I stumble upon or dive into.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
{% paragraph(class="m-8") %}
|
||||||
|
**Thanks again for reading. More to come :rocket:**
|
||||||
|
{% end %}
|
||||||
BIN
static/assets/hello_world.webp
Normal file
BIN
static/assets/hello_world.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
static/assets/resume.pdf
Normal file
BIN
static/assets/resume.pdf
Normal file
Binary file not shown.
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
{% block title %} Not Found {% endblock title %}
|
{% block title %} Not Found {% endblock title %}
|
||||||
|
|
||||||
|
{% block head_extra %}
|
||||||
|
<link rel="preload" as="image" href="{{ get_url(path='assets/404.webp') | safe }}?v={{ get_hash(path='assets/404.webp') }}" type="image/webp" />
|
||||||
|
{% endblock head_extra %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="flex flex-col items-center justify-center text-center min-h-[60vh] space-y-10">
|
<div class="flex flex-col items-center justify-center text-center min-h-[60vh] space-y-10">
|
||||||
<h1 class="text-5xl md:text-7xl font-extrabold text-white drop-shadow-lg">
|
<h1 class="text-5xl md:text-7xl font-extrabold text-white drop-shadow-lg">
|
||||||
|
|||||||
@@ -3,33 +3,65 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="Coolans Portfolio and Blog Website.">
|
|
||||||
<title>{% block title %}{% endblock title %} - Coolans</title>
|
<title>{% block title %}{% endblock title %} - Coolans</title>
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="{{ get_url(path='main.css') | safe }}?v={{ get_hash(path='main.css') }}"
|
href="{{ get_url(path='main.css') | safe }}?v={{ get_hash(path='main.css') }}"
|
||||||
/>
|
/>
|
||||||
<script>
|
<script defer>
|
||||||
// Mobile menu toggle
|
// Mobile menu toggle
|
||||||
function toggleMobileMenu() {
|
function toggleMobileMenu() {
|
||||||
const menu = document.getElementById("mobile-menu");
|
const menu = document.getElementById("mobile-menu");
|
||||||
menu.classList.toggle("hidden");
|
menu.classList.toggle("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener("click", function (event) {
|
||||||
|
const menu = document.getElementById("mobile-menu");
|
||||||
|
const button = event.target.closest("button[aria-label='Toggle menu']");
|
||||||
|
|
||||||
|
// If menu is open, and click is outside menu and button — close it
|
||||||
|
if (
|
||||||
|
!menu.classList.contains("hidden") &&
|
||||||
|
!menu.contains(event.target) &&
|
||||||
|
!button
|
||||||
|
) {
|
||||||
|
menu.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function openFullscreenTailwind(imgElement) {
|
||||||
|
const overlay = document.createElement('div');
|
||||||
|
overlay.className = `
|
||||||
|
fixed inset-0 bg-black bg-opacity-90 backdrop-blur-sm flex items-center justify-center z-50
|
||||||
|
transition-opacity duration-300 ease-in-out
|
||||||
|
`;
|
||||||
|
overlay.onclick = () => overlay.remove();
|
||||||
|
|
||||||
|
const fullscreenImage = document.createElement('img');
|
||||||
|
fullscreenImage.src = imgElement.src;
|
||||||
|
fullscreenImage.alt = imgElement.alt;
|
||||||
|
fullscreenImage.className = `
|
||||||
|
max-w-[90vw] max-h-[90vh] rounded-2xl shadow-2xl
|
||||||
|
transition-transform duration-500 ease-in-out scale-95 hover:scale-100
|
||||||
|
`;
|
||||||
|
|
||||||
|
overlay.appendChild(fullscreenImage);
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<link rel="preload" as="image" href="/assets/background.webp" type="image/webp"/>
|
||||||
<style>
|
<style>
|
||||||
.bg-image {
|
.bg-image {
|
||||||
background-image: url('/assets/background.webp');
|
background-image: url('/assets/background.webp');
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
{% block head_extra %}{% endblock head_extra %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body
|
<body class="min-h-screen flex flex-col bg-black text-white relative transition-colors duration-300">
|
||||||
class="min-h-screen flex flex-col bg-black text-white relative transition-colors duration-300"
|
|
||||||
>
|
|
||||||
<!-- Blurred Background Image -->
|
<!-- Blurred Background Image -->
|
||||||
<div
|
<div class="fixed inset-0 -z-10 bg-image bg-cover bg-center blur-md"></div>
|
||||||
class="fixed inset-0 -z-10 bg-image bg-cover bg-center blur-md"
|
|
||||||
></div>
|
|
||||||
<div class="fixed inset-0 bg-black/70 -z-5"></div>
|
<div class="fixed inset-0 bg-black/70 -z-5"></div>
|
||||||
|
|
||||||
<!-- Top Navigation -->
|
<!-- Top Navigation -->
|
||||||
@@ -46,7 +78,7 @@
|
|||||||
|
|
||||||
<!-- Mobile menu button -->
|
<!-- Mobile menu button -->
|
||||||
<button
|
<button
|
||||||
class="md:hidden px-3 py-2 rounded-lg text-gray-300 bg-gray-900/80 border border-gray-800 hover:text-white focus:outline-none focus:ring-2 focus:ring-white"
|
class="sm:hidden px-3 py-3 rounded-lg text-gray-300 bg-gray-900/80 border border-gray-800 hover:text-white focus:outline-none focus:ring-2 focus:ring-white"
|
||||||
aria-label="Toggle menu"
|
aria-label="Toggle menu"
|
||||||
onclick="toggleMobileMenu()"
|
onclick="toggleMobileMenu()"
|
||||||
>
|
>
|
||||||
@@ -66,20 +98,19 @@
|
|||||||
<!-- Nav Links Island -->
|
<!-- Nav Links Island -->
|
||||||
<ul
|
<ul
|
||||||
id="mobile-menu"
|
id="mobile-menu"
|
||||||
class="hidden md:flex md:static absolute right-4 top-full mt-2 md:mt-0 px-6 py-3 rounded-2xl bg-gray-900/80 border border-gray-800 shadow-xl backdrop-blur-md space-x-6 md:space-x-6 flex-col md:flex-row text-gray-300 md:items-center"
|
class="hidden sm:flex sm:static absolute right-4 top-full mt-2 sm:mt-0 px-6 py-3 rounded-2xl bg-gray-900/70 border border-gray-800 shadow-xl backdrop-blur-md space-x-6 sm:space-x-6 flex-col sm:flex-row text-gray-300 sm:items-center"
|
||||||
>
|
>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
class="hover:text-blue-400 block py-2 md:py-0"
|
class="hover:text-blue-400 block py-2 sm:py-0"
|
||||||
>Home</a
|
>Home</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="/blog"
|
href="/blog"
|
||||||
class="hover:text-blue-400 block py-2 md:py-0"
|
class="hover:text-blue-400 block py-2 sm:py-0"
|
||||||
>Blogs</a
|
>Blogs</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
@@ -93,7 +124,7 @@
|
|||||||
class="container mx-auto px-4"
|
class="container mx-auto px-4"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="px-6 py-4 rounded-2xl bg-gray-900/80 border border-gray-800 shadow-xl backdrop-blur-md text-center text-sm"
|
class="p-8 rounded-2xl bg-gray-900/80 border border-gray-800 shadow-xl backdrop-blur-md text-center text-sm"
|
||||||
>
|
>
|
||||||
{% block content %}{% endblock content %}
|
{% block content %}{% endblock content %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,45 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ page.title }}{% endblock title %}
|
||||||
|
|
||||||
|
{% block head_extra %}
|
||||||
|
{% if page.description %}
|
||||||
|
<meta name="description" content="{{ page.description | safe }}">
|
||||||
|
{% endif %}
|
||||||
|
{% endblock head_extra %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">
|
|
||||||
|
<h1 class="text-4xl md:text-5xl font-extrabold mb-8 text-center">
|
||||||
{{ page.title }}
|
{{ page.title }}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="subtitle"><strong>{{ page.date }}</strong></p>
|
|
||||||
{{ page.content | safe }}
|
|
||||||
{% endblock content %}
|
|
||||||
|
|
||||||
|
<p class="subtitle"><strong>{{ page.date }}</strong></p>
|
||||||
|
|
||||||
|
{% if page.extra.image %}
|
||||||
|
{% set image = page.extra.image %}
|
||||||
|
{% if image is starting_with("http") %}
|
||||||
|
{% set image_url = image %}
|
||||||
|
{% else %}
|
||||||
|
{% set image_url = get_url(path=image) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="flex justify-center my-4">
|
||||||
|
<img
|
||||||
|
src="{{ image_url | safe }}"
|
||||||
|
alt="{{ page.title }}"
|
||||||
|
class="max-w-full max-h-100 object-cover border border-gray-600 rounded-2xl"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
onclick="openFullscreenTailwind(this)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mt-6 text-xl text-gray-300">
|
||||||
|
{{ page.content | safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock content %}
|
||||||
|
|||||||
@@ -3,12 +3,92 @@
|
|||||||
{% block title %} Blogs {% endblock title %}
|
{% block title %} Blogs {% endblock title %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-4xl md:text-5xl font-extrabold">
|
<h1 class="text-4xl md:text-5xl font-extrabold mb-8 text-center">
|
||||||
{{ section.title }}
|
{{ section.title }}
|
||||||
</h1>
|
</h1>
|
||||||
<ul>
|
|
||||||
|
<!-- Search Input -->
|
||||||
|
<div class="mb-8 text-center">
|
||||||
|
<input
|
||||||
|
id="search-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="Search blogs..."
|
||||||
|
class="w-full max-w-2xl px-4 py-2 rounded-md bg-gray-800 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-600"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Blog Posts Container -->
|
||||||
|
<div id="blog-posts" class="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||||
{% for page in section.pages %}
|
{% for page in section.pages %}
|
||||||
<li><a href="{{ page.permalink | safe }}">{{ page.title }}</a></li>
|
<a
|
||||||
|
href="{{ page.permalink | safe }}"
|
||||||
|
class="blog-card rounded-2xl overflow-hidden bg-gray-900/80 border border-gray-600 shadow-lg backdrop-blur-md transition-transform hover:scale-[1.02]"
|
||||||
|
data-title="{{ page.title | safe }}"
|
||||||
|
data-description="{{ page.description | safe }}"
|
||||||
|
data-url="{{ page.permalink | safe }}"
|
||||||
|
>
|
||||||
|
{% if page.extra.image %}
|
||||||
|
{% set image = page.extra.image %}
|
||||||
|
{% if image is starting_with("http") %}
|
||||||
|
{% set image_url = image %}
|
||||||
|
{% else %}
|
||||||
|
{% set image_url = get_url(path=image) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<img
|
||||||
|
src="{{ image_url | safe }}"
|
||||||
|
alt="{{ page.title }}"
|
||||||
|
class="w-full h-48 object-cover"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="p-6">
|
||||||
|
<h2 class="text-xl font-semibold text-white mb-2">
|
||||||
|
{{ page.title }}
|
||||||
|
</h2>
|
||||||
|
<p class="text-white text-sm">{{ page.date }}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</div>
|
||||||
|
|
||||||
|
<!-- ElasticLunr and Script -->
|
||||||
|
<script src="{{ get_url(path='elasticlunr.min.js') | safe }}"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const input = document.getElementById("search-input");
|
||||||
|
const cards = [...document.querySelectorAll(".blog-card")];
|
||||||
|
|
||||||
|
const index = elasticlunr(function () {
|
||||||
|
this.addField("title");
|
||||||
|
this.addField("description");
|
||||||
|
this.setRef("url");
|
||||||
|
});
|
||||||
|
|
||||||
|
cards.forEach(card => {
|
||||||
|
index.addDoc({
|
||||||
|
title: card.dataset.title,
|
||||||
|
description: card.dataset.description,
|
||||||
|
url: card.dataset.url
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener("input", function () {
|
||||||
|
const query = this.value.trim();
|
||||||
|
if (query.length < 1) {
|
||||||
|
cards.forEach(c => c.style.display = "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = index.search(query, { expand: true });
|
||||||
|
const urls = results.map(r => r.ref);
|
||||||
|
|
||||||
|
cards.forEach(card => {
|
||||||
|
card.style.display = urls.includes(card.dataset.url) ? "" : "none";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -2,9 +2,13 @@
|
|||||||
|
|
||||||
{% block title %}Welcome{% endblock title %}
|
{% block title %}Welcome{% endblock title %}
|
||||||
|
|
||||||
|
{% block head_extra %}
|
||||||
|
<meta name="description" content="Coolans Portfolio and Blog Website.">
|
||||||
|
{% endblock head_extra %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-4xl md:text-5xl font-extrabold leading-tight">
|
<h1 class="text-4xl md:text-5xl font-extrabold leading-tight">
|
||||||
Hi, I'm Tanveer — a Full Stack Developer & Self-Taught SysAdmin.
|
HI <br> I'm Tanveer Ahmed Ansari <br>Full Stack Developer & Self-Taught SysAdmin.
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="mt-6 text-lg text-gray-300">
|
<p class="mt-6 text-lg text-gray-300">
|
||||||
|
|||||||
3
templates/shortcodes/paragraph.html
Normal file
3
templates/shortcodes/paragraph.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<p {% if class %}class="{{class}}"{% endif %}>
|
||||||
|
{{ body | markdown | safe }}
|
||||||
|
</p>
|
||||||
Reference in New Issue
Block a user