OWASP-BLT / BLT

OWASP BLT is tool with the purpose of making the web a safer place. We have many facets to the project.
https://blt.owasp.org
GNU Affero General Public License v3.0
136 stars 135 forks source link

Create a blog section #2803

Open DonnieBLT opened 3 days ago

DonnieBLT commented 3 days ago

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

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//', views.PostDetailView.as_view(), name='post_detail'), path('post/new/', views.PostCreateView.as_view(), name='post_create'), path('post//edit/', views.PostUpdateView.as_view(), name='post_update'), path('post//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

{% 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 }}

{% 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 commented 6 hours ago

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

github-actions[bot] commented 6 hours ago

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 commented 5 hours ago

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