diff --git a/astro.config.mjs b/astro.config.mjs
index ab6552d..31edf62 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -7,7 +7,7 @@ import tailwind from '@astrojs/tailwind';
// https://astro.build/config
export default defineConfig({
- site: 'https://laforceit.blog',
+ site: 'https://laforceit-blog.pages.dev', // Your current Cloudflare site
output: 'static',
// adapter: cloudflare(), // Commented out for local development
integrations: [
@@ -17,10 +17,14 @@ export default defineConfig({
],
markdown: {
shikiConfig: {
- theme: 'dracula',
+ theme: 'one-dark-pro',
wrap: true
},
remarkPlugins: [],
rehypePlugins: []
+ },
+ compressHTML: false, // Disable HTML compression to avoid parsing errors
+ build: {
+ format: 'file', // Use 'file' instead of 'directory' format
}
});
\ No newline at end of file
diff --git a/src/components/Header.astro b/src/components/Header.astro
index 1313894..cd066a7 100644
--- a/src/components/Header.astro
+++ b/src/components/Header.astro
@@ -379,12 +379,13 @@ const navItems = [
\ No newline at end of file
diff --git a/src/content/blog/getting-started.md b/src/content/blog/getting-started.md
new file mode 100644
index 0000000..80629d7
--- /dev/null
+++ b/src/content/blog/getting-started.md
@@ -0,0 +1,65 @@
+---
+title: 'Getting Started with Infrastructure as Code'
+description: 'Learn the basics of Infrastructure as Code and how to start using it in your projects.'
+pubDate: '2023-11-15'
+heroImage: '/images/placeholders/infrastructure.jpg'
+categories: ['Infrastructure', 'DevOps']
+tags: ['terraform', 'infrastructure', 'cloud', 'automation']
+minutesRead: '5 min'
+---
+
+# Getting Started with Infrastructure as Code
+
+Infrastructure as Code (IaC) is a key DevOps practice that involves managing and provisioning infrastructure through code instead of manual processes. This approach brings the same rigor, transparency, and version control to infrastructure that developers have long applied to application code.
+
+## Why Infrastructure as Code?
+
+IaC offers numerous benefits for modern DevOps teams:
+
+- **Consistency**: Infrastructure deployments become reproducible and standardized
+- **Version Control**: Track changes to your infrastructure just like application code
+- **Automation**: Reduce manual errors and increase deployment speed
+- **Documentation**: Your code becomes self-documenting
+- **Testing**: Infrastructure can be tested before deployment
+
+## Popular IaC Tools
+
+There are several powerful tools for implementing IaC:
+
+1. **Terraform**: Cloud-agnostic, works with multiple providers
+2. **AWS CloudFormation**: Specific to AWS infrastructure
+3. **Azure Resource Manager**: Microsoft's native IaC solution
+4. **Google Cloud Deployment Manager**: For Google Cloud resources
+5. **Pulumi**: Uses general-purpose programming languages
+
+## Basic Terraform Example
+
+Here's a simple example of Terraform code that provisions an AWS EC2 instance:
+
+```hcl
+provider "aws" {
+ region = "us-west-2"
+}
+
+resource "aws_instance" "web_server" {
+ ami = "ami-0c55b159cbfafe1f0"
+ instance_type = "t2.micro"
+
+ tags = {
+ Name = "Web Server"
+ Environment = "Development"
+ }
+}
+```
+
+## Getting Started
+
+To begin your IaC journey:
+
+1. Choose a tool that fits your infrastructure needs
+2. Start small with a simple resource
+3. Learn about state management
+4. Implement CI/CD for your infrastructure code
+5. Consider using modules for reusability
+
+Infrastructure as Code transforms how teams provision and manage resources, enabling more reliable, consistent deployments while reducing overhead and errors.
\ No newline at end of file
diff --git a/src/content/config.ts b/src/content/config.ts
index 15fec0b..7dd588e 100644
--- a/src/content/config.ts
+++ b/src/content/config.ts
@@ -39,6 +39,16 @@ const baseSchema = z.object({
pubDate: z.union([z.string(), z.date(), z.null()]).optional().default(() => new Date()).transform(customDateParser),
updatedDate: z.union([z.string(), z.date(), z.null()]).optional().transform(val => val ? customDateParser(val) : undefined),
heroImage: z.string().optional().nullable(),
+ // Add categories array that falls back to the single category field
+ categories: z.union([
+ z.array(z.string()),
+ z.string().transform(val => [val]),
+ z.null()
+ ]).optional().transform(val => {
+ if (val === null || val === undefined) return ['Uncategorized'];
+ return val;
+ }),
+ // Keep the original category field for backward compatibility
category: z.string().optional().default('Uncategorized'),
tags: z.union([z.array(z.string()), z.null()]).optional().default([]),
draft: z.boolean().optional().default(false),
@@ -49,7 +59,14 @@ const baseSchema = z.object({
github: z.string().optional(),
live: z.string().optional(),
technologies: z.array(z.string()).optional(),
-}).passthrough(); // Allow any other frontmatter properties
+}).passthrough() // Allow any other frontmatter properties
+ .transform(data => {
+ // If categories isn't set but category is, use category value to populate categories
+ if ((!data.categories || data.categories.length === 0) && data.category) {
+ data.categories = [data.category];
+ }
+ return data;
+ });
// Define collections using the same base schema
const postsCollection = defineCollection({
diff --git a/src/content/posts/getting-started.md b/src/content/posts/getting-started.md
new file mode 100644
index 0000000..80629d7
--- /dev/null
+++ b/src/content/posts/getting-started.md
@@ -0,0 +1,65 @@
+---
+title: 'Getting Started with Infrastructure as Code'
+description: 'Learn the basics of Infrastructure as Code and how to start using it in your projects.'
+pubDate: '2023-11-15'
+heroImage: '/images/placeholders/infrastructure.jpg'
+categories: ['Infrastructure', 'DevOps']
+tags: ['terraform', 'infrastructure', 'cloud', 'automation']
+minutesRead: '5 min'
+---
+
+# Getting Started with Infrastructure as Code
+
+Infrastructure as Code (IaC) is a key DevOps practice that involves managing and provisioning infrastructure through code instead of manual processes. This approach brings the same rigor, transparency, and version control to infrastructure that developers have long applied to application code.
+
+## Why Infrastructure as Code?
+
+IaC offers numerous benefits for modern DevOps teams:
+
+- **Consistency**: Infrastructure deployments become reproducible and standardized
+- **Version Control**: Track changes to your infrastructure just like application code
+- **Automation**: Reduce manual errors and increase deployment speed
+- **Documentation**: Your code becomes self-documenting
+- **Testing**: Infrastructure can be tested before deployment
+
+## Popular IaC Tools
+
+There are several powerful tools for implementing IaC:
+
+1. **Terraform**: Cloud-agnostic, works with multiple providers
+2. **AWS CloudFormation**: Specific to AWS infrastructure
+3. **Azure Resource Manager**: Microsoft's native IaC solution
+4. **Google Cloud Deployment Manager**: For Google Cloud resources
+5. **Pulumi**: Uses general-purpose programming languages
+
+## Basic Terraform Example
+
+Here's a simple example of Terraform code that provisions an AWS EC2 instance:
+
+```hcl
+provider "aws" {
+ region = "us-west-2"
+}
+
+resource "aws_instance" "web_server" {
+ ami = "ami-0c55b159cbfafe1f0"
+ instance_type = "t2.micro"
+
+ tags = {
+ Name = "Web Server"
+ Environment = "Development"
+ }
+}
+```
+
+## Getting Started
+
+To begin your IaC journey:
+
+1. Choose a tool that fits your infrastructure needs
+2. Start small with a simple resource
+3. Learn about state management
+4. Implement CI/CD for your infrastructure code
+5. Consider using modules for reusability
+
+Infrastructure as Code transforms how teams provision and manage resources, enabling more reliable, consistent deployments while reducing overhead and errors.
\ No newline at end of file
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
index 0cf6737..d2f843b 100644
--- a/src/layouts/BaseLayout.astro
+++ b/src/layouts/BaseLayout.astro
@@ -23,6 +23,18 @@ const {
{title}
+
+
+
@@ -44,6 +56,9 @@ const {
+
+
+
diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro
index 48a119f..74b48bb 100644
--- a/src/pages/blog/[slug].astro
+++ b/src/pages/blog/[slug].astro
@@ -1,38 +1,264 @@
---
-import { getCollection, getEntryBySlug } from 'astro:content';
-import BlogPost from '../../layouts/BlogPost.astro';
+// src/pages/blog/[slug].astro
+import { getCollection } from 'astro:content';
+import BaseLayout from '../../layouts/BaseLayout.astro';
+// Required getStaticPaths function for dynamic routes
export async function getStaticPaths() {
- const posts = await getCollection('blog');
- return posts.map(post => ({
- params: { slug: post.slug },
- props: { post },
- }));
+ try {
+ // Try first from 'blog' collection (auto-generated)
+ let allPosts = [];
+ try {
+ allPosts = await getCollection('blog', ({ data }) => {
+ return import.meta.env.PROD ? !data.draft : true;
+ });
+ } catch (e) {
+ console.log('Blog collection not found, trying posts');
+ }
+
+ // If that fails or is empty, try 'posts' collection
+ if (allPosts.length === 0) {
+ allPosts = await getCollection('posts', ({ data }) => {
+ return import.meta.env.PROD ? !data.draft : true;
+ });
+ }
+
+ return allPosts.map(post => ({
+ params: { slug: post.slug },
+ props: { post },
+ }));
+ } catch (error) {
+ console.error('Error fetching posts:', error);
+ // Return empty array if both collections don't exist or are empty
+ return [];
+ }
}
+// Get the post from props
const { post } = Astro.props;
-const { Content } = await post.render();
-// Handle undefined or null values
-const title = post.data.title || '';
-const description = post.data.description || '';
-const pubDate = post.data.pubDate ? new Date(post.data.pubDate) : new Date();
-const updatedDate = post.data.updatedDate ? new Date(post.data.updatedDate) : undefined;
-const heroImage = post.data.heroImage || undefined;
-const category = post.data.category || undefined;
-const tags = post.data.tags || [];
-const draft = post.data.draft || false;
+// Format date helper
+const formatDate = (date) => {
+ if (!date) return '';
+ const d = new Date(date);
+ return d.toLocaleDateString('en-US', {
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric'
+ });
+};
+
+// Generate datetime attribute safely
+const getISODate = (date) => {
+ if (!date) return '';
+ // Handle various date formats
+ try {
+ // If already a Date object
+ if (date instanceof Date) {
+ return date.toISOString();
+ }
+ // If it's a string or number, convert to Date
+ return new Date(date).toISOString();
+ } catch (error) {
+ // Fallback if date is invalid
+ console.error('Invalid date format:', date);
+ return '';
+ }
+};
+
+// Get the Content component for rendering markdown
+const { Content } = await post.render();
---
-
-
-
\ No newline at end of file
+
+
+
+