Connect with Amin Boulouma Official
Building an OOP Jekyll Slug Generator From Scratch
In static site generators like Jekyll, Hugo, or Astro, routing patterns rely on strict file system naming conventions. For instance, to publish a blog post, your Markdown file must live inside a dedicated local _posts/ directory and match an explicit metadata naming standard: YYYY-MM-DD-hyphenated-slug.md.
While modern content management systems (CMS) hide string formatting behind heavy database engines, local static workflows require automated build tools to sanitize text inputs into web-safe, Search Engine Optimized (SEO) URL tokens.
To understand how text pipelines process strings safely from first principles, we can design a decoupled, production-grade text transformation engine.
Adhering to our repository’s strict zero-dependency constraint, we will use Object-Oriented Programming (OOP) principles to separate raw text cleanup pipelines from interactive console interface controllers using nothing but pure Python.
The OOP Content Pipeline Architecture
Our platform design breaks responsibilities down into two independent classes. The SlugGenerator handles character pruning and string serialization, while the TerminalInterface manages system state parameters, caches runtime data, and drives the interactive input loop.
Here is the complete codebase block matching our first-principles system integration matrix:
import datetime
import string
class SlugGenerator:
"""Handles the transformation of raw text titles into clean, web-safe SEO slugs."""
def __init__(self, punctuation_mask=None):
# Allow custom punctuation masks, defaulting to standard string punctuation
self.punctuation_mask = punctuation_mask if punctuation_mask is not None else string.punctuation
def clean_title(self, title: str) -> str:
"""Forces lowercase normalization and purges masked punctuation characters."""
if not title:
return ""
lowercase_title = title.lower()
# Filter technique strips matching punctuation markers in a single pass
return "".join(char for char in lowercase_title if char not in self.punctuation_mask)
def build_slug(self, title: str) -> str:
"""Transforms a raw title into a standard hyphenated url token block."""
cleaned = self.clean_title(title)
tokens = cleaned.split()
return "-".join(tokens)
class TerminalInterface:
"""Manages the terminal input/output state machine and interactive loop logic."""
def __init__(self, generator: SlugGenerator):
# Explicit Dependency Injection of our logic engine worker
self.generator = generator
# Cache today's prefix date string inside instance memory state
self.date_prefix = datetime.date.today().strftime("%Y-%m-%d")
def display_header(self):
"""Renders the standard UI layout system boundaries."""
print("=========================================================")
print(" OOP Jekyll Blog Post Filename Generator Engine ")
print(" Type 'exit' or 'quit' to terminate. ")
print("=========================================================\n")
def process_input(self, user_input: str) -> bool:
"""
Evaluates input tokens. Returns False if a shutdown token is
received, otherwise processes text parameters and returns True.
"""
cleaned_input = user_input.strip()
if cleaned_input.lower() in ['exit', 'quit']:
print("\nShutdown sequence initiated. Goodbye.")
return False
if not cleaned_input:
return True
# Invoke the aggregated generator service dependency
slug = self.generator.build_slug(cleaned_input)
filename = f"{self.date_prefix}-{slug}.md"
print("-" * 60)
print(f"Target Slug : {slug}")
print(f"Jekyll File : _posts/{filename}")
print("-" * 60 + "\n")
return True
def run(self):
"""Ignites the infinite polling loop execution layer."""
self.display_header()
while True:
try:
raw_input = input("Enter Blog Title -> ")
should_continue = self.process_input(raw_input)
if not should_continue:
break
except (KeyboardInterrupt, EOFError):
print("\n\nProcess interrupted via runtime signal. Exiting safely.")
break
if __name__ == "__main__":
# 1. Instantiate the atomic logic engine worker
slug_engine = SlugGenerator()
# 2. Inject the worker instance dependency straight into the Interface Controller
interface = TerminalInterface(generator=slug_engine)
# 3. Trigger the runtime framework loop
interface.run()
Architectural Mechanisms Breakdown
1. Inversion of Control via Dependency Injection
Rather than allowing the user-facing user interface code to tightly instantiate its own processing blocks, our platform relies on an architectural design pattern known as Dependency Injection (DI):
def __init__(self, generator: SlugGenerator):
self.generator = generator
The TerminalInterface explicitly requires a pre-built SlugGenerator context passed into its constructor. This structural decoupling keeps our business data transformation logic completely separated from user interface constraints—allowing engineers to swap components or run isolated unit tests seamlessly.
2. Multi-Stage Token Cleaning Pipeline
The SlugGenerator transforms raw human titles into clean, web-safe strings through a reliable, multi-step pipeline sequence:
- Lowercase Normalization:
.lower()strips away case differences to ensure URLs remain uniformly formatted. - Punctuation Stripping: A generator compression loop inspects characters, dropping symbols like
!,@, or?based on the configuredpunctuation_maskarray. - Whitespace Tokenization:
.split()collapses irregular gaps or tabs, grouping raw text into clean arrays of string words. - Hyphen Join Construction:
"-".join(tokens)links the isolated words together with standard URL-safe dashes.
3. State Preservation and Caching
The interface class utilizes instance caching to optimize resource consumption. Instead of repeatedly creating datetime instances and hitting kernel time subroutines on every individual user input pass, the system computes and saves the prefix token string (self.date_prefix = ...) once during constructor setup. This keeps string concatenation operations ultra-lean and incredibly efficient inside the endless interactive processing loop.
Verifying the Generation Engine
Launch the tool inside your terminal shell workspace environment to generate valid file names instantly:
python py_jekyll_generator.py
Target Execution Session Simulation Log
=========================================================
OOP Jekyll Blog Post Filename Generator Engine
Type 'exit' or 'quit' to terminate.
=========================================================
Enter Blog Title -> Building a Core REST API Server from Scratch!!
------------------------------------------------------------
Target Slug : building-a-core-rest-api-server-from-scratch
Jekyll File : _posts/2026-06-16-building-a-core-rest-api-server-from-scratch.md
------------------------------------------------------------
Enter Blog Title -> quit
Shutdown sequence initiated. Goodbye.
Upcoming Engineering Sprints
While this utility smoothly automates localized text sanitization, title transformations, and file-naming layouts, it operates as an interactive command-line tool.
To scale this pipeline toward a fully featured static blogging helper, our repository roadmap targets these milestones:
- Automated Hard Disk Workspace Creation: Upgrading the
process_inputmethod to use Python’s built-inossystem modules to automatically write an empty starter Markdown template file inside your local_posts/folder upon text confirmation. - Front Matter Header Generation: Expanding the file builder to inject standard Jekyll metadata syntax blocks (such as YAML front matter like
--- layout: post ---) directly into newly generated post files. - Unicode Diacritic Translation: Integrating a text transformation lookup table to map accent characters across international datasets safely (e.g., automatically converting
"Café"into its web-safe URL token form"cafe").