Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a blog section #2803

Closed
DonnieBLT opened this issue Oct 20, 2024 · 8 comments
Closed

Create a blog section #2803

DonnieBLT opened this issue Oct 20, 2024 · 8 comments

Comments

@DonnieBLT
Copy link
Collaborator

Django Blog Implementation with Markdown Support

Objective: Enhance the existing Django website by adding a full-featured blog. The blog should store content in Markdown format and provide a Markdown editor with preview functionality. The new blog should integrate seamlessly with the existing base.html template, which includes top and left navigation.

Requirements

  • Skip initial project setup: Assume the Django project is already created and configured.
  • Beautiful Blog Design: Focus on aesthetics to ensure the blog is visually appealing.
  • Markdown Content: Store and render blog posts written in Markdown.
  • Markdown Editor with Preview: Implement an editor that allows users to write in Markdown with real-time preview.

Implementation Steps

  1. Create a New Django App

    • Name the app blog.
    • Add blog to INSTALLED_APPS in settings.py.
  2. Define the Blog Post Model in blog/models.py

    from django.db import models
    from django.contrib.auth.models import User
    from django.urls import reverse
    
    class Post(models.Model):
        title = models.CharField(max_length=200)
        slug = models.SlugField(unique=True)
        author = models.ForeignKey(User, on_delete=models.CASCADE)
        content = models.TextField()
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return self.title
    
        def get_absolute_url(self):
            return reverse('post_detail', kwargs={'slug': self.slug})
    
     3.	Register the Post Model in blog/admin.py

from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created_at')
prepopulated_fields = {'slug': ('title',)}

4.	Create Views in blog/views.py
•	List View: Display all blog posts.
•	Detail View: Show individual blog post with rendered Markdown.
•	Create View: Allow users to create new posts using a Markdown editor.
•	Update View: Allow users to edit their posts.
•	Delete View: Allow users to delete their posts.

from django.views import generic
from .models import Post
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
import markdown

class PostListView(generic.ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
paginate_by = 5

class PostDetailView(generic.DetailView):
model = Post
template_name = 'blog/post_detail.html'

def get_object(self):
    post = super().get_object()
    post.content = markdown.markdown(post.content)
    return post

class PostCreateView(LoginRequiredMixin, generic.CreateView):
model = Post
fields = ['title', 'content']
template_name = 'blog/post_form.html'

def form_valid(self, form):
    form.instance.author = self.request.user
    return super().form_valid(form)

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, generic.UpdateView):
model = Post
fields = ['title', 'content']
template_name = 'blog/post_form.html'

def form_valid(self, form):
    form.instance.author = self.request.user
    return super().form_valid(form)

def test_func(self):
    post = self.get_object()
    return self.request.user == post.author

class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, generic.DeleteView):
model = Post
template_name = 'blog/post_confirm_delete.html'
success_url = '/'

def test_func(self):
    post = self.get_object()
    return self.request.user == post.author


5.	Configure URLs in blog/urls.py

from django.urls import path
from . import views

urlpatterns = [
path('', views.PostListView.as_view(), name='post_list'),
path('post/slug:slug/', views.PostDetailView.as_view(), name='post_detail'),
path('post/new/', views.PostCreateView.as_view(), name='post_create'),
path('post/slug:slug/edit/', views.PostUpdateView.as_view(), name='post_update'),
path('post/slug:slug/delete/', views.PostDeleteView.as_view(), name='post_delete'),
]

6.	Include Blog URLs in Project’s urls.py

from django.urls import path, include

urlpatterns = [
path('blog/', include('blog.urls')),
# Other URL patterns...
]

7.	Create Templates Extending base.html
•	Template Directory: blog/templates/blog/
•	Templates:
•	post_list.html
•	post_detail.html
•	post_form.html
•	post_confirm_delete.html

Example post_list.html:

{% extends 'base.html' %}

{% block content %}

Blog Posts

    {% for post in posts %}
  • {{ post.title }} by {{ post.author }}
  • {% empty %}

    No posts available.

    {% endfor %}
{% endblock %}
8.	Integrate Markdown Editor with Preview
•	Choose an Editor: Use EasyMDE.
•	Include EasyMDE Assets in base.html or specific templates.

Update post_form.html:

{% extends 'base.html' %}

{% block content %}

{% if form.instance.pk %}Edit{% else %}New{% endif %} Post

{% csrf_token %} {{ form.as_p }} Save <script src="https://unpkg.com/easymde/dist/easymde.min.js"></script> <script> var easyMDE = new EasyMDE({ element: document.getElementById('id_content') }); </script> {% endblock %}
9.	Render Markdown in PostDetailView
•	Already handled in the get_object method using markdown.markdown.
10.	Apply Styling for a Beautiful Blog
•	CSS: Add custom styles to match the existing website theme.
•	Responsive Design: Ensure the blog looks good on all devices.

Additional Notes

•	Authentication: Use Django’s built-in authentication for author management.
•	Slug Generation: Automatically generate slugs from titles in the admin and forms.
•	Pagination: Implement pagination in the post list view.
•	SEO Optimization: Use meta tags and structured data.
•	Testing: Write unit tests for models, views, and forms.

By following these steps, you’ll integrate a fully functional and aesthetically pleasing blog into your existing Django website, complete with Markdown support and a live preview editor.

@MrImmortal09
Copy link
Contributor

MrImmortal09 commented Oct 23, 2024

If you aren't working on #2804, Could you please assign me this issue?

Copy link
Contributor

Hello @MrImmortal09! You've been assigned to OWASP-BLT/BLT. You have 24 hours to complete a pull request. To place a bid and potentially earn some BCH, type /bid [amount in BCH] [BCH address].

@krrish-sehgal
Copy link
Contributor

Hey @MrImmortal09 I was also working on the same issue, maybe we can connect on slack ?

@MrImmortal09
Copy link
Contributor

Hey @MrImmortal09 I was also working on the same issue, maybe we can connect on slack ?

Sure, If you are working then I will pick up some different issue, also here is my slack ID: MrImmortal09

@krrish-sehgal
Copy link
Contributor

krrish-sehgal commented Oct 24, 2024

Hey @MrImmortal09 , please go ahead and take on this issue, I have taken up an issue in BLT-Flutter.
thanks.

@MrImmortal09
Copy link
Contributor

I've also taken on another issue, so if anyone else would like to proceed, please feel free to do so.

@krrish-sehgal
Copy link
Contributor

/assign me

Copy link
Contributor

Hello @krrish-sehgal! You've been assigned to OWASP-BLT/BLT. You have 24 hours to complete a pull request. To place a bid and potentially earn some BCH, type /bid [amount in BCH] [BCH address].

@Sarthak5598 Sarthak5598 self-assigned this Oct 30, 2024
Sarthak5598 added a commit to Sarthak5598/BLT that referenced this issue Oct 30, 2024
Sarthak5598 added a commit that referenced this issue Nov 5, 2024
@github-project-automation github-project-automation bot moved this from Backlog to Done in 📌 All Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

4 participants