Skip to content
Merged
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
Empty file addedapp/pages/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions app/pages/admin.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
from django.contrib import admin

from .models import Page

# Register your models here.
admin.site.register(Page)
6 changes: 6 additions & 0 deletions app/pages/apps.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class PagesConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "app.pages"
33 changes: 33 additions & 0 deletions app/pages/migrations/0001_initial.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
# Generated by Django 5.2.7 on 2025-11-30 07:16

import tinymce.models
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Page',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('slug', models.SlugField(max_length=255, unique=True)),
('content', tinymce.models.HTMLField()),
('is_published', models.BooleanField(default=False)),
('meta_description', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Page',
'verbose_name_plural': 'Pages',
'ordering': ['-created_at'],
},
),
]
18 changes: 18 additions & 0 deletions app/pages/migrations/0002_alter_page_slug.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2025-11-30 07:19

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('pages', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='page',
name='slug',
field=models.SlugField(blank=True, max_length=255, unique=True),
),
]
Empty file.
26 changes: 26 additions & 0 deletions app/pages/models.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
from django.db import models
from django.utils.text import slugify
from tinymce.models import HTMLField


class Page(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True, blank=True)
content = HTMLField()
is_published = models.BooleanField(default=False)
meta_description = models.TextField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)

def __str__(self):
return self.title

class Meta:
ordering = ["-created_at"]
verbose_name = "Page"
verbose_name_plural = "Pages"
22 changes: 22 additions & 0 deletions app/pages/templates/pages/detail.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main>
<div class="min-h-screen bg-contain bg-center" style="background-image: url('{% static 'img/bg-conference-at-glance.png' %}');">
<!-- Navbar -->
{% include "home/components/navbar.html" %}
<!-- Content Block (specific page content) -->
<div class="max-w-3xl mx-auto px-6 pt-40 pb-18">
<article class="max-w-4xl mx-auto bg-white rounded-lg shadow-lg p-8">
<h1 class="text-4xl font-bold mb-4">{{page.title }}</h1>
<div class="prose prose-lg max-w-none">
{{page.content|safe }}
</div>
</article>
</div>

<!-- Footer -->
{% include "home/sections/footer.html" %}
</div>
</main>
{% endblock %}
3 changes: 3 additions & 0 deletions app/pages/tests.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
fromdjango.testimportTestCase

# Create your tests here.
9 changes: 9 additions & 0 deletions app/pages/urls.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
from django.urls import path

from app.pages.views import PageDetailView

app_name = "pages"

urlpatterns = [
path("<slug:slug>/", PageDetailView.as_view(), name="detail"),
]
12 changes: 12 additions & 0 deletions app/pages/views.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
from django.views.generic import DetailView

from app.pages.models import Page


class PageDetailView(DetailView):
model = Page
template_name = "pages/detail.html"
context_object_name = "page"

def get_queryset(self):
return Page.objects.filter(is_published=True)
2 changes: 2 additions & 0 deletions config/settings.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,6 +53,7 @@
"corsheaders",
"django_tailwind_cli",
"bakery",
"tinymce",
]

if settings.APP_ENV == "development":
Expand All@@ -62,6 +63,7 @@
"app.home",
"app.speakers",
"app.sponsors",
"app.pages",
]

INSTALLED_APPS = [
Expand Down
1 change: 1 addition & 0 deletions config/urls.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("app.home.urls")),
path("pages/", include("app.pages.urls")),
]

urlpatterns.append(path("__reload__/", include("django_browser_reload.urls")))
Expand Down