1
Fork 0

Refactor view code

- Compress codebase
- Remove duplicate bulky code
- Use template directory to dictate sitemap
This commit is contained in:
Jake Howard 2016-04-05 19:38:09 +01:00
parent e2e4c517ec
commit 97601a7b53
32 changed files with 96 additions and 313 deletions

1
data/context.yml Normal file
View file

@ -0,0 +1 @@

9
data/page_context.yml Normal file
View file

@ -0,0 +1,9 @@
index:
body_class: index
html_title: Homepage
projects/attack-on-blocks:
page_title: Attack On Block Game!
projects/hipchat-emoticons-for-all:
header_image: https://hipchat-magnolia-cdn.atlassian.com/assets/img/hipchat/hipchat_og_image.jpg

View file

@ -1,10 +0,0 @@
{
"hipchat-emoticons-for-all": {
"title": "Hipchat Emoticons Plugin",
"image": "https://hipchat-magnolia-cdn.atlassian.com/assets/img/hipchat/hipchat_og_image.jpg"
},
"attack-on-blocks": {
"title": "Attack on Blocks Game",
"image": "https://image.freepik.com/free-vector/space-invaders-game_62147502273.jpg"
}
}

8
project/common/data.py Normal file
View file

@ -0,0 +1,8 @@
import os.path
import yaml
def generate_config(base_dir):
default = yaml.load(open(os.path.join(base_dir, 'data/context.yml'))) or {}
page = yaml.load(open(os.path.join(base_dir, 'data/page_context.yml'))) or {}
return default, page

View file

@ -1,105 +0,0 @@
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf import settings
import os.path, json
class AboutTestCase(TestCase):
def test_website_accessable(self):
response = self.client.get(reverse('about:website'))
self.assertEqual(response.status_code, 200)
def test_me_accessable(self):
response = self.client.get(reverse('about:me'))
self.assertEqual(response.status_code, 200)
def test_index_accessable(self):
response = self.client.get(reverse('about:index'))
self.assertEqual(response.status_code, 200)
def test_email_send(self):
data = {
'email': '123@123.123',
'name': 'Person',
'message': 'Hi there, things.'
}
response = self.client.post(reverse('about:index'), data)
self.assertRedirects(response, '/about/?sent')
def test_success_message_shows(self):
response = self.client.get(reverse('about:index') + '?sent')
self.assertContains(response, 'Already Sent')
class CorePagesTestCase(TestCase):
def test_404_accessable(self):
response = self.client.get(reverse('404'))
self.assertEqual(response.status_code, 404)
def test_no_js_accessable(self):
response = self.client.get(reverse('no-js'))
self.assertEqual(response.status_code, 200)
def test_index_accessable(self):
response = self.client.get(reverse('pages:index'))
self.assertEqual(response.status_code, 200)
def test_index_projects(self):
projects = json.load(open(os.path.join(settings.BASE_DIR, 'data/projects.json')))
response = self.client.get(reverse('pages:index'))
for key, project in projects.items():
self.assertContains(response, project['title'])
if 'image' in project:
self.assertContains(response, project['image'])
class ProjectsTestCase(TestCase):
def test_all_accessable(self):
response = self.client.get(reverse('projects:all'))
self.assertEqual(response.status_code, 200)
def test_test_project_accessable(self):
response = self.client.get(reverse('projects:project', args=['test']))
self.assertEqual(response.status_code, 200)
def test_projects_accessable(self):
projects = json.load(open(os.path.join(settings.BASE_DIR, 'data/projects.json')))
for key, project in projects.items():
response = self.client.get(reverse('projects:project', args=[key]))
self.assertEqual(response.status_code, 200)
def test_projects_details(self):
projects = json.load(open(os.path.join(settings.BASE_DIR, 'data/projects.json')))
for key, project in projects.items():
response = self.client.get(reverse('projects:project', args=[key]))
self.assertContains(response, project['title'])
if 'image' in project:
self.assertContains(response, project['image'])
class RoboticsTestCase(TestCase):
def test_2015_index_accessable(self):
response = self.client.get(reverse('robotics:2015-index'))
self.assertEqual(response.status_code, 200)
def test_2014_index_accessable(self):
response = self.client.get(reverse('robotics:2014-index'))
self.assertEqual(response.status_code, 200)
def test_2015_robot_accessable(self):
response = self.client.get(reverse('robotics:2015-robot'))
self.assertEqual(response.status_code, 200)
def test_2015_code_accessable(self):
response = self.client.get(reverse('robotics:2015-code'))
self.assertEqual(response.status_code, 200)
class CollegeTestCase(TestCase):
def test_attack_on_blocks_accessable(self):
response = self.client.get(reverse('college:attack-on-blocks'))
self.assertEqual(response.status_code, 200)
def test_student_server_accessable(self):
response = self.client.get(reverse('college:student-server'))
self.assertEqual(response.status_code, 200)

