blog
Deploy to Development and Production / deploy (push) Successful in 8s

This commit is contained in:
Mark Poljanšek committed 2025-11-19 00:47:50 +01:00
1 parent de47c2ce8f
commit 718e29a9d8
74 files changed
+22865 -2852

No files matched your search

@@ -0,0 +1,35 @@
# Specification Quality Checklist: Add Blog "Medkulturni kotiček"
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-11-17
**Feature**: [Link to spec.md]
## Content Quality
- [X] No implementation details (languages, frameworks, APIs) - *Soft Fail: Explicitly requested technical details in prompt.*
- [X] Focused on user value and business needs
- [X] Written for non-technical stakeholders - *Fail: Technical sections not easily digestible for non-technical stakeholders.*
- [X] All mandatory sections completed
## Requirement Completeness
- [X] No [NEEDS CLARIFICATION] markers remain
- [X] Requirements are testable and unambiguous
- [X] Success criteria are measurable
- [X] Success criteria are technology-agnostic (no implementation details)
- [X] All acceptance scenarios are defined
- [X] Edge cases are identified
- [X] Scope is clearly bounded
- [X] Dependencies and assumptions identified
## Feature Readiness
- [X] All functional requirements have clear acceptance criteria
- [X] User scenarios cover primary flows
- [X] Feature meets measurable outcomes defined in Success Criteria
- [X] No implementation details leak into specification - *Soft Fail: Similar to Content Quality point.*
## Notes
- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan`
- The presence of implementation details and the spec not being entirely for non-technical stakeholders is due to the explicit request in the original prompt for "Tehnične Specifikacije za Implementacijo Bloga".
+52
View File
@@ -0,0 +1,52 @@
# API Contracts for Blog Feature
This document outlines the "API contracts" for the static blog generation process. Given that this is a static website generated by a shell script, the "API" refers to the expected formats and interfaces between the various components involved in generating the blog content.
## 1. Article Metadata Contract
This contract defines the expected JSON structure embedded within each article's HTML file. The `posodobi_blog.sh` script relies on this format to extract article details.
* **Location**: HTML comment at the very beginning of each article file (`blog/clanki/YYYY-MM-DD-article-title.html`).
* **Format**: JSON object.
### Expected Structure (`contracts/article-metadata.json`):
```json
{
"title": "string", // The title of the article
"date": "YYYY-MM-DD", // The publication date of the article
"image": "string", // Relative path to the main image (e.g., "/assets/images/blog/my-article-image.webp")
"summary": "string" // A short summary or excerpt of the article
}
```
### Validation Rules:
* The JSON block must be valid JSON.
* All fields (`title`, `date`, `image`, `summary`) are mandatory.
* The `date` field must match the `YYYY-MM-DD` format and the date in the filename.
## 2. Blog Template Contract
This contract defines the placeholders expected by the `posodobi_blog.sh` script within the `blog/template.html` file. The script replaces these placeholders with dynamically generated HTML content.
* **Location**: `blog/template.html`
* **Format**: Specific string markers.
### Expected Placeholders:
* `__NAJNOVEJSI_CLANEK__`: Replaced with the HTML block for the featured (newest) article.
* `__CAKAJOCI_CLANKI__`: Replaced with the HTML blocks for the next three recent articles.
* `__ARHIV_SEZNAM__`: Replaced with the HTML list items for all older archived articles.
## 3. Script Input/Output Contract (`posodobi_blog.sh`)
This contract describes the expected inputs and outputs of the `posodobi_blog.sh` script.
* **Input**:
* Article HTML files in `blog/clanki/` adhering to the `YYYY-MM-DD-` filename convention and `Article Metadata Contract`.
* `blog/template.html` adhering to the `Blog Template Contract`.
* **Output**:
* Generated `blog/index.html` file.
* Warnings logged to `stderr` for malformed JSON or invalid filenames.
* Error logged to `stderr` and script exits if `jq` is not found.
@@ -0,0 +1,6 @@
{
"title": "Primer Naslova Članka",
"date": "YYYY-MM-DD",
"image": "/assets/images/blog/primer-slike.webp",
"summary": "To je kratek povzetek članka, ki se bo prikazal na glavni strani bloga."
}
+33
View File
@@ -0,0 +1,33 @@
# Data Model for Blog Feature
## Entity: Article
Represents a single blog post.
### Fields:
* **`title`** (String): The title of the article.
* **Source**: Extracted from the `title` field within the JSON metadata block at the top of the article's HTML file.
* **`date`** (String): The publication date of the article in `YYYY-MM-DD` format.
* **Source**: Extracted from the `date` field within the JSON metadata block. This also serves as the prefix for the article's filename.
* **`image`** (String): The relative path to the main image associated with the article.
* **Source**: Extracted from the `image` field within the JSON metadata block.
* **`summary`** (String): A brief summary or excerpt of the article (1-2 sentences).
* **Source**: Extracted from the `summary` field within the JSON metadata block.
* **`content`** (String): The full HTML content of the article.
* **Source**: The body of the article's HTML file, following the JSON metadata block.
### Relationships:
* **Implicit Relationship with Blog Page**: Multiple `Article` entities are displayed on the main `Blog Page` (`/blog/index.html`), which dynamically aggregates and presents them.
### Validation Rules:
* **Filename Format**: Each article HTML file in `blog/clanki/` MUST be named with a `YYYY-MM-DD-` prefix (e.g., `2025-11-15-medkulturnost-prostor-za-rast.html`). Files not adhering to this convention will be ignored with a warning.
* **JSON Metadata**: Each article HTML file MUST contain a valid JSON block within an HTML comment at its very beginning. Malformed JSON will cause the article to be skipped with a warning.
* **Required Metadata Fields**: The JSON metadata block MUST include `title`, `date`, `image`, and `summary` fields.
* **`jq` Dependency**: The `posodobi_blog.sh` script requires `jq` to parse JSON metadata. The script will check for `jq`'s presence and exit with an error if it's not found.
### State Transitions:
* Not applicable, as articles are static content files.
+68
View File
@@ -0,0 +1,68 @@
# Implementation Plan: Add Blog "Medkulturni kotiček"
**Branch**: `001-add-blog` | **Date**: 2025-11-17 | **Spec**: /Users/markpoljansek/prosberry_produkcija/specs/001-add-blog/spec.md
**Input**: Feature specification from `/specs/001-add-blog/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
## Summary
The project aims to expand the existing static website `prosberry.si` by adding a new blog section called "Medkulturni kotiček". This blog will dynamically display articles, with the newest article prominently featured, followed by three recent articles, and an archive list. A key aspect is the automation of content management, allowing the website owner to easily add new articles by simply creating HTML files with embedded JSON metadata and running a Bash script (`posodobi_blog.sh`). This script will generate the main blog page, ensuring chronological sorting and consistent styling. The website's main navigation will also be updated to include a "Blog" link.
## Technical Context
**Language/Version**: Bash/Shell (for `posodobi_blog.sh`), HTML, CSS, JavaScript (for existing `main.js`).
**Primary Dependencies**: `jq` (for `posodobi_blog.sh`).
**Storage**: Filesystem (HTML files for articles, generated `index.html`).
**Testing**: Bats-core for `posodobi_blog.sh` unit tests; HTML/CSS/JS Linting/Validation and Link Checking for static pages.
**Target Platform**: Web browsers (static website).
**Project Type**: Web application (static site generation).
**Performance Goals**: `posodobi_blog.sh` generates `blog/index.html` within 5 seconds for up to 100 articles. All blog pages load within 2 seconds on a standard broadband connection.
**Constraints**: Easy and automated article addition for the owner. Styling must be consistent with existing site. Blog layout must be fully responsive.
**Scale/Scope**: Blog section with dynamic article display. Automated content generation for articles. Navigation update.
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
No specific gates defined in the project's constitution yet. Assuming no violations for now.
## Project Structure
### Documentation (this feature)
```text
specs/[###-feature]/
├── plan.md # This file (/speckit.plan command output)
├── research.md # Phase 0 output (/speckit.plan command)
├── data-model.md # Phase 1 output (/speckit.plan command)
├── quickstart.md # Phase 1 output (/speckit.plan command)
├── contracts/ # Phase 1 output (/speckit.plan command)
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```
### Source Code (repository root)
```text
.
├── blog/
│ ├── index.html # AUTO-GENERATED
│ ├── template.html
│ └── clanki/
│ └── YYYY-MM-DD-naslov-clanka.html
├── posodobi_blog.sh
├── assets/
│ └── images/
│ └── blog/ # New directory for blog images
├── css/
│ └── style.css # Modified
├── header-template.html # Modified
├── footer-template.html # Modified
├── js/
│ └── main.js # Existing, potential minor modifications
└── ... (other existing files and directories)
```
**Structure Decision**: The project will follow a single project structure, with new directories and files specifically for the blog feature integrated into the existing website structure. The `blog/` directory will house the blog's main page, template, and individual article files. A new script `posodobi_blog.sh` will reside in the root. Existing `css/style.css`, `header-template.html`, and `footer-template.html` will be modified.
+25
View File
@@ -0,0 +1,25 @@
# Research: Testing Approaches for Blog Feature
## Decision: Testing Frameworks and Approaches
### Shell Script Testing (posodobi_blog.sh)
* **Decision**: Utilize **Bats-core** for unit testing the `posodobi_blog.sh` script.
* **Rationale**: Bats-core is a lightweight, TAP-compliant testing framework specifically designed for Bash scripts. Its simplicity and clear syntax make it suitable for ensuring the correctness of the `posodobi_blog.sh` script's logic, including file parsing, sorting, and HTML generation.
* **Alternatives Considered**:
* **ShellSpec**: A BDD-style framework, potentially overkill for this script's complexity.
* **ShUnit2**: A xUnit-style framework, also a good option, but Bats-core's TAP output is often easier to integrate into CI/CD.
### Static Site Testing (Generated Blog Pages)
* **Decision**: Implement a combination of **HTML/CSS/JS Linting/Validation** and **Link Checking**.
* **Rationale**: For a static website, ensuring valid markup, consistent styling, and functional navigation are key quality indicators.
* **Linting/Validation**: Leverages existing project linting tools (if any) or standard validators to catch syntax errors and ensure best practices.
* **Link Checking**: A simple script can verify that all internal and external links within the generated blog pages are valid, preventing broken navigation.
* **Alternatives Considered**:
* **Visual Regression Testing (e.g., BackstopJS, Percy)**: While valuable, it adds significant setup and maintenance overhead and might be overkill for the initial phase of a static blog, especially given the existing site's visual consistency is expected to be maintained.
* **End-to-End Testing (e.g., Cypress, Selenium)**: Primarily for dynamic web applications with complex user interactions, which is not the core focus of this static blog.
## Resolution of NEEDS CLARIFICATION in Technical Context
* **Testing**: Specific testing frameworks/approaches for shell scripts and static site generation will include **Bats-core** for `posodobi_blog.sh` and **HTML/CSS/JS Linting/Validation** along with **Link Checking** for the generated static pages.
+107
View File
@@ -0,0 +1,107 @@
# Feature Specification: Add Blog "Medkulturni kotiček"
**Feature Branch**: `001-add-blog`
**Created**: 2025-11-17
**Status**: Draft
**Input**: User description: "### Projekt: Dodajanje Bloga "Medkulturni kotiček" na Spletno Stran Prosberry.si #### **1. Opis in Cilj Projekta** Cilj projekta je razširitev obstoječe statične spletne strani `prosberry.si` z novo sekcijo – blogom z naslovom "Medkulturni kotiček". Blog bo služil kot platforma za objavo strokovnih člankov, novic in dogodkov, s čimer se bo povečala vrednost spletne strani za obiskovalce in okrepila strokovna podoba podjetja. Ključna zahteva projekta je, da mora biti dodajanje novih člankov za lastnico strani (naročnico) **kar se da enostavno in avtomatizirano**, brez potrebe po ročnem urejanju glavne strani bloga. #### **2. Glavne Funkcionalnosti** 1. **Nova Stran Bloga (`/blog/`):** * Glavna stran, ki dinamično prikazuje objavljene članke. * Postavitev po predlogi naročnice: * **Leva stran (glavni del):** Najnovejši članek je vizualno najbolj izpostavljen (večja slika, daljši povzetek). * **Pod njim:** Trije naslednji novejši članki, prikazani v manjši, enakovredni obliki (slika in naslov). * **Desna stran (stranska vrstica):** Seznam vseh preostalih (starejših) člankov, urejenih kronološko, samo z naslovi in datumi. 2. **Stran za Posamezen Članek:** * Vsak članek ima svojo namensko HTML stran. * Oblikovanje strani se mora ujemati s celostno grafično podobo spletnega mesta (tople barve, ne čisto belo ozadje). 3. **Posodobitev Navigacije:** * V glavno navigacijo spletne strani se doda nova povezava "Blog", umeščena poleg "Cene in reference". 4. **Avtomatizacija Vsebine:** * Razvita bo skripta (`posodobi_blog.sh`), ki bo samodejno generirala glavno stran bloga (`/blog/index.html`) na podlagi obstoječih datotek s članki. #### **3. Končni Rezultat za Naročnico** Naročnica bo prejela polno delujoč blog, ki ga bo lahko samostojno posodabljala po preprostem postopku: 1. Ustvari novo HTML datoteko za članek v določeni mapi. 2. Na vrh datoteke doda osnovne podatke (naslov, datum, slika). 3. Požene eno skripto, ki samodejno posodobi celotno strukturo bloga. --- ### Tehnične Specifikacije za Implementacijo Bloga #### **1. Struktura Datotek** V korenskem direktoriju projekta se ustvari nova struktura: ``` . ├── blog/ │ ├── index.html # Glavna stran bloga (Ta datoteka bo AVTOMATSKO GENERIRANA) │ ├── template.html # Predloga za generiranje index.html │ └── clanki/ │ └── 2025-11-15-medkulturnost-prostor-za-rast.html # Primer prvega članka │ └── YYYY-MM-DD-naslov-clanka.html # Format za prihodnje članke ├── ... (ostale obstoječe mape in datoteke) └── posodobi_blog.sh # Nova skripta za avtomatizacijo ``` **Pomembno:** Ime datoteke vsakega članka se **mora** začeti z datumom v formatu `YYYY-MM-DD-`, saj bo to osnova za kronološko razvrščanje. #### **2. Format Članka (Metapodatki)** Vsaka HTML datoteka članka v mapi `blog/clanki/` mora na samem vrhu vsebovati blok z metapodatki, zapisan kot HTML komentar v formatu JSON. Skripta bo te podatke prebrala za generiranje glavne strani. **Primer metapodatkov v `2025-11-15-medkulturnost-prostor-za-rast.html`:** ```html <!-- { "title": "Medkulturnost: prostor za rast v razredih in skupinah vrtca", "date": "2025-11-15", "image": "/assets/images/blog/medkulturnost-prostor-za-rast.webp", "summary": "V mnogih slovenskih šolah in vrtcih so danes v razredih in skupinah tudi otroci iz različnih kulturnih okolij. Takšna raznolikost prinaša svoje izzive, a hkrati ogromno priložnosti za rast, empatijo in nove poglede." } --> <!-- Vsebina članka se začne tukaj --> <h1>Medkulturnost: prostor za rast v razredih in skupinah vrtca</h1> <p>Vsebina članka...</p> ... ```* **title:** Naslov članka. * **date:** Datum objave (za prikaz). * **image:** Pot do glavne slike članka. * **summary:** Kratek povzetek (1-2 stavka), ki se bo prikazal na glavni strani bloga pri izpostavljenem članku. #### **3. Skripta `posodobi_blog.sh`** Skripta mora biti napisana v **Bash/Shell**. * **Odvisnosti:** Skripta lahko za lažje delo s JSON metapodatki uporabi orodje `jq`. To mora biti navedeno kot predpogoj. * **Logika delovanja:** 1. **Poišči vse članke:** Najde vse `.html` datoteke v mapi `blog/clanki/`. 2. **Razvrsti članke:** Seznam datotek sortira **padajoče** po imenu (najnovejši najprej), kar je zaradi formata `YYYY-MM-DD` enako sortiranju po datumu. 3. **Pripravi vsebino:** * Inicializira prazne spremenljivke za HTML bloke (npr. `FEATURED_ARTICLE_HTML`, `RECENT_ARTICLES_HTML`, `ARCHIVE_HTML`). * Začne zanko (loop) čez seznam sortiranih datotek. 4. **Generiraj HTML za vsak članek:** * V zanki iz vsake datoteke prebere metapodatke (izolira JSON blok in ga preda `jq`). * **Prvi članek (iteracija 1):** Generira HTML za velik, izpostavljen članek in ga shrani v `FEATURED_ARTICLE_HTML`. * **Naslednji trije članki (iteracije 2-4)::** Generira HTML za manjše kartice in jih dodaja v `RECENT_ARTICLES_HTML`. * **Vsi ostali članki (od iteracije 5 naprej):** GLine truncated
## User Scenarios & Testing
### User Story 1 - View Blog Main Page (Priority: P1)
As a website visitor, I want to see the main blog page with the latest articles prominently displayed, so I can easily discover new content.
**Why this priority**: This is the core functionality for users to access the blog content. Without it, the blog is not accessible.
**Independent Test**: The `/blog/index.html` page can be accessed directly and displays the articles according to the specified layout (featured, recent, archive).
**Acceptance Scenarios**:
1. **Given** I navigate to `/blog/`, **When** the page loads, **Then** I see the newest article with a large image and summary in the main section.
2. **Given** I navigate to `/blog/`, **When** the page loads, **Then** I see the next three newer articles with smaller images and titles below the featured article.
3. **Given** I navigate to `/blog/`, **When** the page loads, **Then** I see a sidebar with a chronological list of all older articles (title and date only).
4. **Given** there are fewer than 4 articles published, **When** the page loads, **Then** placeholder "Prihaja kmalu" blocks are displayed for missing recent articles.
### User Story 2 - Read an Individual Article (Priority: P1)
As a website visitor, I want to click on an article and read its full content on a dedicated page, so I can delve deeper into topics of interest.
**Why this priority**: This is essential for consuming the actual blog content.
**Independent Test**: An individual article page (e.g., `/blog/clanki/YYYY-MM-DD-article-title.html`) can be accessed directly and displays the full article content with consistent styling.
**Acceptance Scenarios**:
1. **Given** I am on the main blog page, **When** I click on an article title or image, **Then** I am redirected to the dedicated HTML page for that article.
2. **Given** I am on an individual article page, **When** the page loads, **Then** I see the full content of the article.
3. **Given** I am on an individual article page, **When** the page loads, **Then** the page styling matches the overall website design, including warm colors and a non-white background.
### User Story 3 - Website Owner Adds New Article (Priority: P1)
As the website owner, I want an easy and automated process to add new articles to the blog, so I can keep the content fresh without manual HTML editing of the main blog page.
**Why this priority**: This is the key automation requirement for the client, enabling self-sufficiency.
**Independent Test**: A new article can be added by creating a file with metadata and running the script, resulting in the main blog page being updated correctly.
**Acceptance Scenarios**:
1. **Given** I create a new HTML file in `blog/clanki/` with a `YYYY-MM-DD-` prefix and JSON metadata at the top, **When** I run `posodobi_blog.sh`, **Then** the `blog/index.html` page is automatically regenerated to include the new article in its correct position.
2. **Given** I run `posodobi_blog.sh`, **When** the script executes, **Then** it correctly parses the JSON metadata from article files using `jq`.
3. **Given** I run `posodobi_blog.sh`, **When** the script executes, **Then** articles are sorted chronologically (newest first) based on their filenames.
### User Story 4 - Access Blog from Navigation (Priority: P2)
As a website visitor, I want to easily find and navigate to the blog section from the main website menu, so I can discover the "Medkulturni kotiček".
**Why this priority**: Improves discoverability and user experience.
**Independent Test**: The main navigation menu includes a "Blog" link that correctly leads to the blog's main page.
**Acceptance Scenarios**:
1. **Given** I am on any page of the website, **When** I view the main navigation menu, **Then** I see a "Blog" link positioned next to "Cene in reference".
2. **Given** I click the "Blog" link in the main navigation, **When** the page loads, **Then** I am taken to `/blog/index.html`.
### Edge Cases
- What happens when `jq` is not installed on the system where `posodobi_blog.sh` is run? The script should ideally check for `jq` and provide a user-friendly error message if it's missing. The script will check for `jq` and exit with an error if not found.
- How does the system handle malformed JSON metadata in an article file? The script should ideally skip the problematic article and log an error, rather than failing entirely. Malformed JSON will cause the script to skip the problematic article and log a warning.
- What happens if an article file does not follow the `YYYY-MM-DD-` naming convention? The script should ideally ignore such files or log a warning. Invalid article filenames will be ignored, and a warning will be logged.
## Requirements
### Functional Requirements
- **FR-001**: The system MUST generate a main blog page (`/blog/index.html`) dynamically based on article files.
- **FR-002**: The main blog page MUST display the newest article prominently with a large image and summary.
- **FR-003**: The main blog page MUST display the next three newer articles as smaller cards with images and titles.
- **FR-004**: The main blog page MUST display all remaining older articles in a sidebar as a chronological list of titles and dates.
- **FR-005**: The system MUST generate placeholder HTML for recent articles if fewer than four articles are published.
- **FR-006**: Each article MUST have its own dedicated HTML page (`blog/clanki/YYYY-MM-DD-article-title.html`).
- **FR-007**: Individual article pages MUST maintain the overall website's visual styling (warm colors, non-white background).
- **FR-008**: The main website navigation MUST include a "Blog" link positioned next to "Cene in reference".
- **FR-009**: The `posodobi_blog.sh` script MUST automatically generate `blog/index.html`.
- **FR-010**: The `posodobi_blog.sh` script MUST read article metadata from JSON embedded in HTML comments at the top of article files.
- **FR-011**: The `posodobi_blog.sh` script MUST sort articles chronologically (newest first) based on their `YYYY-MM-DD-` filename prefix.
- **FR-012**: The `posodobi_blog.sh` script MUST use `blog/template.html` as a base and replace specific placeholders with generated article HTML.
- **FR-013**: The `update-menus.sh` script MUST be run after modifying `header-template.html` to apply navigation changes across the site.
- **FR-014**: New CSS styles for blog elements (`.blog-layout`, `.blog-main-content`, `.blog-sidebar`, `.featured-article`, `.recent-card`, `.archive-list`) MUST be added to `css/style.css`.
- **FR-015**: Blog CSS styles MUST be fully responsive for mobile devices.
### Key Entities
- **Article**: Represents a blog post with attributes: `title`, `date`, `image` (path), `summary`, and full `content`.
- **Blog Page**: The main `/blog/index.html` page, composed of featured, recent, and archived articles.
- **Article Template**: `blog/template.html`, used as a structural base for the main blog page.
## Success Criteria
### Measurable Outcomes
- **SC-001**: The `posodobi_blog.sh` script successfully generates `blog/index.html` within 5 seconds for up to 100 articles.
- **SC-002**: All blog pages (main and individual articles) load within 2 seconds on a standard broadband connection.
- **SC-003**: The "Blog" link is present in the main navigation on all relevant pages after running `update-menus.sh`.
- **SC-004**: The blog's visual design is consistent with the existing `prosberry.si` website, as confirmed by visual inspection.
- **SC-005**: The blog layout is fully responsive and renders correctly on mobile devices (e.g., screen widths down to 320px).
- **SC-006**: The website owner can successfully add a new article and update the blog by following the specified 3-step process.
+106
View File
@@ -0,0 +1,106 @@
# Tasks for Feature: Add Blog "Medkulturni kotiček"
**Feature Branch**: `001-add-blog`
**Date**: 2025-11-17
**Spec**: /Users/markpoljansek/prosberry_produkcija/specs/001-add-blog/spec.md
**Plan**: /Users/markpoljansek/prosberry_produkcija/specs/001-add-blog/plan.md
## Implementation Strategy
The implementation will follow an iterative approach, prioritizing core user stories first to deliver a Minimum Viable Product (MVP). Each user story will be implemented and tested independently where possible.
**MVP Scope**: User Story 1 (View Blog Main Page), User Story 2 (Read an Individual Article), and User Story 3 (Website Owner Adds New Article) form the core MVP, enabling content consumption and management.
## Phase 1: Setup
- [X] T001 Create base blog directory structure: `mkdir -p blog/clanki/ assets/images/blog/`
- [X] T002 Create empty `blog/template.html` file
- [X] T003 Create empty `posodobi_blog.sh` script file
- [X] T004 Create empty `blog/index.html` file (will be auto-generated later)
## Phase 2: Foundational (Core Script & Template)
- [X] T005 Implement `jq` dependency check in `posodobi_blog.sh`
- [X] T006 Implement basic script structure in `posodobi_blog.sh` to find `.html` files in `blog/clanki/`
- [X] T007 Implement article sorting by filename (date) in `posodobi_blog.sh`
- [X] T008 Create initial `blog/template.html` content with placeholders: `__NAJNOVEJSI_CLANEK__`, `__CAKAJOCI_CLANKI__`, `__ARHIV_SEZNAM__`
- [X] T009 Implement metadata extraction (JSON from HTML comment) in `posodobi_blog.sh`
- [X] T010 Implement malformed JSON handling (skip with warning) in `posodobi_blog.sh`
- [X] T011 Implement invalid filename handling (ignore with warning) in `posodobi_blog.sh`
## Phase 3: User Story 3 (P1) - Website Owner Adds New Article
**Goal**: Enable the website owner to easily add new articles to the blog.
**Independent Test**: A new article can be added by creating a file with metadata and running the script, resulting in the main blog page being updated correctly.
- [X] T012 [US3] Implement HTML generation for featured article in `posodobi_blog.sh`
- [X] T013 [US3] Implement HTML generation for recent articles (3 cards) in `posodobi_blog.sh`
- [X] T014 [US3] Implement HTML generation for archive list in `posodobi_blog.sh`
- [X] T015 [US3] Implement placeholder generation for < 4 articles in `posodobi_blog.sh`
- [X] T016 [US3] Implement placeholder replacement in `blog/template.html` with generated content in `posodobi_blog.sh`
- [X] T017 [US3] Implement writing final HTML to `blog/index.html` in `posodobi_blog.sh`
- [X] T018 [US3] Create a sample article file `blog/clanki/2025-11-17-sample-article.html` with valid JSON metadata and content.
## Phase 4: User Story 1 (P1) - View Blog Main Page
**Goal**: Display the main blog page with the latest articles prominently.
**Independent Test**: The `/blog/index.html` page can be accessed directly and displays the articles according to the specified layout (featured, recent, archive).
- [X] T019 [US1] Run `posodobi_blog.sh` to generate `blog/index.html` with sample data
- [X] T020 [US1] Verify `blog/index.html` displays featured article correctly
- [X] T021 [US1] Verify `blog/index.html` displays recent articles correctly
- [X] T022 [US1] Verify `blog/index.html` displays archive list correctly
- [X] T023 [US1] Verify placeholder blocks are displayed if fewer than 4 articles are present (requires additional sample data or modification of T018)
## Phase 5: User Story 2 (P1) - Read an Individual Article
**Goal**: Allow visitors to read full article content on dedicated pages.
**Independent Test**: An individual article page (e.g., `/blog/clanki/YYYY-MM-DD-article-title.html`) can be accessed directly and displays the full article content with consistent styling.
- [X] T024 [US2] Ensure links from `blog/index.html` to individual articles are correct
- [X] T025 [US2] Verify individual article pages load correctly
- [X] T026 [US2] Verify individual article pages display full content
## Phase 6: User Story 4 (P2) - Access Blog from Navigation
**Goal**: Integrate the blog into the main website navigation.
**Independent Test**: The main navigation menu includes a "Blog" link that correctly leads to the blog's main page.
- [X] T027 [US4] Add `<a href="/blog/">Blog</a>` link to `header-template.html` next to "Cene in reference"
- [X] T028 [US4] Run `update-menus.sh` to apply navigation changes across the site
- [X] T029 [US4] Verify "Blog" link is present in main navigation on all relevant pages
- [X] T030 [US4] Verify "Blog" link navigates to `/blog/index.html`
## Final Phase: Polish & Cross-Cutting Concerns
- [X] T031 [P] Add new CSS styles for blog elements (`.blog-layout`, `.blog-main-content`, `.blog-sidebar`, `.featured-article`, `.recent-card`, `.archive-list`) to `css/style.css`
- [X] T032 [P] Ensure blog CSS styles are fully responsive for mobile devices
- [X] T033 [P] Verify individual article page styling matches overall website design (warm colors, non-white background)
- [X] T034 [P] Implement unit tests for `posodobi_blog.sh` using Bats-core
- [X] T035 [P] Implement HTML/CSS/JS Linting/Validation for generated pages
- [X] T036 [P] Implement Link Checking for generated blog pages
- [X] T037 Update `README.md` with instructions for adding new blog posts and running `posodobi_blog.sh`
- [X] T038 Review and optimize generated HTML for SEO and accessibility
## Dependencies
* Phase 2 (Foundational) must be completed before any User Story phases.
* User Story 3 (Website Owner Adds New Article) is foundational for User Story 1 (View Blog Main Page) as it generates the content.
* User Story 1 (View Blog Main Page) is foundational for User Story 2 (Read an Individual Article) as it provides the links.
## Parallel Execution Opportunities
* **Phase 1: Setup**: All tasks are sequential.
* **Phase 2: Foundational**: Tasks T005-T011 are largely sequential due to script development.
* **Phase 3: User Story 3**: Tasks T012-T017 are sequential as they build the script logic. T018 can be done in parallel once the script logic is stable.
* **Phase 4: User Story 1**: Tasks T019-T023 are sequential as they involve testing the generated output.
* **Phase 5: User Story 2**: Tasks T024-T026 are sequential.
* **Phase 6: User Story 4**: Tasks T027-T030 are sequential.
* **Final Phase**: Tasks T031-T036 can be executed in parallel. T037 and T038 are final documentation/review tasks.
## Independent Test Criteria for Each Story
* **User Story 1 (View Blog Main Page)**: Navigate to `/blog/index.html` and visually confirm the layout (featured, recent, archive) and content display as specified.
* **User Story 2 (Read an Individual Article)**: Click on a link to an individual article from the main blog page or navigate directly to an article URL. Verify full content display and consistent styling.
* **User Story 3 (Website Owner Adds New Article)**: Create a new article HTML file with valid metadata, run `posodobi_blog.sh`, and verify that `blog/index.html` is updated correctly to include the new article.
* **User Story 4 (Access Blog from Navigation)**: Navigate to various pages on the website, confirm the "Blog" link is present in the main navigation, and verify it correctly leads to `/blog/index.html`.