Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
const Blog = require('./models/blog');
const Category = require('/models/category');
const categoryRoutes = require('./routes/categoryRoutes');
app.use(categoryRoutes);
const blogRoutes = require('./routes/blogRoutes');
app.use(blogRoutes);
const blogRoutes = require('./routes/blogRoutes'); // Adjust the path as necessary
app.use(blogRoutes); // Use the blog routes
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
Expand Down Expand Up @@ -158,4 +166,4 @@ mongoose
.catch((error) => console.log(error));
app.listen(PORT, function () {
console.log(`Server started on port ${PORT}`);
});
});
13 changes: 13 additions & 0 deletions models/Category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const mongoose = require('mongoose'); // Importing Mongoose

// Defining the structure of a Category in the database
const categorySchema = new mongoose.Schema({
name: {
type: String, // The name of the category, like "Technology"
required: true, // It must be provided
unique: true // No duplicate category names
}
});

const Category = mongoose.model('Category', categorySchema); // Creating the Category model
module.exports = Category; // Making the model available to use elsewhere
24 changes: 24 additions & 0 deletions models/blog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const mongoose = require('mongoose');

const blogSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
category: {
type: mongoose.Schema.Types.ObjectId, // This will link to the Category model
ref: 'Category', // Refers to the Category model
required: true
},
createdAt: {
type: Date,
default: Date.now
}
});

const Blog = mongoose.model('Blog', blogSchema);
module.exports = Blog;
47 changes: 47 additions & 0 deletions routers/blogRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const express = require('express');
const router = express.Router();
const Blog = require('../models/blog'); // Ensure you have a Blog model
const Category = require('../models/category'); // Ensure you have a Category model

// Route to get all blogs and filter by category
router.get('/blogs', async (req, res) => {
try {
const categories = await Category.find(); // Fetch all categories
let blogs;
if (req.query.category) {
blogs = await Blog.find({ category: req.query.category }).populate('category'); // Filter by category if selected
} else {
blogs = await Blog.find().populate('category'); // Otherwise, fetch all blogs
}
res.render('blogList', { blogs, categories }); // Pass blogs and categories to the view
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});

// Route to get the form for creating a new blog (with category selection)
router.get('/blogs/new', async (req, res) => {
try {
const categories = await Category.find(); // Fetch categories for the form
res.render('newBlog', { categories });
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});

// Route to handle creating a new blog
router.post('/blogs', async (req, res) => {
try {
const { title, content, category } = req.body;
const newBlog = new Blog({ title, content, category }); // Create a new blog with the selected category
await newBlog.save(); // Save the new blog
res.redirect('/blogs'); // Redirect to the blog list
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});

module.exports = router;
25 changes: 25 additions & 0 deletions routers/categoryRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const express = require('express');
const router = express.Router();
const Category = require('./models/category');
// Add a category
router.post('/category', async (req, res) => {
const newCategory = new Category({ name: req.body.name });
try {
await newCategory.save();
res.status(201).json(newCategory);
} catch (err) {
res.status(400).json({ message: err.message });
}
});

// Get all categories
router.get('/categories', async (req, res) => {
try {
const categories = await Category.find();
res.json(categories);
} catch (err) {
res.status(500).json({ message: err.message });
}
});

module.exports = router;
63 changes: 40 additions & 23 deletions views/blogs.ejs
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
<%- include("partials/header"); -%>
<div class="grid grid-columns-3 gap-3 px-3" style="margin-bottom:5%;">
<% blogs.forEach(function(blog) { %>
<div class="card"
style="display: flex; flex-direction: column; justify-content: space-between; padding-bottom: 10px;">
<div class="card-header">
<a href="/blogs/<%= blog.title %>"><img src="<%= blog.image %>" class="card-image"/ alt="Image not Available"></a>
</div>
<div class="card-body card-hover" style="width: max-width; height: max-content;">
<h2 class="card-title">
<a href="/blogs/<%= blog.title %>"><%= blog.title %></a>
</h2>
<div class="card-content">
<p class="card-text">
<%= blog.content.substring(0, 100) + " ..." %>
</p>
</div>
</div>
<div class="card-footer" style="width: 100px;align-self: flex-end; margin-right: 20px;">
<a href="/blogs/<%= blog.title %>" class="btn btn-primary">Read more</a>

<!-- Category Filter Form -->
<form method="GET" action="/blogs" style="margin-bottom: 20px;">
<select name="category" onchange="this.form.submit()">
<option value="">All Categories</option>
<% categories.forEach(function(category) { %>
<option value="<%= category._id %>" <%= category._id.toString() === selectedCategory ? 'selected' : '' %>>
<%= category.name %>
</option>
<% }); %>
</select>
</form>

<div class="grid grid-columns-3 gap-3 px-3" style="margin-bottom:5%;">
<% blogs.forEach(function(blog) { %>
<div class="card"
style="display: flex; flex-direction: column; justify-content: space-between; padding-bottom: 10px;">
<div class="card-header">
<a href="/blogs/<%= blog.title %>">
<img src="<%= blog.image %>" class="card-image" alt="Image not Available">
</a>
</div>
<div class="card-body card-hover" style="width: max-width; height: max-content;">
<h2 class="card-title">
<a href="/blogs/<%= blog.title %>"><%= blog.title %></a>
</h2>
<!-- Display Category -->
<h4 class="card-category" style="color: gray;">Category: <%= blog.category.name %></h4>
<div class="card-content">
<p class="card-text">
<%= blog.content.substring(0, 100) + " ..." %>
</p>
</div>
</div>
<% }); %>
</div>
</div>
<%- include("partials/footer"); -%>
<div class="card-footer" style="width: 100px;align-self: flex-end; margin-right: 20px;">
<a href="/blogs/<%= blog.title %>" class="btn btn-primary">Read more</a>
</div>
</div>
<% }); %>
</div>

<%- include("partials/footer"); -%>