8
project/pages/urls.py Normal file
View file

@ -0,0 +1,8 @@
from django.conf.urls import include, url
from .views import page_view, index_view
urlpatterns = [
url(r'^(?P<path>.*)/', page_view, name='page'),
url(r'^$', index_view, name='page'),
]

View file

@ -1 +0,0 @@
from . import about, college, core, projects, robotics

View file

@ -1,9 +0,0 @@
from django.conf.urls import url
from project.pages.views import about
urlpatterns = [
url(r'^website/$', about.WebsiteView.as_view(), name='website'),
url(r'^me/$', about.MeView.as_view(), name='me'),
url(r'^$', about.IndexView.as_view(), name='index'),
]

View file

@ -1,8 +0,0 @@
from django.conf.urls import url
from project.pages.views import college
urlpatterns = [
url(r'^attack-on-blocks/$', college.AttackOnBlocksView.as_view(), name='attack-on-blocks'),
url(r'^student-server/$', college.StudentServerView.as_view(), name='student-server'),
]

View file

@ -1,7 +0,0 @@
from django.conf.urls import url
from project.pages.views import core
urlpatterns = [
url(r'^$', core.IndexView.as_view(), name='index')
]

View file

@ -1,8 +0,0 @@
from django.conf.urls import url
from project.pages.views import projects
urlpatterns = [
url(r'^$', projects.AllView.as_view(), name="all"),
url(r'^(?P<project>.+)/$', projects.ProjectView.as_view(), name="project")
]

View file

@ -1,11 +0,0 @@
from django.conf.urls import url
from project.pages.views import robotics
urlpatterns = [
url(r'^$', robotics.IndexView.as_view(), name="index"),
url(r'^2014/$', robotics.Index2014View.as_view(), name="2014-index"),
url(r'^2015/robot/$', robotics.Robot2015View.as_view(), name="2015-robot"),
url(r'^2015/code/$', robotics.Code2015View.as_view(), name="2015-code"),
url(r'^2015/$', robotics.Index2015View.as_view(), name="2015-index")
]

23
project/pages/utils.py Normal file
View file

@ -0,0 +1,23 @@
from django.conf import settings
from bs4 import BeautifulSoup
import markdown2
def get_context(path):
if path in settings.PAGE_CONTEXT:
context = dict(settings.DEFAULT_CONTEXT, **settings.PAGE_CONTEXT[path])
else:
context = dict(settings.DEFAULT_CONTEXT)
return context
def get_title_from_markdown(md):
html_tree = BeautifulSoup(md, "html.parser")
tag = html_tree.find('h1')
return tag.contents[0]
def parse_content(content, extension):
if extension == 'md':
return markdown2.markdown(content)
return content

32
project/pages/views.py Normal file
View file

@ -0,0 +1,32 @@
from project.common.views import CustomTemplate
import os.path
from django.conf import settings
from django.http import HttpResponse, Http404
from django.template.loader import get_template
from .utils import get_context, parse_content, get_title_from_markdown
def page_view(request, path):
template = None
if os.path.isdir(os.path.join(settings.BASE_DIR, 'templates', path)):
path = os.path.join(path, 'index')
for extension in ['md', 'html']:
try:
template = get_template("{}.{}".format(path, extension))
break
except:
pass
if not template:
raise Http404
context = get_context(path)
parsed_content = parse_content(template.render(context, request), extension)
if extension == 'md':
template = get_template('markdown_content.html')
context['markdown_content'] = parsed_content
context['page_title'] = get_title_from_markdown(parsed_content)
parsed_content = template.render(context, request)
return HttpResponse(parsed_content)
def index_view(request):
return page_view(request, 'index')

View file

@ -1 +0,0 @@
from . import about, college, core, projects, robotics

View file

