Files
cms.uldp.edu.vn/controllers/blogTagController.js

358 lines
8.8 KiB
JavaScript

const BlogTag = require('../models/blogTag');
const slugify = require('slugify');
// -------------------- Admin Controllers --------------------
// Display tag management page
exports.index = async (req, res) => {
try {
const tags = await BlogTag.find()
.sort({ name: 1 })
.lean();
res.render('admin/blog/tags/index', {
layout: 'layouts/main',
title: 'Blog Tags',
tags,
currentPath: req.path,
user: req.session.user
});
} catch (err) {
console.error('Tag index error:', err);
req.flash('error_msg', 'Error loading tags');
res.redirect('/admin/dashboard');
}
};
// Show create tag form
exports.create = async (req, res) => {
try {
res.render('admin/blog/tags/create', {
layout: 'layouts/main',
title: 'Create New Tag',
currentPath: req.path,
user: req.session.user
});
} catch (err) {
console.error('Tag create form error:', err);
req.flash('error_msg', 'Error loading create form');
res.redirect('/admin/blog/tags');
}
};
// Store new tag
exports.store = async (req, res) => {
try {
const {
name,
isActive
} = req.body;
// Generate slug
const slug = slugify(name, {
lower: true,
strict: true,
locale: 'vi'
});
// Check if slug exists
const existingTag = await BlogTag.findOne({ slug });
if (existingTag) {
req.flash('error_msg', 'A tag with this name already exists');
return res.redirect('/admin/blog/tags/create');
}
// Create tag data
const tagData = {
name,
slug,
isActive: isActive === 'on'
};
// Create tag
const tag = new BlogTag(tagData);
await tag.save();
req.flash('success_msg', 'Tag created successfully');
res.redirect('/admin/blog/tags');
} catch (err) {
console.error('Tag store error:', err);
req.flash('error_msg', 'Error creating tag');
res.redirect('/admin/blog/tags/create');
}
};
// Show edit tag form
exports.edit = async (req, res) => {
try {
const tag = await BlogTag.findById(req.params.id);
if (!tag) {
req.flash('error_msg', 'Tag not found');
return res.redirect('/admin/blog/tags');
}
res.render('admin/blog/tags/edit', {
layout: 'layouts/main',
title: 'Edit Tag',
tag,
currentPath: req.path,
user: req.session.user
});
} catch (err) {
console.error('Tag edit form error:', err);
req.flash('error_msg', 'Error loading tag');
res.redirect('/admin/blog/tags');
}
};
// Update tag
exports.update = async (req, res) => {
try {
const tag = await BlogTag.findById(req.params.id);
if (!tag) {
req.flash('error_msg', 'Tag not found');
return res.redirect('/admin/blog/tags');
}
const {
name,
isActive
} = req.body;
// Update tag data
tag.name = name;
tag.isActive = isActive === 'on';
// Generate new slug if name changed
const newSlug = slugify(name, {
lower: true,
strict: true,
locale: 'vi'
});
if (newSlug !== tag.slug) {
const existingTag = await BlogTag.findOne({
slug: newSlug,
_id: { $ne: tag._id }
});
if (existingTag) {
req.flash('error_msg', 'A tag with this name already exists');
return res.redirect(`/admin/blog/tags/${tag._id}/edit`);
}
tag.slug = newSlug;
}
await tag.save();
req.flash('success_msg', 'Tag updated successfully');
res.redirect('/admin/blog/tags');
} catch (err) {
console.error('Tag update error:', err);
req.flash('error_msg', 'Error updating tag');
res.redirect(`/admin/blog/tags/${req.params.id}/edit`);
}
};
// Delete tag
exports.destroy = async (req, res) => {
try {
const tag = await BlogTag.findById(req.params.id);
if (!tag) {
// Check if it's an AJAX request
const isAjax = req.xhr || req.headers['accept']?.includes('application/json') || req.headers['content-type']?.includes('application/json');
if (isAjax) {
return res.status(404).json({
success: false,
message: 'Tag not found'
});
}
req.flash('error_msg', 'Tag not found');
return res.redirect('/admin/blog/tags');
}
// Check if tag has posts
const Blog = require('../models/blog');
const postCount = await Blog.countDocuments({ tags: { $in: [tag.name] } });
if (postCount > 0) {
// Check if it's an AJAX request
const isAjax = req.xhr || req.headers['accept']?.includes('application/json') || req.headers['content-type']?.includes('application/json');
if (isAjax) {
return res.status(400).json({
success: false,
message: 'Cannot delete tag that is used in blog posts'
});
}
req.flash('error_msg', 'Cannot delete tag that is used in blog posts');
return res.redirect('/admin/blog/tags');
}
await BlogTag.findByIdAndDelete(req.params.id);
// Check if it's an AJAX request
const isAjax = req.xhr || req.headers['accept']?.includes('application/json') || req.headers['content-type']?.includes('application/json');
if (isAjax) {
return res.json({
success: true,
message: 'Tag deleted successfully'
});
}
req.flash('success_msg', 'Tag deleted successfully');
res.redirect('/admin/blog/tags');
} catch (err) {
console.error('Tag delete error:', err);
// Check if it's an AJAX request
const isAjax = req.xhr || req.headers['accept']?.includes('application/json') || req.headers['content-type']?.includes('application/json');
if (isAjax) {
return res.status(500).json({
success: false,
message: 'Error deleting tag',
error: err.message || 'Error deleting tag'
});
}
req.flash('error_msg', 'Error deleting tag');
res.redirect('/admin/blog/tags');
}
};
// -------------------- Public API Controllers --------------------
// Get all active tags
exports.api = async (req, res) => {
try {
const tags = await BlogTag.getActive();
// Update post counts
for (const tag of tags) {
await tag.updatePostCount();
}
res.json({
success: true,
message: 'Tags fetched successfully',
data: tags
});
} catch (err) {
console.error('Tags API error:', err);
res.status(500).json({
success: false,
message: 'Error loading tags',
error: err.message || 'Error loading tags'
});
}
};
// Get popular tags
exports.apiPopular = async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 10;
const tags = await BlogTag.getPopular(limit);
res.json({
success: true,
message: 'Popular tags fetched successfully',
data: tags
});
} catch (err) {
console.error('Popular tags API error:', err);
res.status(500).json({
success: false,
message: 'Error loading popular tags',
error: err.message || 'Error loading popular tags'
});
}
};
// Get tag by slug
exports.apiShow = async (req, res) => {
try {
const tag = await BlogTag.findOne({
slug: req.params.slug,
isActive: true
}).lean();
if (!tag) {
return res.status(404).json({
success: false,
message: 'Tag not found'
});
}
res.json({
success: true,
message: 'Tag fetched successfully',
data: tag
});
} catch (err) {
console.error('Tag show API error:', err);
res.status(500).json({
success: false,
message: 'Error loading tag',
error: err.message || 'Error loading tag'
});
}
};
// Quick create tag (for inline creation in blog form)
exports.quickCreate = async (req, res) => {
try {
const { name } = req.body;
if (!name || !name.trim()) {
return res.status(400).json({
success: false,
message: 'Tag name is required'
});
}
const tagName = name.trim();
// Generate slug
const slug = slugify(tagName, {
lower: true,
strict: true,
locale: 'vi'
});
// Check if tag already exists
let tag = await BlogTag.findOne({ slug });
if (tag) {
return res.json({
success: true,
message: 'Tag already exists',
data: tag.toObject()
});
}
// Create new tag
tag = new BlogTag({
name: tagName,
slug,
isActive: true
});
await tag.save();
res.json({
success: true,
message: 'Tag created successfully',
data: tag.toObject()
});
} catch (err) {
console.error('Quick create tag error:', err);
res.status(500).json({
success: false,
message: 'Error creating tag',
error: err.message || 'Error creating tag'
});
}
};
module.exports = exports;