summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan DeMasi <jonathan.demasi@colorado.edu>2020-03-02 15:31:38 -0700
committerJonathan DeMasi <jonathan.demasi@colorado.edu>2020-03-02 15:31:38 -0700
commit4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a (patch)
tree5bb2626573e30aeb9fe6fddab490170ebe86e43e
parent8234155d407d0bfd1f6d6218fde59b09337294cb (diff)
downloadjthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar.gz
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar.bz2
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar.lz
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar.xz
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.tar.zst
jthanio-4872b099ccd2ddd4e6baa31b7a2b3cf391237a7a.zip
init wagtail
-rw-r--r--Dockerfile27
-rw-r--r--home/__init__.py0
-rw-r--r--home/migrations/0001_initial.py22
-rw-r--r--home/migrations/0002_create_homepage.py58
-rw-r--r--home/migrations/__init__.py0
-rw-r--r--home/models.py7
-rw-r--r--home/static/css/welcome_page.css204
-rw-r--r--home/templates/home/home_page.html21
-rw-r--r--home/templates/home/welcome_page.html52
-rw-r--r--jthanio/__init__.py0
-rw-r--r--jthanio/settings/__init__.py0
-rw-r--r--jthanio/settings/base.py163
-rw-r--r--jthanio/settings/dev.py18
-rw-r--r--jthanio/settings/production.py8
-rw-r--r--jthanio/static/css/jthanio.css0
-rw-r--r--jthanio/static/js/jthanio.js0
-rw-r--r--jthanio/templates/404.html9
-rw-r--r--jthanio/templates/500.html13
-rw-r--r--jthanio/templates/base.html40
-rw-r--r--jthanio/urls.py39
-rw-r--r--jthanio/wsgi.py16
-rwxr-xr-xmanage.py10
-rw-r--r--requirements.txt2
-rw-r--r--search/__init__.py0
-rw-r--r--search/templates/search/search.html38
-rw-r--r--search/views.py34
26 files changed, 781 insertions, 0 deletions
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..130c09d
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,27 @@
+# Use an official Python runtime as a parent image
+FROM python:3.7
+LABEL maintainer="hello@wagtail.io"
+
+# Set environment varibles
+ENV PYTHONUNBUFFERED 1
+ENV DJANGO_ENV dev
+
+COPY ./requirements.txt /code/requirements.txt
+RUN pip install --upgrade pip
+# Install any needed packages specified in requirements.txt
+RUN pip install -r /code/requirements.txt
+RUN pip install gunicorn
+
+# Copy the current directory contents into the container at /code/
+COPY . /code/
+# Set the working directory to /code/
+WORKDIR /code/
+
+RUN python manage.py migrate
+
+RUN useradd wagtail
+RUN chown -R wagtail /code
+USER wagtail
+
+EXPOSE 8000
+CMD exec gunicorn jthanio.wsgi:application --bind 0.0.0.0:8000 --workers 3
diff --git a/home/__init__.py b/home/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/home/__init__.py
diff --git a/home/migrations/0001_initial.py b/home/migrations/0001_initial.py
new file mode 100644
index 0000000..ef46d12
--- /dev/null
+++ b/home/migrations/0001_initial.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wagtailcore', '0040_page_draft_title'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='HomePage',
+ fields=[
+ ('page_ptr', models.OneToOneField(on_delete=models.CASCADE, parent_link=True, auto_created=True, primary_key=True, serialize=False, to='wagtailcore.Page')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=('wagtailcore.page',),
+ ),
+ ]
diff --git a/home/migrations/0002_create_homepage.py b/home/migrations/0002_create_homepage.py
new file mode 100644
index 0000000..039f0f5
--- /dev/null
+++ b/home/migrations/0002_create_homepage.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+from django.db import migrations
+
+
+def create_homepage(apps, schema_editor):
+ # Get models
+ ContentType = apps.get_model('contenttypes.ContentType')
+ Page = apps.get_model('wagtailcore.Page')
+ Site = apps.get_model('wagtailcore.Site')
+ HomePage = apps.get_model('home.HomePage')
+
+ # Delete the default homepage
+ # If migration is run multiple times, it may have already been deleted
+ Page.objects.filter(id=2).delete()
+
+ # Create content type for homepage model
+ homepage_content_type, __ = ContentType.objects.get_or_create(
+ model='homepage', app_label='home')
+
+ # Create a new homepage
+ homepage = HomePage.objects.create(
+ title="Home",
+ draft_title="Home",
+ slug='home',
+ content_type=homepage_content_type,
+ path='00010001',
+ depth=2,
+ numchild=0,
+ url_path='/home/',
+ )
+
+ # Create a site with the new homepage set as the root
+ Site.objects.create(
+ hostname='localhost', root_page=homepage, is_default_site=True)
+
+
+def remove_homepage(apps, schema_editor):
+ # Get models
+ ContentType = apps.get_model('contenttypes.ContentType')
+ HomePage = apps.get_model('home.HomePage')
+
+ # Delete the default homepage
+ # Page and Site objects CASCADE
+ HomePage.objects.filter(slug='home', depth=2).delete()
+
+ # Delete content type for homepage model
+ ContentType.objects.filter(model='homepage', app_label='home').delete()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('home', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RunPython(create_homepage, remove_homepage),
+ ]
diff --git a/home/migrations/__init__.py b/home/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/home/migrations/__init__.py
diff --git a/home/models.py b/home/models.py
new file mode 100644
index 0000000..af7b579
--- /dev/null
+++ b/home/models.py
@@ -0,0 +1,7 @@
+from django.db import models
+
+from wagtail.core.models import Page
+
+
+class HomePage(Page):
+ pass
diff --git a/home/static/css/welcome_page.css b/home/static/css/welcome_page.css
new file mode 100644
index 0000000..ce8b149
--- /dev/null
+++ b/home/static/css/welcome_page.css
@@ -0,0 +1,204 @@
+html {
+ box-sizing: border-box;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+body {
+ max-width: 960px;
+ min-height: 100vh;
+ margin: 0 auto;
+ padding: 0 15px;
+ color: #231f20;
+ font-family: 'Helvetica Neue', 'Segoe UI', Arial, sans-serif;
+ line-height: 1.25;
+}
+
+a {
+ background-color: transparent;
+ color: #308282;
+ text-decoration: underline;
+}
+
+a:hover {
+ color: #ea1b10;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+p,
+ul {
+ padding: 0;
+ margin: 0;
+ font-weight: 400;
+}
+
+main {
+ display: block; /* For IE11 support */
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-top: 20px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #e6e6e6;
+}
+
+.logo {
+ width: 150px;
+ margin-right: 20px;
+}
+
+.logo a {
+ display: block;
+}
+
+.figure-logo {
+ max-width: 150px;
+ max-height: 55.1px;
+}
+
+.release-notes {
+ font-size: 14px;
+}
+
+.main {
+ padding: 40px 0;
+ margin: 0 auto;
+ text-align: center;
+}
+
+.figure-space {
+ max-width: 265px;
+}
+
+@-webkit-keyframes pos {
+ 0%, 100% {
+ -webkit-transform: rotate(-6deg);
+ transform: rotate(-6deg);
+ }
+ 50% {
+ -webkit-transform: rotate(6deg);
+ transform: rotate(6deg);
+ }
+}
+
+@keyframes pos {
+ 0%, 100% {
+ -webkit-transform: rotate(-6deg);
+ transform: rotate(-6deg);
+ }
+ 50% {
+ -webkit-transform: rotate(6deg);
+ transform: rotate(6deg);
+ }
+}
+
+.egg {
+ fill: #43b1b0;
+ -webkit-animation: pos 3s ease infinite;
+ animation: pos 3s ease infinite;
+ -webkit-transform: translateY(50px);
+ transform: translateY(50px);
+ -webkit-transform-origin: 50% 80%;
+ transform-origin: 50% 80%;
+}
+
+.main-text {
+ max-width: 400px;
+ margin: 5px auto;
+}
+
+.main-text h1 {
+ font-size: 22px;
+}
+
+.main-text p {
+ margin: 15px auto 0;
+}
+
+.footer {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ border-top: 1px solid #e6e6e6;
+ padding: 10px;
+}
+
+.option {
+ display: block;
+ padding: 10px 10px 10px 34px;
+ position: relative;
+ text-decoration: none;
+}
+
+.option svg {
+ width: 24px;
+ height: 24px;
+ fill: gray;
+ border: 1px solid #d9d9d9;
+ padding: 5px;
+ border-radius: 100%;
+ top: 10px;
+ left: 0;
+ position: absolute;
+}
+
+.option h4 {
+ font-size: 19px;
+ text-decoration: underline;
+}
+
+.option p {
+ padding-top: 3px;
+ color: #231f20;
+ font-size: 15px;
+ font-weight: 300;
+}
+
+@media (max-width: 996px) {
+ body {
+ max-width: 780px;
+ }
+}
+
+@media (max-width: 767px) {
+ .option {
+ flex: 0 0 50%;
+ }
+}
+
+@media (max-width: 599px) {
+ .main {
+ padding: 20px 0;
+ }
+
+ .figure-space {
+ max-width: 200px;
+ }
+
+ .footer {
+ display: block;
+ width: 300px;
+ margin: 0 auto;
+ }
+}
+
+@media (max-width: 360px) {
+ .header-link {
+ max-width: 100px;
+ }
+}
diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html
new file mode 100644
index 0000000..db9e9b0
--- /dev/null
+++ b/home/templates/home/home_page.html
@@ -0,0 +1,21 @@
+{% extends "base.html" %}
+{% load static %}
+
+{% block body_class %}template-homepage{% endblock %}
+
+{% block extra_css %}
+
+{% comment %}
+Delete the line below if you're just getting started and want to remove the welcome screen!
+{% endcomment %}
+<link rel="stylesheet" href="{% static 'css/welcome_page.css' %}">
+{% endblock extra_css %}
+
+{% block content %}
+
+{% comment %}
+Delete the line below if you're just getting started and want to remove the welcome screen!
+{% endcomment %}
+{% include 'home/welcome_page.html' %}
+
+{% endblock content %}
diff --git a/home/templates/home/welcome_page.html b/home/templates/home/welcome_page.html
new file mode 100644
index 0000000..4c988b1
--- /dev/null
+++ b/home/templates/home/welcome_page.html
@@ -0,0 +1,52 @@
+{% load i18n wagtailcore_tags %}
+
+<header class="header" role="banner">
+ <div class="logo">
+ <a href="https://wagtail.io/">
+ <svg class="figure-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 342.5 126.2"><title>{% trans "Visit the Wagtail website" %}</title><path fill="#FFF" d="M84 1.9v5.7s-10.2-3.8-16.8 3.1c-4.8 5-5.2 10.6-3 18.1 21.6 0 25 12.1 25 12.1L87 27l6.8-8.3c0-9.8-8.1-16.3-9.8-16.8z"/><circle cx="85.9" cy="15.9" r="2.6"/><path d="M89.2 40.9s-3.3-16.6-24.9-12.1c-2.2-7.5-1.8-13 3-18.1C73.8 3.8 84 7.6 84 7.6V1.9C80.4.3 77 0 73.2 0 59.3 0 51.6 10.4 48.3 17.4L9.2 89.3l11-2.1-20.2 39 14.1-2.5L24.9 93c30.6 0 69.8-11 64.3-52.1z"/><path d="M102.4 27l-8.6-8.3L87 27z"/><path fill="#FFF" d="M30 84.1s1-.2 2.8-.6c1.8-.4 4.3-1 7.3-1.8 1.5-.4 3.1-.9 4.8-1.5 1.7-.6 3.5-1.2 5.2-2 1.8-.7 3.6-1.6 5.4-2.6 1.8-1 3.5-2.1 5.1-3.4.4-.3.8-.6 1.2-1l1.2-1c.7-.7 1.5-1.4 2.2-2.2.7-.7 1.3-1.5 1.9-2.3l.9-1.2.4-.6.4-.6c.2-.4.5-.8.7-1.2.2-.4.4-.8.7-1.2l.3-.6.3-.6c.2-.4.4-.8.5-1.2l.9-2.4c.2-.8.5-1.6.7-2.3.2-.7.3-1.5.5-2.1.1-.7.2-1.3.3-2 .1-.6.2-1.2.2-1.7.1-.5.1-1 .2-1.5.1-1.8.1-2.8.1-2.8l1.6.1s-.1 1.1-.2 2.9c-.1.5-.1 1-.2 1.5-.1.6-.1 1.2-.3 1.8-.1.6-.3 1.3-.4 2-.2.7-.4 1.4-.6 2.2-.2.8-.5 1.5-.8 2.4-.3.8-.6 1.6-1 2.5l-.6 1.2-.3.6-.3.6c-.2.4-.5.8-.7 1.3-.3.4-.5.8-.8 1.2-.1.2-.3.4-.4.6l-.4.6-.9 1.2c-.7.8-1.3 1.6-2.1 2.3-.7.8-1.5 1.4-2.3 2.2l-1.2 1c-.4.3-.8.6-1.3.9-1.7 1.2-3.5 2.3-5.3 3.3-1.8.9-3.7 1.8-5.5 2.5-1.8.7-3.6 1.3-5.3 1.8-1.7.5-3.3 1-4.9 1.3-3 .7-5.6 1.3-7.4 1.6-1.6.6-2.6.8-2.6.8z"/><g fill="#231F20"><path d="M127 83.9h-8.8l-12.6-36.4h7.9l9 27.5 9-27.5h7.9l9 27.5 9-27.5h7.9L153 83.9h-8.8L135.6 59 127 83.9zM200.1 83.9h-7V79c-3 3.6-7 5.4-12.1 5.4-3.8 0-6.9-1.1-9.4-3.2s-3.7-5-3.7-8.6c0-3.6 1.3-6.3 4-8 2.6-1.8 6.2-2.7 10.7-2.7h9.9v-1.4c0-4.8-2.7-7.3-8.1-7.3-3.4 0-6.9 1.2-10.5 3.7l-3.4-4.8c4.4-3.5 9.4-5.3 15.1-5.3 4.3 0 7.8 1.1 10.5 3.2 2.7 2.2 4.1 5.6 4.1 10.2v23.7zm-7.7-13.6v-3.1h-8.6c-5.5 0-8.3 1.7-8.3 5.2 0 1.8.7 3.1 2.1 4.1 1.4.9 3.3 1.4 5.7 1.4 2.4 0 4.6-.7 6.4-2.1 1.8-1.3 2.7-3.1 2.7-5.5zM241.7 47.5v31.7c0 6.4-1.7 11.3-5.2 14.5-3.5 3.2-8 4.8-13.4 4.8-5.5 0-10.4-1.7-14.8-5.1l3.6-5.8c3.6 2.7 7.1 4 10.8 4 3.6 0 6.5-.9 8.6-2.8 2.1-1.9 3.2-4.9 3.2-9v-4.7c-1.1 2.1-2.8 3.9-4.9 5.1-2.1 1.3-4.5 1.9-7.1 1.9-4.8 0-8.8-1.7-11.9-5.1-3.1-3.4-4.7-7.6-4.7-12.6s1.6-9.2 4.7-12.6c3.1-3.4 7.1-5.1 11.9-5.1 4.8 0 8.7 2 11.7 6v-5.4h7.5zm-28.4 16.8c0 3 .9 5.6 2.8 7.7 1.8 2.2 4.3 3.2 7.5 3.2 3.1 0 5.7-1 7.6-3.1 1.9-2.1 2.9-4.7 2.9-7.8 0-3.1-1-5.8-2.9-7.9-2-2.2-4.5-3.2-7.6-3.2-3.1 0-5.6 1.1-7.4 3.4-2 2.1-2.9 4.7-2.9 7.7zM260.9 53.6v18.5c0 1.7.5 3.1 1.4 4.1.9 1 2.2 1.5 3.8 1.5 1.6 0 3.2-.8 4.7-2.4l3.1 5.4c-2.7 2.4-5.7 3.6-8.9 3.6-3.3 0-6-1.1-8.3-3.4-2.3-2.3-3.5-5.3-3.5-9.1V53.6h-4.6v-6.2h4.6V36.1h7.7v11.4h9.6v6.2h-9.6zM309.5 83.9h-7V79c-3 3.6-7 5.4-12.1 5.4-3.8 0-6.9-1.1-9.4-3.2s-3.7-5-3.7-8.6c0-3.6 1.3-6.3 4-8 2.6-1.8 6.2-2.7 10.7-2.7h9.9v-1.4c0-4.8-2.7-7.3-8.1-7.3-3.4 0-6.9 1.2-10.5 3.7l-3.4-4.8c4.4-3.5 9.4-5.3 15.1-5.3 4.3 0 7.8 1.1 10.5 3.2 2.7 2.2 4.1 5.6 4.1 10.2v23.7zm-7.7-13.6v-3.1h-8.6c-5.5 0-8.3 1.7-8.3 5.2 0 1.8.7 3.1 2.1 4.1 1.4.9 3.3 1.4 5.7 1.4 2.4 0 4.6-.7 6.4-2.1 1.8-1.3 2.7-3.1 2.7-5.5zM319.3 40.2c-1-1-1.4-2.1-1.4-3.4 0-1.3.5-2.5 1.4-3.4 1-1 2.1-1.4 3.4-1.4 1.3 0 2.5.5 3.4 1.4 1 1 1.4 2.1 1.4 3.4 0 1.3-.5 2.5-1.4 3.4s-2.1 1.4-3.4 1.4c-1.3.1-2.4-.4-3.4-1.4zm7.2 43.7h-7.7V47.5h7.7v36.4zM342.5 83.9h-7.7V33.1h7.7v50.8z"/></g></svg>
+ </a>
+ </div>
+ <div class="header-link">
+ {% comment %}
+ This works for all cases but prerelease versions:
+ {% endcomment %}
+ <a href="{% wagtail_documentation_path %}/releases/{% wagtail_release_notes_path %}">
+ {% trans "View the release notes" %}
+ </a>
+ </div>
+</header>
+<main class="main">
+ <div class="figure">
+ <svg class="figure-space" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" aria-hidden="true">
+ <path class="egg" fill="currentColor" d="M150 250c-42.741 0-75-32.693-75-90s42.913-110 75-110c32.088 0 75 52.693 75 110s-32.258 90-75 90z"/>
+ <ellipse fill="#ddd" cx="150" cy="270" rx="40" ry="7"/>
+ </svg>
+ </div>
+ <div class="main-text">
+ <h1>{% trans "Welcome to your new Wagtail site!" %}</h1>
+ <p>{% trans 'Please feel free to <a href="https://github.com/wagtail/wagtail/wiki/Slack">join our community on Slack</a>, or get started with one of the links below.' %}</p>
+ </div>
+</main>
+<footer class="footer" role="contentinfo">
+ <a class="option option-one" href="{% wagtail_documentation_path %}/">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 21c0 .5.4 1 1 1h4c.6 0 1-.5 1-1v-1H9v1zm3-19C8.1 2 5 5.1 5 9c0 2.4 1.2 4.5 3 5.7V17c0 .5.4 1 1 1h6c.6 0 1-.5 1-1v-2.3c1.8-1.3 3-3.4 3-5.7 0-3.9-3.1-7-7-7zm2.9 11.1l-.9.6V16h-4v-2.3l-.9-.6C7.8 12.2 7 10.6 7 9c0-2.8 2.2-5 5-5s5 2.2 5 5c0 1.6-.8 3.2-2.1 4.1z"/></svg>
+ <div>
+ <h4>{% trans "Wagtail Documentation" %}</h4>
+ <p>{% trans "Topics, references, & how-tos" %}</p>
+ </div>
+ </a>
+ <a class="option option-two" href="{% wagtail_documentation_path %}/getting_started/tutorial.html">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>
+ <div>
+ <h4>{% trans "Tutorial" %}</h4>
+ <p>{% trans "Build your first Wagtail site" %}</p>
+ </div>
+ </a>
+ <a class="option option-three" href="{% url 'wagtailadmin_home' %}">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><path d="M0 0h24v24H0z" fill="none"/><path d="M16.5 13c-1.2 0-3.07.34-4.5 1-1.43-.67-3.3-1-4.5-1C5.33 13 1 14.08 1 16.25V19h22v-2.75c0-2.17-4.33-3.25-6.5-3.25zm-4 4.5h-10v-1.25c0-.54 2.56-1.75 5-1.75s5 1.21 5 1.75v1.25zm9 0H14v-1.25c0-.46-.2-.86-.52-1.22.88-.3 1.96-.53 3.02-.53 2.44 0 5 1.21 5 1.75v1.25zM7.5 12c1.93 0 3.5-1.57 3.5-3.5S9.43 5 7.5 5 4 6.57 4 8.5 5.57 12 7.5 12zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 5.5c1.93 0 3.5-1.57 3.5-3.5S18.43 5 16.5 5 13 6.57 13 8.5s1.57 3.5 3.5 3.5zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2z"/></svg>
+ <div>
+ <h4>{% trans "Admin Interface" %}</h4>
+ <p>{% trans "Create your superuser first!" %}</p>
+ </div>
+ </a>
+</footer>
diff --git a/jthanio/__init__.py b/jthanio/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jthanio/__init__.py
diff --git a/jthanio/settings/__init__.py b/jthanio/settings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jthanio/settings/__init__.py
diff --git a/jthanio/settings/base.py b/jthanio/settings/base.py
new file mode 100644
index 0000000..494f905
--- /dev/null
+++ b/jthanio/settings/base.py
@@ -0,0 +1,163 @@
+"""
+Django settings for jthanio project.
+
+Generated by 'django-admin startproject' using Django 3.0.3.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.0/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/3.0/howto/deployment/checklist/
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'home',
+ 'search',
+
+ 'wagtail.contrib.forms',
+ 'wagtail.contrib.redirects',
+ 'wagtail.embeds',
+ 'wagtail.sites',
+ 'wagtail.users',
+ 'wagtail.snippets',
+ 'wagtail.documents',
+ 'wagtail.images',
+ 'wagtail.search',
+ 'wagtail.admin',
+ 'wagtail.core',
+
+ '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.core.middleware.SiteMiddleware',
+ 'wagtail.contrib.redirects.middleware.RedirectMiddleware',
+]
+
+ROOT_URLCONF = 'jthanio.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',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'jthanio.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.0/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/3.0/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/3.0/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/3.0/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/3.0/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 = "jthanio"
+
+# 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
+BASE_URL = 'http://example.com'
diff --git a/jthanio/settings/dev.py b/jthanio/settings/dev.py
new file mode 100644
index 0000000..14d9ee4
--- /dev/null
+++ b/jthanio/settings/dev.py
@@ -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 = 'hwq)dss*tg_p#ryuqvr)d*hk3785$13r=#kffh++1-de_5za!y'
+
+# 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
diff --git a/jthanio/settings/production.py b/jthanio/settings/production.py
new file mode 100644
index 0000000..9ca4ed7
--- /dev/null
+++ b/jthanio/settings/production.py
@@ -0,0 +1,8 @@
+from .base import *
+
+DEBUG = False
+
+try:
+ from .local import *
+except ImportError:
+ pass
diff --git a/jthanio/static/css/jthanio.css b/jthanio/static/css/jthanio.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jthanio/static/css/jthanio.css
diff --git a/jthanio/static/js/jthanio.js b/jthanio/static/js/jthanio.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jthanio/static/js/jthanio.js
diff --git a/jthanio/templates/404.html b/jthanio/templates/404.html
new file mode 100644
index 0000000..3a5500e
--- /dev/null
+++ b/jthanio/templates/404.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block body_class %}template-404{% endblock %}
+
+{% block content %}
+ <h1>Page not found</h1>
+
+ <h2>Sorry, this page could not be found.</h2>
+{% endblock %}
diff --git a/jthanio/templates/500.html b/jthanio/templates/500.html
new file mode 100644
index 0000000..72b6406
--- /dev/null
+++ b/jthanio/templates/500.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html class="no-js">
+ <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>
diff --git a/jthanio/templates/base.html b/jthanio/templates/base.html
new file mode 100644
index 0000000..82a3fe8
--- /dev/null
+++ b/jthanio/templates/base.html
@@ -0,0 +1,40 @@
+{% load static wagtailuserbar %}
+
+<!DOCTYPE html>
+<html class="no-js" lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>
+ {% block title %}
+ {% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}
+ {% endblock %}
+ {% block title_suffix %}
+ {% with self.get_site.site_name as site_name %}
+ {% if site_name %}- {{ site_name }}{% endif %}
+ {% endwith %}
+ {% endblock %}
+ </title>
+ <meta name="description" content="" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+
+ {# Global stylesheets #}
+ <link rel="stylesheet" type="text/css" href="{% static 'css/jthanio.css' %}">
+
+ {% block extra_css %}
+ {# Override this in templates to add extra stylesheets #}
+ {% endblock %}
+ </head>
+
+ <body class="{% block body_class %}{% endblock %}">
+ {% wagtailuserbar %}
+
+ {% block content %}{% endblock %}
+
+ {# Global javascript #}
+ <script type="text/javascript" src="{% static 'js/jthanio.js' %}"></script>
+
+ {% block extra_js %}
+ {# Override this in templates to add extra javascript #}
+ {% endblock %}
+ </body>
+</html>
diff --git a/jthanio/urls.py b/jthanio/urls.py
new file mode 100644
index 0000000..89cfde3
--- /dev/null
+++ b/jthanio/urls.py
@@ -0,0 +1,39 @@
+from django.conf import settings
+from django.conf.urls import include, url
+from django.contrib import admin
+
+from wagtail.admin import urls as wagtailadmin_urls
+from wagtail.core import urls as wagtail_urls
+from wagtail.documents import urls as wagtaildocs_urls
+
+from search import views as search_views
+
+urlpatterns = [
+ url(r'^django-admin/', admin.site.urls),
+
+ url(r'^admin/', include(wagtailadmin_urls)),
+ url(r'^documents/', include(wagtaildocs_urls)),
+
+ url(r'^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:
+ url(r"", include(wagtail_urls)),
+
+ # Alternatively, if you want Wagtail pages to be served from a subpath
+ # of your site, rather than the site root:
+ # url(r"^pages/", include(wagtail_urls)),
+]
diff --git a/jthanio/wsgi.py b/jthanio/wsgi.py
new file mode 100644
index 0000000..8d50879
--- /dev/null
+++ b/jthanio/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for jthanio 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/3.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jthanio.settings.dev")
+
+application = get_wsgi_application()
diff --git a/manage.py b/manage.py
new file mode 100755
index 0000000..d76f65b
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jthanio.settings.dev")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..eca1c97
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+Django>=3.0,<3.1
+wagtail>=2.8,<2.9
diff --git a/search/__init__.py b/search/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/search/__init__.py
diff --git a/search/templates/search/search.html b/search/templates/search/search.html
new file mode 100644
index 0000000..5f222e5
--- /dev/null
+++ b/search/templates/search/search.html
@@ -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 }}&amp;page={{ search_results.previous_page_number }}">Previous</a>
+ {% endif %}
+
+ {% if search_results.has_next %}
+ <a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.next_page_number }}">Next</a>
+ {% endif %}
+ {% elif search_query %}
+ No results found
+ {% endif %}
+{% endblock %}
diff --git a/search/views.py b/search/views.py
new file mode 100644
index 0000000..eeace7c
--- /dev/null
+++ b/search/views.py
@@ -0,0 +1,34 @@
+from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
+from django.shortcuts import render
+
+from wagtail.core.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 render(request, 'search/search.html', {
+ 'search_query': search_query,
+ 'search_results': search_results,
+ })