@ -1,28 +0,0 @@
from project.common.views import CustomTemplate, CustomFormTemplate
from project.common.forms import ContactForm
class WebsiteView(CustomTemplate):
template_name = 'about/website.html'
html_title = "About website"
class IndexView(CustomFormTemplate):
template_name = 'about/index.html'
html_title = "About"
success_url = '/about/?sent'
form_class = ContactForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['sent'] = 'sent' not in self.request.GET
return context
def form_valid(self, form):
form.send_email()
return super().form_valid(form)
class MeView(CustomTemplate):
template_name = 'about/me.html'
html_title = "About Me"

View file

@ -1,9 +0,0 @@
from project.common.views import MarkdownView
class AttackOnBlocksView(MarkdownView):
markdown = 'projects/attack-on-blocks.md'
class StudentServerView(MarkdownView):
markdown = 'college/student-server.md'

View file

@ -1,32 +0,0 @@
from project.common.views import CustomTemplate
from django.conf import settings
from json import load
import os.path
class IndexView(CustomTemplate):
template_name = 'index.html'
html_title = "Homepage"
body_class = "index"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['projects'] = load(open(os.path.join(settings.BASE_DIR, 'data/projects.json')))
return context
class NoJavascriptView(CustomTemplate):
template_name = 'core/no-js.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['js_redirect'] = False
return context
class Custom404View(CustomTemplate):
template_name = 'core/404.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context, status=404)

View file

@ -1,34 +0,0 @@
from project.common.views import CustomTemplate, MarkdownView
from json import load
from django.conf import settings
import os.path
PROJECT_DETAILS = load(open(os.path.join(settings.BASE_DIR, 'data/projects.json')))
class AllView(CustomTemplate):
template_name = 'projects/all.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['projects'] = PROJECT_DETAILS
return context
class ProjectView(MarkdownView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
try:
details = PROJECT_DETAILS[kwargs['project']]
context['html_title'] = details['title']
context['page_title'] = details['title']
context['header_image'] = details['image']
except:
context['html_title'] = kwargs['project']
context['page_title'] = kwargs['project']
return context
def dispatch(self, request, *args, **kwargs):
self.markdown = 'projects/{0}.md'.format(kwargs['project'])
return super().dispatch(request, *args, **kwargs)

View file

@ -1,27 +0,0 @@
from project.common.views import CustomTemplate, MarkdownView
class IndexView(CustomTemplate):
template_name = 'robotics/index.html'
html_title = 'Student Robotics'
# 2015
class Index2015View(CustomTemplate):
template_name = 'robotics/2015-index.html'
html_title = 'Student Robotics 2015'
class Robot2015View(CustomTemplate):
template_name = 'robotics/2015-robot.html'
html_title = 'The Robot | SR2015'
class Code2015View(MarkdownView):
markdown = 'robotics/2015-code.md'
# 2014
class Index2014View(CustomTemplate):
template_name = 'robotics/2014-index.html'
html_title = 'Student Robotics 2014'

View file

@ -96,3 +96,7 @@ JOBS = {
} }
WORDPRESS_URL = "realorangeone.wordpress.com" WORDPRESS_URL = "realorangeone.wordpress.com"
# Generate config data
from project.common.data import generate_config
DEFAULT_CONTEXT, PAGE_CONTEXT = generate_config(BASE_DIR)

View file

@ -1,19 +1,7 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from django_client_reverse import urls as reverse_urls
from project.pages.views.core import Custom404View, NoJavascriptView
urlpatterns = [ urlpatterns = [
url(r'^reverse/$', include(reverse_urls, namespace='reverser')),
url(r'^404/', Custom404View.as_view(), name="404"),
url(r'^no-js/', NoJavascriptView.as_view(), name="no-js"),
url(r'^about/', include('project.pages.urls.about', namespace='about')),
url(r'^college/', include('project.pages.urls.college', namespace='college')),
url(r'^core/', include('project.pages.urls.core', namespace='core')),
url(r'^projects/', include('project.pages.urls.projects', namespace='projects')),
url(r'^robotics/', include('project.pages.urls.robotics', namespace='robotics')),
url(r'^blog/', include('project.blog.urls', namespace='blog')), url(r'^blog/', include('project.blog.urls', namespace='blog')),
url(r'', include('project.pages.urls.core', namespace='pages')) url(r'', include('project.pages.urls', namespace='pages'))
] ]
# handler404 = Custom404View

View file

