commit
7f7e6a4090
@ -0,0 +1 @@
|
||||
media/
|
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class BlogConfig(AppConfig):
|
||||
name = "blog"
|
@ -0,0 +1,34 @@
|
||||
# Generated by Django 2.1.2 on 2018-11-11 02:20
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import wagtail.core.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [("wagtailcore", "0040_page_draft_title")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="BlogIndexPage",
|
||||
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",
|
||||
),
|
||||
),
|
||||
("intro", wagtail.core.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={"abstract": False},
|
||||
bases=("wagtailcore.page",),
|
||||
)
|
||||
]
|
@ -0,0 +1,34 @@
|
||||
# Generated by Django 2.1.2 on 2018-11-11 02:58
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import wagtail.core.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [("wagtailcore", "0040_page_draft_title"), ("blog", "0001_initial")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="BlogPage",
|
||||
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",
|
||||
),
|
||||
),
|
||||
("date", models.DateField(verbose_name="Post date")),
|
||||
("intro", models.CharField(max_length=250)),
|
||||
("body", wagtail.core.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={"abstract": False},
|
||||
bases=("wagtailcore.page",),
|
||||
)
|
||||
]
|
@ -0,0 +1,52 @@
|
||||
# Generated by Django 2.1.2 on 2018-11-16 18:45
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("wagtailimages", "0021_image_file_hash"),
|
||||
("blog", "0002_blogpage"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="BlogPageGalleryImage",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"sort_order",
|
||||
models.IntegerField(blank=True, editable=False, null=True),
|
||||
),
|
||||
("caption", models.CharField(blank=True, max_length=250)),
|
||||
(
|
||||
"image",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="+",
|
||||
to="wagtailimages.Image",
|
||||
),
|
||||
),
|
||||
(
|
||||
"page",
|
||||
modelcluster.fields.ParentalKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="gallery_images",
|
||||
to="blog.BlogPage",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"ordering": ["sort_order"], "abstract": False},
|
||||
)
|
||||
]
|
@ -0,0 +1,33 @@
|
||||
# Generated by Django 2.1.2 on 2018-11-19 19:50
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import modelcluster.contrib.taggit
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('taggit', '0002_auto_20150616_2121'),
|
||||
('blog', '0003_blogpagegalleryimage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BlogPageTag',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='blog.BlogPage')),
|
||||
('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='blog_blogpagetag_items', to='taggit.Tag')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogpage',
|
||||
name='tags',
|
||||
field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='blog.BlogPageTag', to='taggit.Tag', verbose_name='Tags'),
|
||||
),
|
||||
]
|
@ -0,0 +1,25 @@
|
||||
# Generated by Django 2.1.2 on 2018-11-19 20:04
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0040_page_draft_title'),
|
||||
('blog', '0004_auto_20181119_1950'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BlogTagIndexPage',
|
||||
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',),
|
||||
),
|
||||
]
|
@ -0,0 +1,117 @@
|
||||
from django.db import models
|
||||
|
||||
from modelcluster.fields import ParentalKey
|
||||
from modelcluster.contrib.taggit import ClusterTaggableManager
|
||||
from taggit.models import TaggedItemBase
|
||||
|
||||
from wagtail.core.models import Page, Orderable
|
||||
from wagtail.core.fields import RichTextField
|
||||
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, MultiFieldPanel
|
||||
from wagtail.images.edit_handlers import ImageChooserPanel
|
||||
from wagtail.search import index
|
||||
|
||||
|
||||
class BlogIndexPage(Page):
|
||||
"""Entry point of the blog. Displays its children `BlogPages`"""
|
||||
|
||||
intro = RichTextField(blank=True)
|
||||
|
||||
content_panels = Page.content_panels + [FieldPanel("intro", classname="full")]
|
||||
|
||||
def get_context(self, request, *args, **kwargs):
|
||||
"""
|
||||
Overrides the default context to include only published pages, ordered by reverse chronological order.
|
||||
These child pages can be accessed in the template using `blogpages` instead of page.get_children.
|
||||
"""
|
||||
context = super().get_context(request)
|
||||
blogpages = self.get_children().live().order_by("-first_published_at")
|
||||
context["blogpages"] = blogpages
|
||||
return context
|
||||
|
||||
|
||||
class BlogPageTag(TaggedItemBase):
|
||||
"""Provides a simple tagging feature to Blog Pages"""
|
||||
|
||||
content_object = ParentalKey(
|
||||
"BlogPage", related_name="tagged_items", on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
|
||||
class BlogPage(Page):
|
||||
"""Models a blog page entry."""
|
||||
|
||||
date = models.DateField("Post date")
|
||||
intro = models.CharField(max_length=250)
|
||||
body = RichTextField(blank=True)
|
||||
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
|
||||
|
||||
def main_image(self):
|
||||
"""Returns the first image associated with a `BlogPage` from `BlogPageGalleryImage`"""
|
||||
gallery_item = self.gallery_images.first()
|
||||
if gallery_item:
|
||||
return gallery_item.image
|
||||
else:
|
||||
return None
|
||||
|
||||
search_fields = Page.search_fields + [
|
||||
index.SearchField("intro"),
|
||||
index.SearchField("body"),
|
||||
]
|
||||
|
||||
content_panels = Page.content_panels + [
|
||||
# Grouping Date and tags together for readability in the Admin panel
|
||||
MultiFieldPanel(
|
||||
[FieldPanel("date"), FieldPanel("tags")], heading="Blog information"
|
||||
),
|
||||
FieldPanel("intro"),
|
||||
FieldPanel("body", classname="full"),
|
||||
InlinePanel("gallery_images", label="Gallery images"),
|
||||
]
|
||||
|
||||
|
||||
class BlogPageGalleryImage(Orderable):
|
||||
"""
|
||||
An image gallery descendant to a `BlogPage`
|
||||
|
||||
Inherits a `sort_order` field from the `Orderable` object which keeps track of image ordering.
|
||||
The `ParentalKey` works similarly to a `ForeignKey` but also defines this class as a child of `BlogPage` model.
|
||||
This means that the image gallery associated with a particular `BlogPage` instance is treated as a part of the page
|
||||
in operations like submitting for moderation, and tracking version history.
|
||||
|
||||
The `BlogPageGalleryImage.image` is a `ForeignKey to the Wagtail built-in `Image` model where images themselves are
|
||||
stored. The `ImageChooserPanel` provides a popup interface for choosing an existing image or uploading a new one.
|
||||
This allows for the same image to exist in multiple galleries - effectively creating a many-to-many relationship
|
||||
between pages and images.
|
||||
"""
|
||||
|
||||
page = ParentalKey(
|
||||
BlogPage, on_delete=models.CASCADE, related_name="gallery_images"
|
||||
)
|
||||
image = models.ForeignKey(
|
||||
# on_delete here means that is an image is deleted from the system, the gallery entry is deleted as well.
|
||||
"wagtailimages.Image",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="+",
|
||||
)
|
||||
caption = models.CharField(blank=True, max_length=250)
|
||||
|
||||
panels = [ImageChooserPanel("image"), FieldPanel("caption")]
|
||||
|
||||
|
||||
class BlogTagIndexPage(Page):
|
||||
"""
|
||||
Models the Index page of blogs by tag.
|
||||
|
||||
Even though this model does not define any fields of its own, it is a subclass of Page and is added to the Wagtail
|
||||
ecosystem. This means that it can be given a title and a URL in the admin
|
||||
|
||||
"""
|
||||
|
||||
def get_context(self, request, *args, **kwargs):
|
||||
"""Filters by tage passed in request query string"""
|
||||
tag = request.GET.get('tag')
|
||||
blogpages = BlogPage.objects.filter(tags__name=tag)
|
||||
|
||||
context = super().get_context(request)
|
||||
context['blogpages'] = blogpages
|
||||
return context
|
@ -0,0 +1,40 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
{% block body_class %}helvetica{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include 'header.html' %}
|
||||
|
||||
<section class="mw7 center bg-white-10">
|
||||
<h1 class="ph3 ph0-l">{{ page.title }}</h1>
|
||||
|
||||
{% for post in blogpages %}
|
||||
{% with post=post.specific %}
|
||||
<article class="pv4 bt bb b--black-10 ph3 ph0-l">
|
||||
<a class="db pv4 ph3 ph0-l no-underline black dim" href="{% pageurl post %}">
|
||||
<div class="flex flex-column flex-row-ns">
|
||||
<div class="w-100 w-60-ns pr3-ns order-2 order-1-ns">
|
||||
<h1 class="f3 mt0 lh-title">{{ post.title }}</h1>
|
||||
<p class="f5 f4-l lh-copy">{{ post.intro }}</p>
|
||||
</div>
|
||||
<div class="pl3-ns order-1 order-2-ns mb4 mb0-ns w-100 w-40-ns">
|
||||
{% with post.main_image as main_image %}
|
||||
{% if main_image %}{% image main_image fill-320x240 class="db" %}{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
<p class="f6 lh-copy gray mv0">By <span class="ttu">{{ post.owner }}</span></p>
|
||||
<time class="f6 db gray">{{ post.date|date }}</time>
|
||||
</a>
|
||||
</article>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
</section>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,30 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
{% block body_class %}helvetica{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include 'header.html' %}
|
||||
<article class="ph3 ph3-ns center mw8">
|
||||
<h1>{{ page.title }}</h1>
|
||||
<p class="meta">{{ page.date }}</p>
|
||||
{% if page.tags.all.count %}
|
||||
<div class="dib">
|
||||
{% for tag in page.tags.all %}
|
||||
<a href="{% slugurl 'tags' %}?tag={{ tag }}" class="f6 link dim br1 ph3 pv2 mb2 dib white bg-black">{{ tag }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ page.body|richtext }}
|
||||
|
||||
{% for item in page.gallery_images.all %}
|
||||
<div class="fl ma1">
|
||||
{% image item.image fill-320x240 %}
|
||||
<p> {{ item.caption }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</article>
|
||||
{% endblock %}
|
@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
{% block body_class %}helvetica{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include 'header.html' %}
|
||||
<section class="mw7 center">
|
||||
{% if request.GET.tag|length %}
|
||||
<h1 class="ph3 ph0-l">Showing pages tagged "{{ request.GET.tag }}"</h1>
|
||||
{% endif %}
|
||||
|
||||
{% for post in blogpages %}
|
||||
{% with post=post.specific %}
|
||||
<article class="pv4 bt bb b--black-10 ph3 ph0-l">
|
||||
<a class="db pv4 ph3 ph0-l no-underline black dim" href="{% pageurl post %}">
|
||||
<div class="flex flex-column flex-row-ns">
|
||||
<div class="w-100 w-60-ns pr3-ns order-2 order-1-ns">
|
||||
<h1 class="f3 mt0 lh-title">{{ post.title }}</h1>
|
||||
<p class="f5 f4-l lh-copy">{{ post.intro }}</p>
|
||||
</div>
|
||||
<div class="pl3-ns order-1 order-2-ns mb4 mb0-ns w-100 w-40-ns">
|
||||
{% with post.main_image as main_image %}
|
||||
{% if main_image %}{% image main_image fill-320x240 class="db" %}{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
<p class="f6 lh-copy gray mv0">By <span class="ttu">{{ post.owner }}</span></p>
|
||||
<time class="f6 db gray">{{ post.date|date }}</time>
|
||||
</a>
|
||||
</article>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
No pages found with that tag.
|
||||
{% endfor %}
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
@ -0,0 +1,9 @@
|
||||
.bg-grad-blue {
|
||||
background-image: linear-gradient(-208deg, #86C3D0 0%, #4E90A3 66%); }
|
||||
|
||||
.bg-grad-green {
|
||||
background-image: linear-gradient(to top right, #41b782, #86D169); }
|
||||
|
||||
.hover-bg-orange:hover {
|
||||
background-color: #FF6300;
|
||||
transition: all .3s ease; }
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||
<rect x="1" y="1" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" width="46" height="62"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="9" y1="63" x2="9" y2="2"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="14" y1="15" x2="42" y2="15"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="14" y1="21" x2="42" y2="21"/>
|
||||
<polygon fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="63,3 63,53 59,61 55,53 55,3 "/>
|
||||
<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="55,7 51,7 51,17 "/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="36" y1="34" x2="41" y2="39"/>
|
||||
<rect x="46.257" y="35.065" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 120.5036 47.0858)" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" width="8.485" height="26.87"/>
|
||||
<polygon fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="12,16 18,10 8,4 6,6 "/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="28" y1="26" x2="15" y2="13"/>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" d="M58,12.5l-8,3.75l-4-4.125l3.5-8.062l0,0
|
||||
C39.5,4.062,37,9,37,14v4L3.5,52l-1.75,6l2.125,2l6.062-1.5L44,25h4C53,25,58,22.5,58,12.5L58,12.5z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="6" y1="25" x2="58" y2="25"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="6" y1="33" x2="58" y2="33"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="6" y1="41" x2="58" y2="41"/>
|
||||
<rect x="1" y="7" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" width="62" height="50"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="1" y1="15" x2="63" y2="15"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="10" y1="11" x2="6" y2="11"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="18" y1="11" x2="14" y2="11"/>
|
||||
<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="26" y1="11" x2="22" y2="11"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.7 MiB |
@ -0,0 +1,12 @@
|
||||
.bg-grad-blue {
|
||||
background-image: linear-gradient(-208deg, #86C3D0 0%, #4E90A3 66%);
|
||||
}
|
||||
|
||||
.bg-grad-green {
|
||||
background-image: linear-gradient(to top right, #41b782, #86D169);
|
||||
}
|
||||
|
||||
.hover-bg-orange:hover {
|
||||
background-color: #FF6300;
|
||||
transition: all .3s ease;
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<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>
|
||||
<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>
|
||||
<h2>Sorry, there seems to be an error. Please try again soon.</h2>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,10 @@
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
<footer class="pv5 pv6-ns ph3 ph5-m ph6-l white-70 bg-black-50">
|
||||
<small class="f6 db tc">© 2018 <span class="ttu f5 fw3">Andrew Bednar</span>, All Rights Reserved</small>
|
||||
<div class="tc mt3">
|
||||
<a href="/terms/" title="Terms" class="f5 dib ph2 link white-70 dim mb2">Terms of Use</a>
|
||||
<a href="/privacy/" title="Privacy" class="f5 dib ph2 link white-70 dim mb2">Privacy</a>
|
||||
<a href="http://linea.io/" title="Privacy" class="f5 dib ph2 link white-70 dim mb2">Icons by Dario Ferrando</a>
|
||||
</div>
|
||||
</footer>
|
@ -0,0 +1,20 @@
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
<header class="dt w-100 bg-grad-blue ph2 ph3-ns ph3-m">
|
||||
<div id="logo" class="dtc v-mid">
|
||||
<a href="{% slugurl 'home' %}" class="f2-ns f3 fw6 link dim white mr3">Datasketch.io</a>
|
||||
</div>
|
||||
<nav class="dtc tr fw6 f6 pv3 pv4-ns pv4-m pv4-l ttu tracked">
|
||||
<a href="{% slugurl 'blog' %}" class="no-underline dim white mr2 mr3-ns dn dib-l dib-m">Blog</a>
|
||||
<a href="{% slugurl 'home' %}#services" class="no-underline dim white mr2 mr3-ns dn dib-l dib-m">Services</a>
|
||||
<!-- <a href="{% slugurl 'blog' %}" class="no-underline dim white mr2 mr3-ns dn dib-l dib-m">Portfolio</a> -->
|
||||
<a href="{% slugurl 'home' %}#connect" class="hover-bg-orange no-underline white mr2 mr3-ns ba pv2 ph3 br1 dn dib-l dib-m">Connect</a>
|
||||
<a href="{% slugurl 'home' %}" class="dib dn-ns w2 h2 pa1 br1 ba b--white-90 grow-large border-box">
|
||||
<svg class="link white-90 hover-white" data-icon="skull" viewBox="0 0 32 32" style="fill:currentcolor"><title>
|
||||
skull icon</title>
|
||||
<path
|
||||
d="M16 0 C6 0 2 4 2 14 L2 22 L6 24 L6 30 L26 30 L26 24 L30 22 L30 14 C30 4 26 0 16 0 M9 12 A4.5 4.5 0 0 1 9 21 A4.5 4.5 0 0 1 9 12 M23 12 A4.5 4.5 0 0 1 23 21 A4.5 4.5 0 0 1 23 12"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
@ -1,10 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
{% block body_class %}helvetica{% endblock %}
|
||||
{% block body_class %}helvetica bg-black-10{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Welcome to Datasketch.io!</h1>
|
||||
{{ page.body|richtext }}
|
||||
<div class="cover bg-left bg-center-l" style="background-image: url({% static 'img/programming_background.jpg' %})">
|
||||
<div class="bg-black-80 pb5 pb6-m pb7-l">
|
||||
{% include "header.html" %}
|
||||
<div id="hero-text" class="tc-l mt4 mt5-m mt6-l ph3">
|
||||
<h1 class="f2 f1-l fw2 white-90 mb0 lh-title">Hire Datasketch</h1>
|
||||
<h2 class="fw1 f3 white-80 mt3 mb4">A full stack shop for web design, application development, and training</h2>
|
||||
<a href="#connect" class="f6 no-underline grow dib v-mid bg-orange white ba bn ph3 pv2 mb3 br1 tracked">Connect</a>
|
||||
<span class="dib v-mid ph3 white-70 mb3">or</span>
|
||||
<a class="f6 no-underline grow dib v-mid white ba b--white ph3 pv2 mb3 br1" href="{% slugurl 'blog' %}" ">Read our blog</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<main id="services" class="pv4 ph2 tc">
|
||||
<h1 class="f2 fw6">Just a man trying to make a buck</h1>
|
||||
<div class="flex-ns justify-center-ns">
|
||||
<article class="mw5 dib bg-white br1 pa3 pa4-ns mv3 mr4-l ba b--black-10 shadow-4">
|
||||
<div class="tc">
|
||||
<img src="{% static 'icon/basic_book_pen.svg' %}" class="h3 w3 dib" title="Photo of a kitty staring at you">
|
||||
<h1 class="f4">Training</h1>
|
||||
<hr class="mw3 bb bw1 b--black-10">
|
||||
</div>
|
||||
<p class="lh-copy measure f6 black-70">
|
||||
As a college educator I learned what does and does not work for students. I strive to bring each of my students
|
||||
along thier learning journey.
|
||||
</p>
|
||||
</article>
|
||||
<article class="mw5 dib bg-white br1 pa3 pa4-ns mv3 mr4-l ba b--black-10 shadow-4">
|
||||
<div class="tc">
|
||||
<img src="{% static 'icon/basic_webpage_txt.svg' %}" class="h3 w3 dib" title="web-icon">
|
||||
<h1 class="f4">Websites</h1>
|
||||
<hr class="mw3 bb bw1 b--black-10">
|
||||
</div>
|
||||
<p class="h3 lh-copy measure center f6 black-70">
|
||||
Design & Development, eCommerce, Responsive Design. I can deliver you a stunning website.
|
||||
</p>
|
||||
</article>
|
||||
<article class="mw5 dib bg-white br1 pa3 pa4-ns mv3 mr4-l ba b--black-10 shadow-4">
|
||||
<div class="tc">
|
||||
<img src="{% static 'icon/basic_settings.svg' %}" class="h3 w3 dib" title="App development icon">
|
||||
<h1 class="f4">App Development</h1>
|
||||
<hr class="mw3 bb bw1 b--black-10">
|
||||
</div>
|
||||
<p class="lh-copy measure center f6 black-70">
|
||||
Quite affectionate and outgoing.
|
||||
She loves to get chin scratches and will
|
||||
roll around on the floor waiting for you give her more of them.
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
<div id="connect" class="bg-grad-blue tc pv5 pv6-ns ph2">
|
||||
<div class="mw6 center">
|
||||
<h1 class="white f2 fw5 mb5">Together we can make great things.</h1>
|
||||
<form class="" action="">
|
||||
<input class="input-reset w-100 w-45-ns mb3 pv2 ba br1 b--black-10" type="text" name="fullname" placeholder="Full Name">
|
||||
<input class="input-reset w-100 mb3 pv2 ba br1 b--black-10 mail-icon" type="email" name="email" placeholder="Email">
|
||||
<br>
|
||||
<textarea class="input-reset w-100 h4 mb3 pv2 ba br1 b--black-10" name="comments" placeholder="Comments"></textarea>
|
||||
<br>
|
||||
<button class="f5 dim fw5 dib v-mid bg-orange white ba bn ph3 pv2 mb3 br1 tracked">Talk to the developer!</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% include "footer.html" %}
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue