commit
20ebc17caa
@ -0,0 +1,39 @@
|
||||
# Django project
|
||||
/media/
|
||||
/static/
|
||||
*.sqlite3
|
||||
|
||||
# Python and others
|
||||
__pycache__
|
||||
*.pyc
|
||||
.DS_Store
|
||||
*.swp
|
||||
/venv/
|
||||
/tmp/
|
||||
/.vagrant/
|
||||
/Vagrantfile.local
|
||||
node_modules/
|
||||
/npm-debug.log
|
||||
/.idea/
|
||||
.vscode
|
||||
coverage
|
||||
.python-version
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
@ -0,0 +1,4 @@
|
||||
db.sqlite3
|
||||
__pycache__/
|
||||
venv/
|
||||
media/
|
@ -0,0 +1,60 @@
|
||||
# Use an official Python runtime based on Debian 10 "buster" as a parent image.
|
||||
FROM python:3.8.1-slim-buster
|
||||
|
||||
# Add user that will be used in the container.
|
||||
RUN useradd wagtail
|
||||
|
||||
# Port used by this container to serve HTTP.
|
||||
EXPOSE 8000
|
||||
|
||||
# Set environment variables.
|
||||
# 1. Force Python stdout and stderr streams to be unbuffered.
|
||||
# 2. Set PORT variable that is used by Gunicorn. This should match "EXPOSE"
|
||||
# command.
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PORT=8000
|
||||
|
||||
# Install system packages required by Wagtail and Django.
|
||||
RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
libmariadbclient-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
zlib1g-dev \
|
||||
libwebp-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install the application server.
|
||||
RUN pip install "gunicorn==20.0.4"
|
||||
|
||||
# Install the project requirements.
|
||||
COPY requirements.txt /
|
||||
RUN pip install -r /requirements.txt
|
||||
|
||||
# Use /app folder as a directory where the source code is stored.
|
||||
WORKDIR /app
|
||||
|
||||
# Set this directory to be owned by the "wagtail" user. This Wagtail project
|
||||
# uses SQLite, the folder needs to be owned by the user that
|
||||
# will be writing to the database file.
|
||||
RUN chown wagtail:wagtail /app
|
||||
|
||||
# Copy the source code of the project into the container.
|
||||
COPY --chown=wagtail:wagtail . .
|
||||
|
||||
# Use user "wagtail" to run the build commands below and the server itself.
|
||||
USER wagtail
|
||||
|
||||
# Collect static files.
|
||||
RUN python manage.py collectstatic --noinput --clear
|
||||
|
||||
# Runtime command that executes when "docker run" is called, it does the
|
||||
# following:
|
||||
# 1. Migrate the database.
|
||||
# 2. Start the application server.
|
||||
# WARNING:
|
||||
# Migrating database at the same time as starting the server IS NOT THE BEST
|
||||
# PRACTICE. The database should be migrated manually or using the release
|
||||
# phase facilities of your hosting platform. This is used only so the
|
||||
# Wagtail instance can be started with a simple "docker run" command.
|
||||
CMD set -xe; python manage.py migrate --noinput; gunicorn stairfield.wsgi:application
|
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class FrontendConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "frontend"
|
@ -0,0 +1,108 @@
|
||||
# Generated by Django 4.2.6 on 2023-11-02 16:52
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("wagtailcore", "0089_log_entry_data_json_null_to_object"),
|
||||
("wagtailimages", "0025_alter_image_file_alter_rendition_file"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="LandingPage",
|
||||
fields=[
|
||||
(
|
||||
"page_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="wagtailcore.page",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
bases=("wagtailcore.page",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="LandingPageImage",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("caption", models.CharField(max_length=255)),
|
||||
(
|
||||
"image",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="wagtailimages.image",
|
||||
),
|
||||
),
|
||||
(
|
||||
"owner",
|
||||
modelcluster.fields.ParentalKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="carousel_image",
|
||||
to="frontend.landingpage",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="LandingPageFeature",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("caption", models.CharField(max_length=255)),
|
||||
(
|
||||
"image",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="wagtailimages.image",
|
||||
),
|
||||
),
|
||||
(
|
||||
"owner",
|
||||
modelcluster.fields.ParentalKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="featured_page",
|
||||
to="frontend.landingpage",
|
||||
),
|
||||
),
|
||||
(
|
||||
"page",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="wagtailcore.page",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
@ -0,0 +1,53 @@
|
||||
from django.db import models
|
||||
from wagtail.admin.panels import FieldPanel, InlinePanel
|
||||
from wagtail.images.models import Image
|
||||
from wagtail.models import Page, ParentalKey
|
||||
from wagtail.snippets.models import register_snippet
|
||||
|
||||
|
||||
class LandingPage(Page):
|
||||
content_panels = Page.content_panels + [
|
||||
InlinePanel('carousel_images', label='Carousel images'),
|
||||
InlinePanel('featured_pages', label='Featured pages'),
|
||||
]
|
||||
|
||||
|
||||
@register_snippet
|
||||
class LandingPageImage(models.Model):
|
||||
owner = ParentalKey(
|
||||
LandingPage,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='carousel_images',
|
||||
)
|
||||
image = models.ForeignKey(Image, on_delete=models.SET_NULL, null=True)
|
||||
caption = models.CharField(max_length=255)
|
||||
|
||||
panels = [
|
||||
FieldPanel('image'),
|
||||
FieldPanel('caption'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.caption
|
||||
|
||||
|
||||
@register_snippet
|
||||
class LandingPageFeature(models.Model):
|
||||
owner = ParentalKey(
|
||||
LandingPage,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='featured_pages',
|
||||
)
|
||||
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True)
|
||||
image = models.ForeignKey(Image, on_delete=models.SET_NULL, null=True)
|
||||
caption = models.CharField(max_length=255)
|
||||
|
||||
panels = [
|
||||
FieldPanel('page'),
|
||||
FieldPanel('image'),
|
||||
FieldPanel('caption'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.page.title
|
||||
|
@ -0,0 +1,51 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load wagtailimages_tags %}
|
||||
|
||||
{% block content %}
|
||||
<div id="maincarousel" class="carousel slide py-5" data-bs-theme="dark" data-bs-ride="true">
|
||||
<div class="carousel-inner">
|
||||
{% for cimg in self.carousel_images.all %}
|
||||
<div class="carousel-item {% if forloop.first %}active{% endif %}">
|
||||
{% image cimg.image width-1200 as fimg %}
|
||||
<img src="{{ fimg.url }}" class="d-block mx-auto" style="max-width:100%;">
|
||||
<div class="carousel-caption bottom-0">
|
||||
<p class="text-bg-dark fs-5 d-flex d-md-block">{{ cimg.caption }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="carousel-indicators">
|
||||
{% for cimg in self.carousel_images.all %}
|
||||
<button type="button"
|
||||
data-bs-target="#maincarousel"
|
||||
data-bs-slide-to="{{ forloop.counter0 }}"
|
||||
{% if forloop.first %}
|
||||
class="active"
|
||||
aria-current="true"
|
||||
{% endif %}
|
||||
aria-label="Slide {{ forloop.counter }}"></button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<button class="carousel-control-prev"
|
||||
type="button"
|
||||
data-bs-target="#maincarousel"
|
||||
data-bs-slide="prev">
|
||||
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">Previous</span>
|
||||
</button>
|
||||
<button class="carousel-control-next"
|
||||
type="button"
|
||||
data-bs-target="#maincarousel"
|
||||
data-bs-slide="next">
|
||||
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">Next</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex g-3">
|
||||
{% for p in self.featured_pages.all %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "stairfield.settings.dev")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
execute_from_command_line(sys.argv)
|
@ -0,0 +1,33 @@
|
||||
anyascii==0.3.2
|
||||
asgiref==3.7.2
|
||||
beautifulsoup4==4.11.2
|
||||
certifi==2023.7.22
|
||||
charset-normalizer==3.3.1
|
||||
defusedxml==0.7.1
|
||||
Django==4.2.6
|
||||
django-filter==23.3
|
||||
django-modelcluster==6.1
|
||||
django-permissionedforms==0.1
|
||||
django-taggit==4.0.0
|
||||
django-treebeard==4.7
|
||||
djangorestframework==3.14.0
|
||||
draftjs-exporter==2.1.7
|
||||
et-xmlfile==1.1.0
|
||||
filetype==1.2.0
|
||||
html5lib==1.1
|
||||
idna==3.4
|
||||
l18n==2021.3
|
||||
openpyxl==3.1.2
|
||||
Pillow==10.1.0
|
||||
pillow-heif==0.13.1
|
||||
pytz==2023.3.post1
|
||||
requests==2.31.0
|
||||
six==1.16.0
|
||||
soupsieve==2.5
|
||||
sqlparse==0.4.4
|
||||
telepath==0.3.1
|
||||
typing-extensions==4.8.0
|
||||
urllib3==2.0.7
|
||||
wagtail==5.2
|
||||
webencodings==0.5.1
|
||||
willow==1.6.2
|
@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static wagtailcore_tags %}
|
||||
|
||||
{% block body_class %}template-searchresults{% endblock %}
|
||||
|
||||
{% block title %}Search{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Search</h1>
|
||||
|
||||
<form action="{% url 'search' %}" method="get">
|
||||
<input type="text" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
|
||||
<input type="submit" value="Search" class="button">
|
||||
</form>
|
||||
|
||||
{% if search_results %}
|
||||
<ul>
|
||||
{% for result in search_results %}
|
||||
<li>
|
||||
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
|
||||
{% if result.search_description %}
|
||||
{{ result.search_description }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if search_results.has_previous %}
|
||||
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&page={{ search_results.previous_page_number }}">Previous</a>
|
||||
{% endif %}
|
||||
|
||||
{% if search_results.has_next %}
|
||||
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&page={{ search_results.next_page_number }}">Next</a>
|
||||
{% endif %}
|
||||
{% elif search_query %}
|
||||
No results found
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -0,0 +1,38 @@
|
||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||
from django.template.response import TemplateResponse
|
||||
|
||||
from wagtail.models import Page
|
||||
from wagtail.search.models import Query
|
||||
|
||||
|
||||
def search(request):
|
||||
search_query = request.GET.get("query", None)
|
||||
page = request.GET.get("page", 1)
|
||||
|
||||
# Search
|
||||
if search_query:
|
||||
search_results = Page.objects.live().search(search_query)
|
||||
query = Query.get(search_query)
|
||||
|
||||
# Record hit
|
||||
query.add_hit()
|
||||
else:
|
||||
search_results = Page.objects.none()
|
||||
|
||||
# Pagination
|
||||
paginator = Paginator(search_results, 10)
|
||||
try:
|
||||
search_results = paginator.page(page)
|
||||
except PageNotAnInteger:
|
||||
search_results = paginator.page(1)
|
||||
except EmptyPage:
|
||||
search_results = paginator.page(paginator.num_pages)
|
||||
|
||||
return TemplateResponse(
|
||||
request,
|
||||
"search/search.html",
|
||||
{
|
||||
"search_query": search_query,
|
||||
"search_results": search_results,
|
||||
},
|
||||
)
|
@ -0,0 +1,5 @@
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def stairfield_context(_request):
|
||||
return {'SF_TITLE': settings.SF_TITLE}
|
@ -0,0 +1,167 @@
|
||||
"""
|
||||
Django settings for stairfield project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 4.1.4.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/4.1/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
|
||||
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
BASE_DIR = os.path.dirname(PROJECT_DIR)
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'frontend',
|
||||
"search",
|
||||
"wagtail.contrib.forms",
|
||||
"wagtail.contrib.redirects",
|
||||
"wagtail.embeds",
|
||||
"wagtail.sites",
|
||||
"wagtail.users",
|
||||
"wagtail.snippets",
|
||||
"wagtail.documents",
|
||||
"wagtail.images",
|
||||
"wagtail.search",
|
||||
"wagtail.admin",
|
||||
"wagtail",
|
||||
"modelcluster",
|
||||
"taggit",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "stairfield.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [
|
||||
os.path.join(PROJECT_DIR, "templates"),
|
||||
],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
'stairfield.context_processors.stairfield_context',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "stairfield.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/4.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
||||
|
||||
STATICFILES_FINDERS = [
|
||||
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||
]
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(PROJECT_DIR, "static"),
|
||||
]
|
||||
|
||||
# ManifestStaticFilesStorage is recommended in production, to prevent outdated
|
||||
# JavaScript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
|
||||
# See https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
|
||||
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
|
||||
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||
MEDIA_URL = "/media/"
|
||||
|
||||
|
||||
# Wagtail settings
|
||||
|
||||
WAGTAIL_SITE_NAME = "stairfield"
|
||||
|
||||
# Search
|
||||
# https://docs.wagtail.org/en/stable/topics/search/backends.html
|
||||
WAGTAILSEARCH_BACKENDS = {
|
||||
"default": {
|
||||
"BACKEND": "wagtail.search.backends.database",
|
||||
}
|
||||
}
|
||||
|
||||
# Base URL to use when referring to full URLs within the Wagtail admin backend -
|
||||
# e.g. in notification emails. Don't include '/admin' or a trailing slash
|
||||
WAGTAILADMIN_BASE_URL = "http://example.com"
|
@ -0,0 +1,18 @@
|
||||
from .base import *
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "django-insecure-^x9)z(yc6yg8x)2ujv*%@g&&&#!&35oncve35vpxo^_!q0e+%)"
|
||||
|
||||
# SECURITY WARNING: define the correct hosts in production!
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
|
||||
|
||||
try:
|
||||
from .local import *
|
||||
except ImportError:
|
||||
pass
|
@ -0,0 +1,8 @@
|
||||
from .base import *
|
||||
|
||||
DEBUG = False
|
||||
|
||||
try:
|
||||
from .local import *
|
||||
except ImportError:
|
||||
pass
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 918 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 36 KiB |
@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Page not found{% endblock %}
|
||||
|
||||
{% block body_class %}template-404{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Page not found</h1>
|
||||
|
||||
<h2>Sorry, this page could not be found.</h2>
|
||||
{% endblock %}
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Internal server error</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Internal server error</h1>
|
||||
|
||||
<h2>Sorry, there seems to be an error. Please try again soon.</h2>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,3 @@
|
||||
{% load static %}
|
||||
|
||||
<img src="{% static 'images/favicon.ico' %}" alt="Pacific Stair" />
|
@ -0,0 +1,97 @@
|
||||
{% load static wagtailcore_tags wagtailuserbar %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>
|
||||
{% block title %}
|
||||
{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title }}{% endif %}
|
||||
{% endblock %} |
|
||||
{% block title_suffix %}
|
||||
{{ SF_TITLE }}
|
||||
{% endblock %}
|
||||
</title>
|
||||
{% if page.search_description %}
|
||||
<meta name="description" content="{{ page.search_description }}" />
|
||||
{% endif %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
{# Force all links in the live preview panel to be opened in a new tab #}
|
||||
{% if request.in_preview_panel %}
|
||||
<base target="_blank">
|
||||
{% endif %}
|
||||
|
||||
<link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" type="image/png" />
|
||||
|
||||
{# Global stylesheets #}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/stairfield.css' %}">
|
||||
|
||||
{# Bootstrap CSS #}
|
||||
<link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">
|
||||
|
||||
{% block extra_css %}
|
||||
{# Override this in templates to add extra stylesheets #}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="{% block body_class %}bg-secondary{% endblock %}"
|
||||
style="background-image:url({% static 'images/home-bg.png' %});background-attachment:fixed;background-repeat:no-repeat;background-size:auto 100%;">
|
||||
{% wagtailuserbar %}
|
||||
|
||||
<header class="bg-light">
|
||||
<div class="container p-0">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
|
||||
<a href="/" class="d-flex align-items-center py-2 my-2 my-lg-0 me-lg-auto" title="Home">
|
||||
<img src="{% static 'images/logo-lg-transparent-bg-color.png' %}"
|
||||
alt="Pacific Stair Co"
|
||||
height="60" />
|
||||
</a>
|
||||
<p class="text-end text-uppercase text-primary">
|
||||
Complete commercial egress solutions. Call us!
|
||||
<a href="tel:+18884778247">888.477.8247</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center py-2 bg-primary">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">HOME</a></li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">PROJECTS</a></li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">DOWNLOADS</a></li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle text-light fs-5" data-bs-toggle="dropdown" role="button">PRODUCTS</a>
|
||||
<ul class="dropdown-menu text-bg-primary">
|
||||
<li class="nav-item dropdown-item"><a href="/" class="nav-link text-light fs-5">Stairs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">SERVICES</a></li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">CREDENTIALS</a></li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">ABOUT</a></li>
|
||||
<li class="nav-item"><a href="/" class="nav-link text-light fs-5">CONTACT</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container bg-light">
|
||||
{% block content %}
|
||||
CONTENT PLACEHOLDER
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer class="position-relative bottom-0 start-0 end-0 pt-5 pb-1 px-3 my-0 bg-dark text-light">
|
||||
<p>© 2023 Pacific Stair Corporation. All rights reserved.</p>
|
||||
</footer>
|
||||
|
||||
{# Global javascript #}
|
||||
<script type="text/javascript" src="{% static 'js/stairfield.js' %}"></script>
|
||||
|
||||
{# Bootstrap JS #}
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
{% block extra_js %}
|
||||
{# Override this in templates to add extra javascript #}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,5 @@
|
||||
{% extends 'wagtailadmin/404.html' %}
|
||||
|
||||
{% block branding_logo %}
|
||||
{% include "_logo.html" %}
|
||||
{% endblock %}
|
@ -0,0 +1,12 @@
|
||||
{% extends 'wagtailadmin/base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block branding_favicon %}
|
||||
<link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block branding_logo %}
|
||||
{% include "_logo.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block branding_title %}{{ SF_TITLE }}{% endblock %}
|
@ -0,0 +1,3 @@
|
||||
{% extends 'wagtailadmin/home.html' %}
|
||||
|
||||
{% block branding_welcome %}Welcome to {{ SF_TITLE }}{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'wagtailadmin/login.html' %}
|
||||
|
||||
{% block branding_logo %}
|
||||
{% include "_logo.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block branding_login %}Log in to {{ SF_TITLE }}{% endblock %}
|
@ -0,0 +1,5 @@
|
||||
{% extends 'wagtailadmin/userbar/base.html' %}
|
||||
|
||||
{% block branding_logo %}
|
||||
{% include "_logo.html" %}
|
||||
{% endblock %}
|
@ -0,0 +1,35 @@
|
||||
from django.conf import settings
|
||||
from django.urls import include, path
|
||||
from django.contrib import admin
|
||||
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail import urls as wagtail_urls
|
||||
from wagtail.documents import urls as wagtaildocs_urls
|
||||
|
||||
from search import views as search_views
|
||||
|
||||
urlpatterns = [
|
||||
path("django-admin/", admin.site.urls),
|
||||
path("admin/", include(wagtailadmin_urls)),
|
||||
path("documents/", include(wagtaildocs_urls)),
|
||||
path("search/", search_views.search, name="search"),
|
||||
]
|
||||
|
||||
|
||||
if settings.DEBUG:
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
# Serve static and media files from development server
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
urlpatterns = urlpatterns + [
|
||||
# For anything not caught by a more specific rule above, hand over to
|
||||
# Wagtail's page serving mechanism. This should be the last pattern in
|
||||
# the list:
|
||||
path("", include(wagtail_urls)),
|
||||
# Alternatively, if you want Wagtail pages to be served from a subpath
|
||||
# of your site, rather than the site root:
|
||||
# path("pages/", include(wagtail_urls)),
|
||||
]
|
@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for stairfield project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "stairfield.settings.dev")
|
||||
|
||||
application = get_wsgi_application()
|
Loading…
Reference in new issue