-
-
Save jtauber/7d6379ad640e4b560363 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/requirements.txt b/requirements.txt | |
index 016a56b..2685f0b 100644 | |
--- a/requirements.txt | |
+++ b/requirements.txt | |
@@ -1,2 +1,7 @@ | |
Django==1.8.5 | |
pinax-theme-bootstrap==7.1.1 | |
+django-bootstrap-form==3.2 | |
+pinax-blog==4.2.1 | |
+pytz==2015.4 | |
+Markdown==2.6.2 | |
+Pillow==2.9.0 | |
diff --git a/project_name/urls.py b/project_name/urls.py | |
index aeb47f8..3af58d3 100644 | |
--- a/project_name/urls.py | |
+++ b/project_name/urls.py | |
@@ -1,8 +1,14 @@ | |
-from django.conf.urls import patterns, url | |
-from django.views.generic import TemplateView | |
+from django.conf import settings | |
+from django.conf.urls import patterns, include, url | |
+from django.conf.urls.static import static | |
+from django.contrib import admin | |
urlpatterns = patterns( | |
"", | |
- url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"), | |
+ url(r"^admin/", include(admin.site.urls)), | |
+ url(r"", include("pinax.blog.urls")), | |
) | |
+ | |
+ | |
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | |
diff --git a/project_name/settings.py b/project_name/settings.py | |
index e24d9a9..267d30d 100644 | |
--- a/project_name/settings.py | |
+++ b/project_name/settings.py | |
@@ -95,6 +95,7 @@ TEMPLATES = [ | |
"django.core.context_processors.request", | |
"django.contrib.messages.context_processors.messages", | |
"pinax_theme_bootstrap.context_processors.theme", | |
+ "{{ project_name }}.context_processors.settings", | |
], | |
}, | |
}, | |
@@ -116,6 +117,7 @@ ROOT_URLCONF = "{{ project_name }}.urls" | |
WSGI_APPLICATION = "{{ project_name }}.wsgi.application" | |
INSTALLED_APPS = [ | |
+ "django.contrib.admin", | |
"django.contrib.auth", | |
"django.contrib.contenttypes", | |
"django.contrib.messages", | |
@@ -127,6 +129,9 @@ INSTALLED_APPS = [ | |
"bootstrapform", | |
"pinax_theme_bootstrap", | |
+ # external | |
+ "pinax.blog", | |
+ | |
# project | |
"{{ project_name }}", | |
] | |
diff --git a/project_name/context_processors.py b/project_name/context_processors.py | |
new file mode 100644 | |
index 0000000..9251599 | |
--- /dev/null | |
+++ b/project_name/context_processors.py | |
@@ -0,0 +1,12 @@ | |
+from django.contrib.sites.models import Site | |
+ | |
+ | |
+def settings(request): | |
+ ctx = {} | |
+ if Site._meta.installed: | |
+ site = Site.objects.get_current() | |
+ ctx.update({ | |
+ "SITE_NAME": site.name, | |
+ "SITE_DOMAIN": site.domain | |
+ }) | |
+ return ctx | |
diff --git a/project_name/templates/admin/blog/post/change_form.html b/project_name/templates/admin/blog/post/change_form.html | |
new file mode 100644 | |
index 0000000..77f2082 | |
--- /dev/null | |
+++ b/project_name/templates/admin/blog/post/change_form.html | |
@@ -0,0 +1,44 @@ | |
+{% extends "admin/change_form.html" %} | |
+{% load i18n admin_urls %} | |
+{% block extrahead %} | |
+ {{ block.super }} | |
+ <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
+ <script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.1.8/ace.js"></script> | |
+ <script> | |
+ $(function () { | |
+ var contentDiv = $("<div>").attr("id", "content-editor"), | |
+ teaserDiv = $("<div>").attr("id", "teaser-editor"), | |
+ setupEditor = function (editor, textarea) { | |
+ editor.setTheme("ace/theme/twilight"); | |
+ editor.getSession().setMode("ace/mode/markdown"); | |
+ editor.getSession().setValue(textarea.val()); | |
+ editor.getSession().setUseWrapMode(true); | |
+ editor.getSession().on('change', function(){ | |
+ textarea.val(editor.getSession().getValue()); | |
+ }); | |
+ editor.getSession().setTabSize(4); | |
+ editor.getSession().setUseSoftTabs(true); | |
+ }; | |
+ $(".field-content div").append(contentDiv); | |
+ $(".field-teaser div").append(teaserDiv); | |
+ var editor1 = ace.edit("content-editor"); | |
+ var editor2 = ace.edit("teaser-editor"); | |
+ var textarea1 = $('textarea[name="content"]').hide(); | |
+ var textarea2 = $('textarea[name="teaser"]').hide(); | |
+ setupEditor(editor1, textarea1); | |
+ setupEditor(editor2, textarea2); | |
+ }); | |
+ </script> | |
+ <style type="text/css" media="screen"> | |
+ #content-editor { | |
+ min-height: 300px; | |
+ width: 80%; | |
+ min-width: 800px; | |
+ } | |
+ #teaser-editor { | |
+ min-height: 100px; | |
+ width: 80%; | |
+ min-width: 800px; | |
+ } | |
+</style> | |
+{% endblock %} | |
\ No newline at end of file | |
diff --git a/project_name/templates/pinax/blog/blog_base.html b/project_name/templates/pinax/blog/blog_base.html | |
new file mode 100644 | |
index 0000000..f7ae532 | |
--- /dev/null | |
+++ b/project_name/templates/pinax/blog/blog_base.html | |
@@ -0,0 +1,51 @@ | |
+{% extends "site_base.html" %} | |
+ | |
+{% load pinax_blog_tags %} | |
+ | |
+{% block body_class %}blog{% endblock %} | |
+ | |
+{% block body %} | |
+ <div class="row blog-container"> | |
+ <div class="col-md-3 sidebar"> | |
+ {% block sidebar %} | |
+ <h1> | |
+ <a href="{% url "blog" %}">{{ SITE_NAME }}</a> | |
+ </h1> | |
+ <p class="lead"> | |
+ This is where you can list your bio, add links | |
+ etc., by editing the <code>pinax/blog/blog_base.html</code> | |
+ template. | |
+ </p> | |
+ <p> | |
+ <a href="{% url 'blog_feed' 'all' 'atom' %}"><i class="fa fa-rss"></i> Atom Feed</a> | |
+ </p> | |
+ <div class="search"> | |
+ {% if section_slug %} | |
+ {% url "blog_section" section_slug as search_url %} | |
+ {% else %} | |
+ {% url "blog" as search_url %} | |
+ {% endif %} | |
+ | |
+ <form class="form-search" action="{{ search_url }}"> | |
+ <label><i class="fa fa-search"></i></label> | |
+ <input class="form-control" type="search" placeholder="Search..." name="q" value="{{ search_term|default:"" }}"> | |
+ </form> | |
+ </div> | |
+ <ul class=""> | |
+ <li class="{% if current_section == "all" %}active{% endif %}"> | |
+ <a href="{% url "blog" %}">All</a> | |
+ </li> | |
+ {% blog_sections as sections %} | |
+ {% for section in sections %} | |
+ <li class="{% if current_section == section %}active{% endif %}"> | |
+ <a href="{% url "blog_section" section.slug %}">{{ section.name }}</a> | |
+ </li> | |
+ {% endfor %} | |
+ </ul> | |
+ {% endblock %} | |
+ </div> | |
+ <div class="col-md-8 blog-content"> | |
+ {% block content %}{% endblock %} | |
+ </div> | |
+ </div> | |
+{% endblock %} | |
diff --git a/project_name/templates/pinax/blog/blog_list.html b/project_name/templates/pinax/blog/blog_list.html | |
new file mode 100644 | |
index 0000000..8bc1304 | |
--- /dev/null | |
+++ b/project_name/templates/pinax/blog/blog_list.html | |
@@ -0,0 +1,23 @@ | |
+{% extends "pinax/blog/blog_base.html" %} | |
+ | |
+{% block head_title_base %}{{ SITE_NAME }}{% endblock %} | |
+ | |
+ | |
+{% block content %} | |
+ <h1>Blog Posts</h1> | |
+ {% if post_list %} | |
+ <div class="post-list"> | |
+ {% for post in post_list %} | |
+ <div class="post"> | |
+ <h2><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h2> | |
+ {% include "pinax/blog/dateline.html" %} | |
+ <div class="teaser">{{ post.teaser_html|safe }}</div> | |
+ <p class="more"><a href="{{ post.get_absolute_url }}" class="post-link">read more...</a></p> | |
+ </div> | |
+ {% endfor %} | |
+ </div> | |
+ {% include "pagination/builtin_pagination_reverse.html" %} | |
+ {% else %} | |
+ <p class="alert alert-info lead">No blog posts have been published.</p> | |
+ {% endif %} | |
+{% endblock %} | |
diff --git a/project_name/templates/pinax/blog/blog_post.html b/project_name/templates/pinax/blog/blog_post.html | |
new file mode 100644 | |
index 0000000..9e2047c | |
--- /dev/null | |
+++ b/project_name/templates/pinax/blog/blog_post.html | |
@@ -0,0 +1,48 @@ | |
+{% extends "pinax/blog/blog_base.html" %} | |
+ | |
+{% block body_class %}blog blog-post{% endblock %} | |
+ | |
+{% block head_title_base %}{{ post.title }} | {{ SITE_NAME }}{% endblock %} | |
+ | |
+{% block extra_head %} | |
+ {{ block.super }} | |
+ <meta name="twitter:card" content="summary"> | |
+ {% comment %} | |
+ <meta name="twitter:image" content="https://pbs.twimg.com/profile_images/62846141/pinaxproject_avatar.png"> | |
+ {% endcomment %} | |
+ <meta property="og:title" content="{{ post.title }}"> | |
+ {% if post.description %} | |
+ <meta name="description" content="{{ post.description }}"> | |
+ <meta property="og:description" content="{{ post.description }}"> | |
+ {% else %} | |
+ <meta name="description" content="{{ post.teaser_html|striptags }}"> | |
+ <meta property="og:description" content="{{ post.teaser_html|striptags }}"> | |
+ {% endif %} | |
+ {% if post.primary_image %} | |
+ <meta property="og:image" content="http://{{ SITE_DOMAIN }}{{ post.primary_image.image_path.url }}"> | |
+ {% else %} | |
+ {% comment %} | |
+ <meta property="og:image" content="https://pbs.twimg.com/profile_images/62846141/pinaxproject_avatar.png"> | |
+ {% endcomment %} | |
+ {% endif %} | |
+ <meta property="og:url" content="http://{{ SITE_DOMAIN }}{{ post.get_absolute_url }}"> | |
+ <meta property="og:type" content="article"> | |
+{% endblock %} | |
+ | |
+{% block content %} | |
+ <div class="post-detail"> | |
+ <div class="post"> | |
+ <h1>{{ post.title }}</h1> | |
+ {% include "pinax/blog/dateline_stale.html" %} | |
+ | |
+ <div class="teaser">{{ post.teaser_html|safe }}</div> | |
+ | |
+ <div class="content">{{ post.content_html|safe }}</div> | |
+ | |
+ <div class="twitter-button"> | |
+ <a href="https://twitter.com/share" class="twitter-share-button" data-via="">Tweet</a> | |
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> | |
+ </div> | |
+ </div> | |
+ </div> | |
+{% endblock %} | |
diff --git a/project_name/templates/pinax/blog/dateline.html b/project_name/templates/pinax/blog/dateline.html | |
new file mode 100644 | |
index 0000000..8fa92b6 | |
--- /dev/null | |
+++ b/project_name/templates/pinax/blog/dateline.html | |
@@ -0,0 +1,5 @@ | |
+<p class="post-meta"> | |
+ <span class="date">{% if post.published %}{{ post.published|date:"jS F Y" }}{% else %}Not published yet{% endif %}</span> / | |
+ by <span class="author">{{ post.author.get_full_name }}</span> in | |
+ <a href="{% url "blog_section" post.section.slug %}"><span class="section">{{ post.section.name }}</span></a> | |
+</p> | |
diff --git a/project_name/templates/pinax/blog/dateline_stale.html b/project_name/templates/pinax/blog/dateline_stale.html | |
new file mode 100644 | |
index 0000000..18f2730 | |
--- /dev/null | |
+++ b/project_name/templates/pinax/blog/dateline_stale.html | |
@@ -0,0 +1,7 @@ | |
+<p class="post-meta"> | |
+ {% if not post.stale %} | |
+ <span class="date">{% if post.published %}{{ post.published|date:"jS F Y" }}{% else %}Not published yet{% endif %}</span> / | |
+ {% endif %} | |
+ by <span class="author">{{ post.author.get_full_name }}</span> in | |
+ <a href="{% url "blog_section" post.section.slug %}"><span class="section">{{ post.section.name }}</span></a> | |
+</p> | |
diff --git a/project_name/templates/site_base.html b/project_name/templates/site_base.html | |
index 7221602..2aad610 100644 | |
--- a/project_name/templates/site_base.html | |
+++ b/project_name/templates/site_base.html | |
@@ -14,14 +14,18 @@ | |
{% block extra_head_base %} | |
- {% block extra_head %}{% endblock %} | |
+ {% block extra_head %} | |
+ {{ block.super }} | |
+ {% comment %} | |
+ <meta name="twitter:site" content="@pinaxproject"> | |
+ {% endcomment %} | |
+ <meta property="og:site_name" content="{{ SITE_NAME }}"> | |
+ <link rel="alternate" type="application/atom+xml" href="{% url 'blog_feed' 'all' 'atom' %}" title="Atom Feed for Blog"> | |
+ {% endblock %} | |
{% endblock %} | |
-{% block footer %} | |
- {% include "_footer.html" %} | |
-{% endblock %} | |
- | |
+{% block footer_base %}{% endblock %} | |
{% block scripts %} | |
{% include "_scripts.html" %} | |
diff --git a/static/src/less/custom.less b/static/src/less/custom.less | |
index e4e43ce..a38948b 100644 | |
--- a/static/src/less/custom.less | |
+++ b/static/src/less/custom.less | |
@@ -1,29 +1,20 @@ | |
-body { | |
- padding-top: 50px; | |
- position: relative; | |
-} | |
-section { | |
- padding: 20px 0px; | |
-} | |
-.modal form { | |
- margin-bottom: 0px; | |
-} | |
-footer { | |
- padding-bottom: 20px; | |
-} | |
-p.login-signup { | |
- margin-top: 20px; | |
+.teaser { | |
+ .lead; | |
} | |
-.feature-columns { | |
- .make-row(); | |
+form.form-search { | |
+ position: relative; | |
+ margin-top: 20px; | |
+ | |
+ input { | |
+ padding-left: 28px; | |
+ } | |
- > div { | |
- i.fa { | |
- margin-bottom: 0.2em; | |
- } | |
- .make-sm-column(4); | |
- .text-center; | |
- margin: 2em 0; | |
- } | |
+ label { | |
+ position: absolute; | |
+ left: 10px; | |
+ top: 6px; | |
+ color: #999; | |
+ font-size: 13px; | |
+ } | |
} | |
diff --git a/static/src/less/site.less b/static/src/less/site.less | |
index 37295ea..492bd33 100644 | |
--- a/static/src/less/site.less | |
+++ b/static/src/less/site.less | |
@@ -10,6 +10,11 @@ | |
@font-family-serif: Georgia, "Times New Roman", Times, serif; | |
@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; | |
+// Theme | |
+@import "theme.less"; | |
+ | |
+// Code highlighting | |
+@import "tomorrow-night.less"; | |
// Site overrides | |
@import "custom.less"; | |
diff --git a/static/src/less/theme.less b/static/src/less/theme.less | |
new file mode 100644 | |
index 0000000..52f6b67 | |
--- /dev/null | |
+++ b/static/src/less/theme.less | |
@@ -0,0 +1,16 @@ | |
+body { | |
+ padding-top: 50px; | |
+ position: relative; | |
+} | |
+section { | |
+ padding: 20px 0px; | |
+} | |
+.modal form { | |
+ margin-bottom: 0px; | |
+} | |
+footer { | |
+ padding-bottom: 20px; | |
+} | |
+p.login-signup { | |
+ margin-top: 20px; | |
+} | |
diff --git a/static/src/less/tomorrow-night.less b/static/src/less/tomorrow-night.less | |
new file mode 100644 | |
index 0000000..97225aa | |
--- /dev/null | |
+++ b/static/src/less/tomorrow-night.less | |
@@ -0,0 +1,72 @@ | |
+.codehilitetable, | |
+.codehilite { | |
+ .linenos {display: none;} | |
+ pre { | |
+ background: #1d1f21; | |
+ color: #c5c8c6; | |
+ } | |
+ .hll { background-color: #373b41 } | |
+ .c { color: #969896 } /* Comment */ | |
+ .err { color: #cc6666 } /* Error */ | |
+ .k { color: #b294bb } /* Keyword */ | |
+ .l { color: #de935f } /* Literal */ | |
+ .n { color: #c5c8c6 } /* Name */ | |
+ .o { color: #8abeb7 } /* Operator */ | |
+ .p { color: #c5c8c6 } /* Punctuation */ | |
+ .cm { color: #969896 } /* Comment.Multiline */ | |
+ .cp { color: #969896 } /* Comment.Preproc */ | |
+ .c1 { color: #969896 } /* Comment.Single */ | |
+ .cs { color: #969896 } /* Comment.Special */ | |
+ .gd { color: #cc6666 } /* Generic.Deleted */ | |
+ .ge { font-style: italic } /* Generic.Emph */ | |
+ .gh { color: #c5c8c6; font-weight: bold } /* Generic.Heading */ | |
+ .gi { color: #b5bd68 } /* Generic.Inserted */ | |
+ .gp { color: #969896; font-weight: bold } /* Generic.Prompt */ | |
+ .gs { font-weight: bold } /* Generic.Strong */ | |
+ .gu { color: #8abeb7; font-weight: bold } /* Generic.Subheading */ | |
+ .kc { color: #b294bb } /* Keyword.Constant */ | |
+ .kd { color: #b294bb } /* Keyword.Declaration */ | |
+ .kn { color: #8abeb7 } /* Keyword.Namespace */ | |
+ .kp { color: #b294bb } /* Keyword.Pseudo */ | |
+ .kr { color: #b294bb } /* Keyword.Reserved */ | |
+ .kt { color: #f0c674 } /* Keyword.Type */ | |
+ .ld { color: #b5bd68 } /* Literal.Date */ | |
+ .m { color: #de935f } /* Literal.Number */ | |
+ .s { color: #b5bd68 } /* Literal.String */ | |
+ .na { color: #81a2be } /* Name.Attribute */ | |
+ .nb { color: #c5c8c6 } /* Name.Builtin */ | |
+ .nc { color: #f0c674 } /* Name.Class */ | |
+ .no { color: #cc6666 } /* Name.Constant */ | |
+ .nd { color: #8abeb7 } /* Name.Decorator */ | |
+ .ni { color: #c5c8c6 } /* Name.Entity */ | |
+ .ne { color: #cc6666 } /* Name.Exception */ | |
+ .nf { color: #81a2be } /* Name.Function */ | |
+ .nl { color: #c5c8c6 } /* Name.Label */ | |
+ .nn { color: #f0c674 } /* Name.Namespace */ | |
+ .nx { color: #81a2be } /* Name.Other */ | |
+ .py { color: #c5c8c6 } /* Name.Property */ | |
+ .nt { color: #8abeb7 } /* Name.Tag */ | |
+ .nv { color: #cc6666 } /* Name.Variable */ | |
+ .ow { color: #8abeb7 } /* Operator.Word */ | |
+ .w { color: #c5c8c6 } /* Text.Whitespace */ | |
+ .mf { color: #de935f } /* Literal.Number.Float */ | |
+ .mh { color: #de935f } /* Literal.Number.Hex */ | |
+ .mi { color: #de935f } /* Literal.Number.Integer */ | |
+ .mo { color: #de935f } /* Literal.Number.Oct */ | |
+ .sb { color: #b5bd68 } /* Literal.String.Backtick */ | |
+ .sc { color: #c5c8c6 } /* Literal.String.Char */ | |
+ .sd { color: #969896 } /* Literal.String.Doc */ | |
+ .s2 { color: #b5bd68 } /* Literal.String.Double */ | |
+ .se { color: #de935f } /* Literal.String.Escape */ | |
+ .sh { color: #b5bd68 } /* Literal.String.Heredoc */ | |
+ .si { color: #de935f } /* Literal.String.Interpol */ | |
+ .sx { color: #b5bd68 } /* Literal.String.Other */ | |
+ .sr { color: #b5bd68 } /* Literal.String.Regex */ | |
+ .s1 { color: #b5bd68 } /* Literal.String.Single */ | |
+ .ss { color: #b5bd68 } /* Literal.String.Symbol */ | |
+ .bp { color: #c5c8c6 } /* Name.Builtin.Pseudo */ | |
+ .vc { color: #cc6666 } /* Name.Variable.Class */ | |
+ .vg { color: #cc6666 } /* Name.Variable.Global */ | |
+ .vi { color: #cc6666 } /* Name.Variable.Instance */ | |
+ .il { color: #de935f } /* Literal.Number.Integer.Long */ | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment