# Django Blog Package
A comprehensive, reusable Django blog package that can be easily installed and integrated into any Django project. This package provides a complete blogging system with standard features including post management, categories, tags, comments, user management, enhanced rich text editing with CKEditor's full editor suite, and sophisticated view tracking.
## Features
- **Easy Installation**: Simple pip installation and Django app configuration
- **Complete Blog Management**: Create, edit, publish, and manage blog posts
- **Categories & Tags**: Organize content with categories and flexible tagging
- **Comment System**: Threaded comments with moderation capabilities
- **Search Functionality**: Full-text search across posts, titles, and content
- **SEO Optimization**: Automatic meta tags, clean URLs, and SEO-friendly structure
- **Admin Interface**: Comprehensive Django admin integration with CKEditor
- **Rich Text Editing**: Full CKEditor suite with search/replace, spell checking, and advanced formatting
- **View Counter**: Sophisticated unique view tracking with duplicate prevention
- **Customizable Templates**: Easy template overriding and theming
- **Header/Footer Swapping**: Seamlessly integrate with existing company/business headers and footers
- **Social Sharing**: Built-in social media sharing buttons
- **Performance Optimized**: Efficient queries and caching support
- **Security**: Input validation, permission controls, and secure file uploads
## Quick Start
### Installation
```bash
pip install django-blog-package
```
### Basic Setup
1. **Add to INSTALLED_APPS** (CKEditor must be added BEFORE the blog app):
```python
# settings.py
INSTALLED_APPS = [
# ... other Django apps
'ckeditor',
'ckeditor_uploader', # Optional, for file uploads
'blog',
]
```
2. **Run migrations**:
```bash
python manage.py migrate
```
3. **Include URLs** in your project's `urls.py`:
```python
from django.urls import include, path
urlpatterns = [
# ... your other URL patterns
path('blog/', include('blog.urls')),
path('ckeditor/', include('ckeditor_uploader.urls')), # For file uploads
]
```
4. **Collect static files**:
```bash
python manage.py collectstatic
```
## Essential Configuration
### CKEditor Setup (REQUIRED)
**IMPORTANT**: You MUST add CKEditor configuration to your project's `settings.py`:
```python
# settings.py
# Media configuration (required for file uploads)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
# CKEditor configuration for blog posts
CKEDITOR_CONFIGS = {
'blog_editor': {
'toolbar': 'Full',
'height': 500,
'width': '100%',
'extraPlugins': 'codesnippet,image2,uploadimage,find,autolink,autoembed,embedsemantic,autogrow',
'removePlugins': 'elementspath',
'resize_enabled': True,
'allowedContent': True,
'filebrowserUploadUrl': '/ckeditor/upload/',
'filebrowserUploadMethod': 'form',
'autoGrow_minHeight': 400,
'autoGrow_maxHeight': 1200,
'autoGrow_bottomSpace': 50,
'autoGrow_onStartup': True,
'wordcount': {
'showParagraphs': True,
'showWordCount': True,
'showCharCount': True,
'countSpacesAsChars': True,
'countHTML': False,
},
'linkDefaultTarget': '_blank',
'find_highlight': {
'element': 'span',
'styles': {'background-color': '#ffeb3b', 'color': '#000000'}
},
'scayt_autoStartup': True,
'scayt_sLang': 'en_US',
'scayt_maxSuggestions': 5,
'scayt_minWordLength': 4,
}
}
```
### View Counter Middleware Setup
To enable the sophisticated view counter, add the middleware to your settings:
```python
# settings.py
MIDDLEWARE = [
# ... other middleware
# Session middleware is REQUIRED for view counter
'django.contrib.sessions.middleware.SessionMiddleware',
# ... other middleware
# Add these two middleware classes
'blog.middleware.view_counter.ViewCounterMiddleware',
'blog.middleware.view_counter.ViewCounterCleanupMiddleware',
# ... other middleware
]
```
**View Counter Features:**
- ✅ Unique view tracking (IP + session based)
- ✅ Duplicate prevention (1-hour cache)
- ✅ Automatic cleanup (30-day retention)
- ✅ Performance optimized with caching
### Blog Settings
Configure basic blog behavior:
```python
# settings.py
BLOG_SETTINGS = {
'PAGINATE_BY': 10,
'COMMENTS_ENABLED': True,
'COMMENT_MODERATION': True,
'SEARCH_ENABLED': True,
'SOCIAL_SHARING_ENABLED': True,
'DEFAULT_CATEGORY_SLUG': 'general',
'EXCERPT_LENGTH': 150,
'IMAGE_UPLOAD_PATH': 'blog/images/',
'ALLOW_HTML_IN_COMMENTS': False,
# Header/Footer Configuration
'USE_CUSTOM_HEADER': False, # Set to True to use custom header
'USE_CUSTOM_FOOTER': False, # Set to True to use custom footer
'HEADER_TEMPLATE': 'blog/includes/header.html', # Default header template
'FOOTER_TEMPLATE': 'blog/includes/footer.html', # Default footer template
'CUSTOM_HEADER_TEMPLATE': None, # Path to your custom header template
'CUSTOM_FOOTER_TEMPLATE': None, # Path to your custom footer template
}
```
## Enhanced CKEditor Features
The package includes a fully configured CKEditor with:
### 🛠️ Full Editor Suite
- Complete toolbar with all editing tools
- Advanced formatting options
- Table creation and editing
- Multiple font styles and sizes
### 🔍 Document Search & Replace
- **Find text (Ctrl+F)** - Search throughout your document
- **Replace text** - Find and replace repeated characters
- **Highlight search results** - Visual feedback for matches
### ✨ Advanced Functionality
- **Spell checking** as you type
- **Auto-grow editor** that expands with content
- **Code snippet support** with syntax highlighting
- **Image upload and management**
- **Enhanced word count and statistics**
- **File upload capabilities**
## Header/Footer Integration
Seamlessly integrate the blog with your existing company/business website design by swapping the default header and footer with your own templates.
### Basic Configuration
```python
# Use default blog header/footer (default behavior)
BLOG_SETTINGS = {
'USE_CUSTOM_HEADER': False,
'USE_CUSTOM_FOOTER': False,
}
# Use custom header only
BLOG_SETTINGS = {
'USE_CUSTOM_HEADER': True,
'USE_CUSTOM_FOOTER': False,
'CUSTOM_HEADER_TEMPLATE': 'myapp/includes/header.html',
}
# Use custom footer only
BLOG_SETTINGS = {
'USE_CUSTOM_HEADER': False,
'USE_CUSTOM_FOOTER': True,
'CUSTOM_FOOTER_TEMPLATE': 'myapp/includes/footer.html',
}
# Use both custom header and footer
BLOG_SETTINGS = {
'USE_CUSTOM_HEADER': True,
'USE_CUSTOM_FOOTER': True,
'CUSTOM_HEADER_TEMPLATE': 'myapp/includes/header.html',
'CUSTOM_FOOTER_TEMPLATE': 'myapp/includes/footer.html',
}
```
### Template Requirements
Your custom templates should include blog navigation links:
**Header Template:**
```html
<!-- myapp/templates/myapp/includes/header.html -->
<header class="your-company-header">
<nav>
<a href="/">Home</a>
<a href="{% url 'blog:post_list' %}">Blog</a>
<a href="{% url 'blog:post_archive' %}">Archive</a>
<a href="{% url 'blog:post_search' %}">Search</a>
<!-- Your other navigation items -->
</nav>
</header>
```
**Footer Template:**
```html
<!-- myapp/templates/myapp/includes/footer.html -->
<footer class="your-company-footer">
<div class="blog-links">
<a href="{% url 'blog:post_list' %}">Latest Posts</a>
<a href="{% url 'blog:post_archive' %}">Archive</a>
</div>
<!-- Your other footer content -->
</footer>
```
### Benefits
- **Seamless Integration**: Maintain consistent branding across your entire website
- **Flexible Design**: Mix and match default and custom templates
- **Easy Migration**: Switch between designs without changing blog functionality
- **Professional Appearance**: Blog appears as a natural part of your website
### Complete Header/Footer Configuration Options
The header/footer swapping feature supports the following settings:
```python
BLOG_SETTINGS = {
# Enable/disable custom header
'USE_CUSTOM_HEADER': False,
# Enable/disable custom footer
'USE_CUSTOM_FOOTER': False,
# Default header template (fallback)
'HEADER_TEMPLATE': 'blog/includes/header.html',
# Default footer template (fallback)
'FOOTER_TEMPLATE': 'blog/includes/footer.html',
# Path to your custom header template
'CUSTOM_HEADER_TEMPLATE': None,
# Path to your custom footer template
'CUSTOM_FOOTER_TEMPLATE': None,
}
```
### Template Requirements
Your custom templates should include blog navigation links:
**Header Template Requirements:**
- Include navigation with blog links
- Use `{% url 'blog:post_list' %}` for blog home
- Use `{% url 'blog:post_archive' %}` for archive
- Use `{% url 'blog:post_search' %}` for search
**Footer Template Requirements:**
- Include blog-related links for easy navigation
- Maintain consistent styling with your website
### Troubleshooting
**Common Issues:**
- Template not found: Verify template paths exist
- Missing blog URLs: Ensure blog app is properly installed
- Styling conflicts: Check CSS loading order and specificity
**Debug Mode:**
Enable Django debug mode to see template loading errors:
```python
DEBUG = True
```
## Usage
### Creating Blog Posts
1. Go to Django admin at `/admin/`
2. Navigate to **Blog → Posts**
3. Create categories and tags as needed
4. Create blog posts with the enhanced CKEditor
### Displaying View Counts
View counts are automatically tracked and available:
```django
{# In templates #}
{{ post.view_count }} views
{# In Python code #}
post.view_count
```
### Template Customization
Override default templates by creating your own:
```bash
your_project/
├── templates/
│ └── blog/
│ ├── base.html
│ ├── post_list.html
│ ├── post_detail.html
│ ├── post_archive.html
│ └── includes/
│ ├── sidebar.html
│ ├── pagination.html
│ └── comments.html
```
### Template Tags
Use built-in template tags for common functionality:
```django
{% load blog_tags %}
{# Get categories #}
{% get_categories as categories %}
{# Get recent posts #}
{% get_recent_posts 5 as recent_posts %}
{# Get popular tags #}
{% get_popular_tags 10 as popular_tags %}
{# Render sidebar #}
{% blog_sidebar %}
{# Render pagination #}
{% blog_pagination page_obj paginator request %}
{# Social sharing buttons #}
{% social_sharing_buttons post %}
```
## URL Structure
The package provides the following URL patterns:
- `/blog/` - Blog post list
- `/blog/page/<page>/` - Paginated post list
- `/blog/search/` - Search results
- `/blog/category/<slug>/` - Posts by category
- `/blog/tag/<slug>/` - Posts by tag
- `/blog/<year>/<month>/<day>/<slug>/` - Individual post detail
- `/blog/comment/<post_id>/` - Comment submission
- `/blog/archive/` - Post archive
- `/blog/archive/<year>/` - Yearly archive
- `/blog/archive/<year>/<month>/` - Monthly archive
## Troubleshooting
### Common CKEditor Issues
**Error: "No configuration named 'blog_editor' found"**
- **Solution**: Add the `CKEDITOR_CONFIGS` dictionary with `blog_editor` configuration to your `settings.py`
**Error: TemplateDoesNotExist: ckeditor/widget.html**
- **Solution**: Ensure `ckeditor` is in `INSTALLED_APPS` and `APP_DIRS = True` in `TEMPLATES` setting
### Common View Counter Issues
**Views not being counted**
- **Solution**: Verify middleware is in `MIDDLEWARE` list and session middleware is enabled
**Duplicate counts**
- **Solution**: System prevents duplicates within 1 hour - this is normal behavior
### Quick Verification
Run the included configuration checker:
```bash
python check_ckeditor_config.py
```
## Models
### Core Models
- **Category**: Hierarchical organization of posts
- **Tag**: Flexible categorization through many-to-many relationships
- **Post**: Core content with publication workflow
- **Comment**: User engagement with moderation system
- **PostView**: Unique view tracking records
### Example Usage
```python
from blog.models import Post, Category, Tag
# Get published posts
published_posts = Post.objects.published()
# Get posts by category
tech_posts = Post.objects.by_category('technology')
# Get posts by tag
python_posts = Post.objects.by_tag('python')
# Get recent posts
recent_posts = Post.objects.recent(5)
# Get view count for a post
post = Post.objects.get(slug='my-post')
views = post.view_count
```
## Admin Interface
The package provides a comprehensive admin interface with:
- Post management with bulk actions
- Category and tag management
- Comment moderation tools
- Publication workflow management
- Search and filtering capabilities
- Enhanced CKEditor for content editing
## Testing
Run the test suite:
```bash
python manage.py test blog
```
## Included Documentation Files
After installation, you'll find these comprehensive documentation files:
- `CKEDITOR_SETUP.md` - Complete CKEditor setup guide
- `CKEDITOR_TROUBLESHOOTING.md` - CKEditor issues and solutions
- `CKEDITOR_SETTINGS_TEMPLATE.py` - Ready-to-copy configuration
- `check_ckeditor_config.py` - Configuration verification script
- `VIEW_COUNTER_SETUP.md` - Complete view counter middleware guide
## Dependencies
- Django >= 4.2, < 5.0
- Pillow >= 9.0, < 11.0
- django-ckeditor >= 6.0, < 7.0
## Compatibility
- Python 3.8+
- Django 4.2+
- SQLite, PostgreSQL, MySQL databases
## Support
For issues and questions:
- Check the included documentation files
- Create an issue on GitHub: https://github.com/josephbraide/django-blog-package/issues
- Review the code examples
## License
This project is licensed under the MIT License - see the LICENSE file for details.
---
**Django Blog Package** - Making blogging in Django projects simple and powerful with professional-grade rich text editing and sophisticated analytics.
Raw data
{
"_id": null,
"home_page": "https://github.com/josephbraide/django-blog-package",
"name": "django-blog-package",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "django, blog, cms, content, posts, articles, comments, categories, tags",
"author": "Joseph Braide",
"author_email": "Joseph Braide <braidej@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/0e/4e/d748cadca760ae33da7ef66a4a475a95ed0f6ccea226f8c3438b4f9ab4e9/django_blog_package-1.0.7.tar.gz",
"platform": null,
"description": "# Django Blog Package\n\nA comprehensive, reusable Django blog package that can be easily installed and integrated into any Django project. This package provides a complete blogging system with standard features including post management, categories, tags, comments, user management, enhanced rich text editing with CKEditor's full editor suite, and sophisticated view tracking.\n\n## Features\n\n- **Easy Installation**: Simple pip installation and Django app configuration\n- **Complete Blog Management**: Create, edit, publish, and manage blog posts\n- **Categories & Tags**: Organize content with categories and flexible tagging\n- **Comment System**: Threaded comments with moderation capabilities\n- **Search Functionality**: Full-text search across posts, titles, and content\n- **SEO Optimization**: Automatic meta tags, clean URLs, and SEO-friendly structure\n- **Admin Interface**: Comprehensive Django admin integration with CKEditor\n- **Rich Text Editing**: Full CKEditor suite with search/replace, spell checking, and advanced formatting\n- **View Counter**: Sophisticated unique view tracking with duplicate prevention\n- **Customizable Templates**: Easy template overriding and theming\n- **Header/Footer Swapping**: Seamlessly integrate with existing company/business headers and footers\n- **Social Sharing**: Built-in social media sharing buttons\n- **Performance Optimized**: Efficient queries and caching support\n- **Security**: Input validation, permission controls, and secure file uploads\n\n## Quick Start\n\n### Installation\n\n```bash\npip install django-blog-package\n```\n\n### Basic Setup\n\n1. **Add to INSTALLED_APPS** (CKEditor must be added BEFORE the blog app):\n```python\n# settings.py\nINSTALLED_APPS = [\n # ... other Django apps\n 'ckeditor',\n 'ckeditor_uploader', # Optional, for file uploads\n 'blog',\n]\n```\n\n2. **Run migrations**:\n```bash\npython manage.py migrate\n```\n\n3. **Include URLs** in your project's `urls.py`:\n```python\nfrom django.urls import include, path\n\nurlpatterns = [\n # ... your other URL patterns\n path('blog/', include('blog.urls')),\n path('ckeditor/', include('ckeditor_uploader.urls')), # For file uploads\n]\n```\n\n4. **Collect static files**:\n```bash\npython manage.py collectstatic\n```\n\n## Essential Configuration\n\n### CKEditor Setup (REQUIRED)\n\n**IMPORTANT**: You MUST add CKEditor configuration to your project's `settings.py`:\n\n```python\n# settings.py\n\n# Media configuration (required for file uploads)\nMEDIA_URL = '/media/'\nMEDIA_ROOT = os.path.join(BASE_DIR, 'media/')\n\n# CKEditor configuration for blog posts\nCKEDITOR_CONFIGS = {\n 'blog_editor': {\n 'toolbar': 'Full',\n 'height': 500,\n 'width': '100%',\n 'extraPlugins': 'codesnippet,image2,uploadimage,find,autolink,autoembed,embedsemantic,autogrow',\n 'removePlugins': 'elementspath',\n 'resize_enabled': True,\n 'allowedContent': True,\n 'filebrowserUploadUrl': '/ckeditor/upload/',\n 'filebrowserUploadMethod': 'form',\n 'autoGrow_minHeight': 400,\n 'autoGrow_maxHeight': 1200,\n 'autoGrow_bottomSpace': 50,\n 'autoGrow_onStartup': True,\n 'wordcount': {\n 'showParagraphs': True,\n 'showWordCount': True,\n 'showCharCount': True,\n 'countSpacesAsChars': True,\n 'countHTML': False,\n },\n 'linkDefaultTarget': '_blank',\n 'find_highlight': {\n 'element': 'span',\n 'styles': {'background-color': '#ffeb3b', 'color': '#000000'}\n },\n 'scayt_autoStartup': True,\n 'scayt_sLang': 'en_US',\n 'scayt_maxSuggestions': 5,\n 'scayt_minWordLength': 4,\n }\n}\n```\n\n### View Counter Middleware Setup\n\nTo enable the sophisticated view counter, add the middleware to your settings:\n\n```python\n# settings.py\nMIDDLEWARE = [\n # ... other middleware\n \n # Session middleware is REQUIRED for view counter\n 'django.contrib.sessions.middleware.SessionMiddleware',\n \n # ... other middleware\n \n # Add these two middleware classes\n 'blog.middleware.view_counter.ViewCounterMiddleware',\n 'blog.middleware.view_counter.ViewCounterCleanupMiddleware',\n \n # ... other middleware\n]\n```\n\n**View Counter Features:**\n- \u2705 Unique view tracking (IP + session based)\n- \u2705 Duplicate prevention (1-hour cache)\n- \u2705 Automatic cleanup (30-day retention)\n- \u2705 Performance optimized with caching\n\n### Blog Settings\n\nConfigure basic blog behavior:\n\n```python\n# settings.py\nBLOG_SETTINGS = {\n 'PAGINATE_BY': 10,\n 'COMMENTS_ENABLED': True,\n 'COMMENT_MODERATION': True,\n 'SEARCH_ENABLED': True,\n 'SOCIAL_SHARING_ENABLED': True,\n 'DEFAULT_CATEGORY_SLUG': 'general',\n 'EXCERPT_LENGTH': 150,\n 'IMAGE_UPLOAD_PATH': 'blog/images/',\n 'ALLOW_HTML_IN_COMMENTS': False,\n \n # Header/Footer Configuration\n 'USE_CUSTOM_HEADER': False, # Set to True to use custom header\n 'USE_CUSTOM_FOOTER': False, # Set to True to use custom footer\n 'HEADER_TEMPLATE': 'blog/includes/header.html', # Default header template\n 'FOOTER_TEMPLATE': 'blog/includes/footer.html', # Default footer template\n 'CUSTOM_HEADER_TEMPLATE': None, # Path to your custom header template\n 'CUSTOM_FOOTER_TEMPLATE': None, # Path to your custom footer template\n}\n```\n\n## Enhanced CKEditor Features\n\nThe package includes a fully configured CKEditor with:\n\n### \ud83d\udee0\ufe0f Full Editor Suite\n- Complete toolbar with all editing tools\n- Advanced formatting options\n- Table creation and editing\n- Multiple font styles and sizes\n\n### \ud83d\udd0d Document Search & Replace\n- **Find text (Ctrl+F)** - Search throughout your document\n- **Replace text** - Find and replace repeated characters\n- **Highlight search results** - Visual feedback for matches\n\n### \u2728 Advanced Functionality\n- **Spell checking** as you type\n- **Auto-grow editor** that expands with content\n- **Code snippet support** with syntax highlighting\n- **Image upload and management**\n- **Enhanced word count and statistics**\n- **File upload capabilities**\n\n## Header/Footer Integration\n\nSeamlessly integrate the blog with your existing company/business website design by swapping the default header and footer with your own templates.\n\n### Basic Configuration\n\n```python\n# Use default blog header/footer (default behavior)\nBLOG_SETTINGS = {\n 'USE_CUSTOM_HEADER': False,\n 'USE_CUSTOM_FOOTER': False,\n}\n\n# Use custom header only\nBLOG_SETTINGS = {\n 'USE_CUSTOM_HEADER': True,\n 'USE_CUSTOM_FOOTER': False,\n 'CUSTOM_HEADER_TEMPLATE': 'myapp/includes/header.html',\n}\n\n# Use custom footer only\nBLOG_SETTINGS = {\n 'USE_CUSTOM_HEADER': False,\n 'USE_CUSTOM_FOOTER': True,\n 'CUSTOM_FOOTER_TEMPLATE': 'myapp/includes/footer.html',\n}\n\n# Use both custom header and footer\nBLOG_SETTINGS = {\n 'USE_CUSTOM_HEADER': True,\n 'USE_CUSTOM_FOOTER': True,\n 'CUSTOM_HEADER_TEMPLATE': 'myapp/includes/header.html',\n 'CUSTOM_FOOTER_TEMPLATE': 'myapp/includes/footer.html',\n}\n```\n\n### Template Requirements\n\nYour custom templates should include blog navigation links:\n\n**Header Template:**\n```html\n<!-- myapp/templates/myapp/includes/header.html -->\n<header class=\"your-company-header\">\n <nav>\n <a href=\"/\">Home</a>\n <a href=\"{% url 'blog:post_list' %}\">Blog</a>\n <a href=\"{% url 'blog:post_archive' %}\">Archive</a>\n <a href=\"{% url 'blog:post_search' %}\">Search</a>\n <!-- Your other navigation items -->\n </nav>\n</header>\n```\n\n**Footer Template:**\n```html\n<!-- myapp/templates/myapp/includes/footer.html -->\n<footer class=\"your-company-footer\">\n <div class=\"blog-links\">\n <a href=\"{% url 'blog:post_list' %}\">Latest Posts</a>\n <a href=\"{% url 'blog:post_archive' %}\">Archive</a>\n </div>\n <!-- Your other footer content -->\n</footer>\n```\n\n### Benefits\n\n- **Seamless Integration**: Maintain consistent branding across your entire website\n- **Flexible Design**: Mix and match default and custom templates\n- **Easy Migration**: Switch between designs without changing blog functionality\n- **Professional Appearance**: Blog appears as a natural part of your website\n\n### Complete Header/Footer Configuration Options\n\nThe header/footer swapping feature supports the following settings:\n\n```python\nBLOG_SETTINGS = {\n # Enable/disable custom header\n 'USE_CUSTOM_HEADER': False,\n \n # Enable/disable custom footer \n 'USE_CUSTOM_FOOTER': False,\n \n # Default header template (fallback)\n 'HEADER_TEMPLATE': 'blog/includes/header.html',\n \n # Default footer template (fallback)\n 'FOOTER_TEMPLATE': 'blog/includes/footer.html',\n \n # Path to your custom header template\n 'CUSTOM_HEADER_TEMPLATE': None,\n \n # Path to your custom footer template\n 'CUSTOM_FOOTER_TEMPLATE': None,\n}\n```\n\n### Template Requirements\n\nYour custom templates should include blog navigation links:\n\n**Header Template Requirements:**\n- Include navigation with blog links\n- Use `{% url 'blog:post_list' %}` for blog home\n- Use `{% url 'blog:post_archive' %}` for archive\n- Use `{% url 'blog:post_search' %}` for search\n\n**Footer Template Requirements:**\n- Include blog-related links for easy navigation\n- Maintain consistent styling with your website\n\n### Troubleshooting\n\n**Common Issues:**\n- Template not found: Verify template paths exist\n- Missing blog URLs: Ensure blog app is properly installed\n- Styling conflicts: Check CSS loading order and specificity\n\n**Debug Mode:**\nEnable Django debug mode to see template loading errors:\n```python\nDEBUG = True\n```\n\n## Usage\n\n### Creating Blog Posts\n\n1. Go to Django admin at `/admin/`\n2. Navigate to **Blog \u2192 Posts**\n3. Create categories and tags as needed\n4. Create blog posts with the enhanced CKEditor\n\n### Displaying View Counts\n\nView counts are automatically tracked and available:\n\n```django\n{# In templates #}\n{{ post.view_count }} views\n\n{# In Python code #}\npost.view_count\n```\n\n### Template Customization\n\nOverride default templates by creating your own:\n\n```bash\nyour_project/\n\u251c\u2500\u2500 templates/\n\u2502 \u2514\u2500\u2500 blog/\n\u2502 \u251c\u2500\u2500 base.html\n\u2502 \u251c\u2500\u2500 post_list.html\n\u2502 \u251c\u2500\u2500 post_detail.html\n\u2502 \u251c\u2500\u2500 post_archive.html\n\u2502 \u2514\u2500\u2500 includes/\n\u2502 \u251c\u2500\u2500 sidebar.html\n\u2502 \u251c\u2500\u2500 pagination.html\n\u2502 \u2514\u2500\u2500 comments.html\n```\n\n### Template Tags\n\nUse built-in template tags for common functionality:\n\n```django\n{% load blog_tags %}\n\n{# Get categories #}\n{% get_categories as categories %}\n\n{# Get recent posts #}\n{% get_recent_posts 5 as recent_posts %}\n\n{# Get popular tags #}\n{% get_popular_tags 10 as popular_tags %}\n\n{# Render sidebar #}\n{% blog_sidebar %}\n\n{# Render pagination #}\n{% blog_pagination page_obj paginator request %}\n\n{# Social sharing buttons #}\n{% social_sharing_buttons post %}\n```\n\n## URL Structure\n\nThe package provides the following URL patterns:\n\n- `/blog/` - Blog post list\n- `/blog/page/<page>/` - Paginated post list\n- `/blog/search/` - Search results\n- `/blog/category/<slug>/` - Posts by category\n- `/blog/tag/<slug>/` - Posts by tag\n- `/blog/<year>/<month>/<day>/<slug>/` - Individual post detail\n- `/blog/comment/<post_id>/` - Comment submission\n- `/blog/archive/` - Post archive\n- `/blog/archive/<year>/` - Yearly archive\n- `/blog/archive/<year>/<month>/` - Monthly archive\n\n## Troubleshooting\n\n### Common CKEditor Issues\n\n**Error: \"No configuration named 'blog_editor' found\"**\n- **Solution**: Add the `CKEDITOR_CONFIGS` dictionary with `blog_editor` configuration to your `settings.py`\n\n**Error: TemplateDoesNotExist: ckeditor/widget.html**\n- **Solution**: Ensure `ckeditor` is in `INSTALLED_APPS` and `APP_DIRS = True` in `TEMPLATES` setting\n\n### Common View Counter Issues\n\n**Views not being counted**\n- **Solution**: Verify middleware is in `MIDDLEWARE` list and session middleware is enabled\n\n**Duplicate counts**\n- **Solution**: System prevents duplicates within 1 hour - this is normal behavior\n\n### Quick Verification\n\nRun the included configuration checker:\n```bash\npython check_ckeditor_config.py\n```\n\n## Models\n\n### Core Models\n\n- **Category**: Hierarchical organization of posts\n- **Tag**: Flexible categorization through many-to-many relationships\n- **Post**: Core content with publication workflow\n- **Comment**: User engagement with moderation system\n- **PostView**: Unique view tracking records\n\n### Example Usage\n\n```python\nfrom blog.models import Post, Category, Tag\n\n# Get published posts\npublished_posts = Post.objects.published()\n\n# Get posts by category\ntech_posts = Post.objects.by_category('technology')\n\n# Get posts by tag\npython_posts = Post.objects.by_tag('python')\n\n# Get recent posts\nrecent_posts = Post.objects.recent(5)\n\n# Get view count for a post\npost = Post.objects.get(slug='my-post')\nviews = post.view_count\n```\n\n## Admin Interface\n\nThe package provides a comprehensive admin interface with:\n\n- Post management with bulk actions\n- Category and tag management\n- Comment moderation tools\n- Publication workflow management\n- Search and filtering capabilities\n- Enhanced CKEditor for content editing\n\n## Testing\n\nRun the test suite:\n\n```bash\npython manage.py test blog\n```\n\n## Included Documentation Files\n\nAfter installation, you'll find these comprehensive documentation files:\n\n- `CKEDITOR_SETUP.md` - Complete CKEditor setup guide\n- `CKEDITOR_TROUBLESHOOTING.md` - CKEditor issues and solutions\n- `CKEDITOR_SETTINGS_TEMPLATE.py` - Ready-to-copy configuration\n- `check_ckeditor_config.py` - Configuration verification script\n- `VIEW_COUNTER_SETUP.md` - Complete view counter middleware guide\n\n## Dependencies\n\n- Django >= 4.2, < 5.0\n- Pillow >= 9.0, < 11.0\n- django-ckeditor >= 6.0, < 7.0\n\n## Compatibility\n\n- Python 3.8+\n- Django 4.2+\n- SQLite, PostgreSQL, MySQL databases\n\n## Support\n\nFor issues and questions:\n\n- Check the included documentation files\n- Create an issue on GitHub: https://github.com/josephbraide/django-blog-package/issues\n- Review the code examples\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n---\n\n**Django Blog Package** - Making blogging in Django projects simple and powerful with professional-grade rich text editing and sophisticated analytics.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A reusable Django blog package for adding blog functionality to any Django project",
"version": "1.0.7",
"project_urls": {
"Documentation": "https://github.com/josephbraide/django-blog-package/blob/main/README.md",
"Homepage": "https://github.com/josephbraide/django-blog-package",
"Issues": "https://github.com/josephbraide/django-blog-package/issues",
"Source": "https://github.com/josephbraide/django-blog-package"
},
"split_keywords": [
"django",
" blog",
" cms",
" content",
" posts",
" articles",
" comments",
" categories",
" tags"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3a08a6be397133c2aa624ab1266efeeaa26c5c4d7931b31e8f7f585fa361366a",
"md5": "5a5412e839de60bc45650aea1d2ae9e7",
"sha256": "106b9905cb474f4a29c74d0e79b6b325be72574068ea87b572e85d2ba71c8152"
},
"downloads": -1,
"filename": "django_blog_package-1.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5a5412e839de60bc45650aea1d2ae9e7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 57925,
"upload_time": "2025-10-21T05:49:42",
"upload_time_iso_8601": "2025-10-21T05:49:42.381370Z",
"url": "https://files.pythonhosted.org/packages/3a/08/a6be397133c2aa624ab1266efeeaa26c5c4d7931b31e8f7f585fa361366a/django_blog_package-1.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0e4ed748cadca760ae33da7ef66a4a475a95ed0f6ccea226f8c3438b4f9ab4e9",
"md5": "aadbdf7b7f4551d83b730b2217d68475",
"sha256": "a1c75338f83b069c89144161de9e16e0bedff243a2c751ec69e5d8dbfc29b654"
},
"downloads": -1,
"filename": "django_blog_package-1.0.7.tar.gz",
"has_sig": false,
"md5_digest": "aadbdf7b7f4551d83b730b2217d68475",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 49154,
"upload_time": "2025-10-21T05:49:44",
"upload_time_iso_8601": "2025-10-21T05:49:44.201552Z",
"url": "https://files.pythonhosted.org/packages/0e/4e/d748cadca760ae33da7ef66a4a475a95ed0f6ccea226f8c3438b4f9ab4e9/django_blog_package-1.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-21 05:49:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "josephbraide",
"github_project": "django-blog-package",
"github_not_found": true,
"lcname": "django-blog-package"
}