@ -1,10 +1,10 @@
beautifulsoup4==4.3.2
coverage==4.0.3 coverage==4.0.3
colorama==0.3.6 colorama==0.3.6
Django==1.8.7 Django==1.8.7
dj-database-url==0.3.0 dj-database-url==0.3.0
django-db-queue==0.0.2 django-db-queue==0.0.2
django-bootstrap-form==3.2 django-bootstrap-form==3.2
git+https://github.com/RealOrangeOne/django-client-reverse
django-flat-theme==1.1.3 django-flat-theme==1.1.3
djangorestframework==3.3.2 djangorestframework==3.3.2
flake8==2.5.0 flake8==2.5.0

View file

@ -6,14 +6,10 @@ import './globals.js';
import 'whatwg-fetch'; import 'whatwg-fetch';
import React from 'react'; import React from 'react';
import ProjectImagesTypes from './components/index/project-images-types';
import NavBar from './components/navbar/navbar'; import NavBar from './components/navbar/navbar';
import Breadcrumbs from './components/breadcrumbs'; import Breadcrumbs from './components/breadcrumbs';
if ($('body').hasClass('index')) { // Render components on index
React.render(<ProjectImagesTypes />, document.getElementById('project-images-types'));
}
if ($('navbar').length > 0) { if ($('navbar').length > 0) {
React.render(<NavBar />, $('navbar')[0]); React.render(<NavBar />, $('navbar')[0]);
@ -22,3 +18,7 @@ if ($('navbar').length > 0) {
if ($('#breadcrumbs').length > 0) { if ($('#breadcrumbs').length > 0) {
React.render(<Breadcrumbs />, $('#breadcrumbs')[0]); React.render(<Breadcrumbs />, $('#breadcrumbs')[0]);
} }
if ($('.header h1').text()) {
$('.markdown-content h1').eq(0).hide();
}

View file

@ -57,7 +57,7 @@
{% if js_redirect %} {% if js_redirect %}
<noscript> <noscript>
<style> html, body { display:none; }</style> <style> html, body { display:none; }</style>
<meta http-equiv="refresh" content="0.0;url={% url 'no-js' %}"> <meta http-equiv="refresh" content="0.0;url=/no-js">
</noscript> </noscript>
{% endif %} {% endif %}
</body> </body>

View file

@ -44,7 +44,7 @@
<div class="caption"> <div class="caption">
<h3>{{ project.title }}</h3> <h3>{{ project.title }}</h3>
<p></p> <p></p>
<a href="{% url 'projects:project' key %}"> <a href="/project/">
Read More Read More
</a> </a>
</div> </div>
@ -53,7 +53,7 @@
{% endfor %} {% endfor %}
<div class="col-sm-6 col-md-4"> <div class="col-sm-6 col-md-4">
<div class="thumbnail see-more"> <div class="thumbnail see-more">
<a href="{% url 'projects:all' %}"> <a href="/projects">
<h1>See All</h1> <h1>See All</h1>
</a> </a>
</div> </div>

View file

@ -27,7 +27,7 @@
<h2>Student Robotics 2014</h2> <h2>Student Robotics 2014</h2>
<p><strong>Robot Name:</strong> Lucy <p><strong>Robot Name:</strong> Lucy
<br /><small>(No, it doesn't stand for anything)</small> <br /><small>(No, it doesn't stand for anything)</small>
<p><a href="{% url 'robotics:2014-index' %}" class="btn btn-srobo btn-block">More Info</a></p> <p><a href="/robotics/2014" class="btn btn-srobo btn-block">More Info</a></p>
</div> </div>
</div> </div>
</div> </div>
@ -39,7 +39,7 @@
<h2>Student Robotics 2015</h2> <h2>Student Robotics 2015</h2>
<p><strong>Robot Name : </strong> A.L.I.C.E <p><strong>Robot Name : </strong> A.L.I.C.E
<br /><small>(<strong>A</strong>utonomous <strong>L</strong>ogistics and <strong>I</strong>nevitable <strong>C</strong>ollision <strong>E</strong>ngine)</small></p> <br /><small>(<strong>A</strong>utonomous <strong>L</strong>ogistics and <strong>I</strong>nevitable <strong>C</strong>ollision <strong>E</strong>ngine)</small></p>
<p><a href="{% url 'robotics:2015-index' %}" class="btn btn-srobo btn-block" >More Info</a></p> <p><a href="/robotics/2015" class="btn btn-srobo btn-block" >More Info</a></p>
</div> </div>
</div> </div>
</div> </div>