diff --git a/.gitignore b/.gitignore
index 8e30f6c..75eba39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,10 @@ pip-log.txt
# paste config files
development.ini
production.ini
+
+# Default wiki directory
+wiki.git/
+wiki/
+
+# Default assets directory
+assets/
diff --git a/README.rst b/README.rst
index 6fa9757..536ce84 100644
--- a/README.rst
+++ b/README.rst
@@ -152,3 +152,26 @@ Here is an example config for Apache with ``mod_wsgi``:
# Make sure to setup anything else you are using, such as SSL certs
+Static Assets
+~~~~~~~~~~~~~
+
+The location of site-specific assets for development can be configured in your development config:
+
+.. code:: ini
+
+ # Custom Assets Configuration
+ custom_assets.dir = /path/to/assets/dir
+ custom_assets.css = relative/path/to/css.file
+ custom_assets.logo = relative/path/to/logo.file
+
+Wiki
+~~~~
+
+Mozzarella includes a wiki that can be enabled by uncommenting the `wiki.repo` option in your configuration.
+When visiting the wiki for the first time after enabling it, Mozzarella will generate a bare git repository with a sample
+page in it.
+
+.. code:: ini
+
+ # Wiki repository location
+ wiki.repo = /path/to/wiki/dir
diff --git a/acmwebsite/config/app_cfg.py b/acmwebsite/config/app_cfg.py
index fcc261a..56f041b 100644
--- a/acmwebsite/config/app_cfg.py
+++ b/acmwebsite/config/app_cfg.py
@@ -75,6 +75,9 @@
# what is the class you want to use to search for users in the database
base_config.sa_auth.user_class = model.User
+#Configure site name
+base_config['site.name'] = 'Mozzarella'
+
from tg.configuration.auth import TGAuthMetadata
diff --git a/acmwebsite/config/middleware.py b/acmwebsite/config/middleware.py
index 6e85585..a0cc834 100644
--- a/acmwebsite/config/middleware.py
+++ b/acmwebsite/config/middleware.py
@@ -2,10 +2,10 @@
"""WSGI middleware initialization for the acm-website application."""
from acmwebsite.config.app_cfg import base_config
from acmwebsite.config.environment import load_environment
-
# Depot
from depot.manager import DepotManager
+from tg.support.statics import StaticsMiddleware
__all__ = ['make_app']
@@ -34,6 +34,10 @@ def make_app(global_conf, full_stack=True, **app_conf):
"""
app = make_base_app(global_conf, full_stack=True, **app_conf)
app = DepotManager.make_middleware(app)
+ try:
+ app = StaticsMiddleware(app, app_conf['site.custom_assets'])
+ except KeyError:
+ pass
# Wrap your base TurboGears 2 application with custom middleware here
diff --git a/acmwebsite/controllers/root.py b/acmwebsite/controllers/root.py
index ca49bc9..5ee7ce3 100644
--- a/acmwebsite/controllers/root.py
+++ b/acmwebsite/controllers/root.py
@@ -23,6 +23,7 @@
from acmwebsite.controllers.schedule import ScheduleController
from acmwebsite.controllers.survey import SurveysController
from acmwebsite.controllers.project import ProjectsController
+from acmwebsite.controllers.wiki import WikiPagesController
from sqlalchemy.sql import functions
@@ -53,6 +54,7 @@ class RootController(BaseController):
error = ErrorController()
contact = ContactController()
projects = ProjectsController()
+ wiki = WikiPagesController()
def _before(self, *args, **kw):
tmpl_context.project_name = "acmwebsite"
diff --git a/acmwebsite/controllers/wiki.py b/acmwebsite/controllers/wiki.py
new file mode 100644
index 0000000..2fd5097
--- /dev/null
+++ b/acmwebsite/controllers/wiki.py
@@ -0,0 +1,86 @@
+"""Wiki controller module"""
+import os
+import tg
+import pygit2 as pg
+
+from tg import expose
+
+from acmwebsite.lib.base import BaseController
+
+from pygit2 import Repository,init_repository
+from pygit2 import Tree
+from pygit2 import Signature
+
+from docutils.core import publish_parts
+
+
+__all__ = ['WikiController']
+
+class WikiController(BaseController):
+ """Controls the wiki"""
+
+ def __init__(self, repo, entry):
+ self.repo = repo
+ self.entry = entry
+
+ @expose('acmwebsite.templates.wiki_view')
+ def _default(self):
+ """Display a specific page"""
+ settings = {'initial_header_level': 2,
+ 'file_insertion_enabled': 0,
+ 'raw_enabled': 0,
+ 'disable_config': 1,
+ }
+
+ blob = self.repo.get(self.entry.id)
+ document = publish_parts(blob.data, writer_name='html5', settings_overrides=settings)
+ return dict(pagename=self.entry.name.strip('.rst'), parts=document)
+
+ @expose('acmwebsite.templates.wiki_history')
+ def history(self):
+ revision_list = []
+ last_id = None
+
+ #Get a list of commits that include the queried file
+ for commit in self.repo.walk(self.repo.head.target, pg.GIT_SORT_TIME):
+ if filename in commit.tree:
+ entry = commit.tree[filename]
+ if entry.id != last_id: #Only add to history if it file chnaged.
+ revision_list.append({"author": commit.author,
+ "time": commit.commit_time,
+ "message": commit.message})
+ last_id = entry.id
+
+ if not revision_list: #No commits include file - possibly faulty?
+ tg.abort(404, "Page not found")
+ return dict(page=pagename, revisions=revision_list)
+
+class WikiPagesController(BaseController):
+ def __new__(cls, repo_path=None):
+ if not repo_path:
+ repo_path = tg.config.get('wiki.repo')
+ if not repo_path:
+ return None
+
+ obj = super().__new__(cls)
+ obj.repo = Repository(repo_path)
+ return obj
+
+ @expose()
+ def _lookup(self, pagename=None, *args):
+ entry = None
+ if pagename:
+ tb = self.repo.TreeBuilder(self.repo.head.peel(Tree))
+ entry = tb.get(pagename + '.rst')
+ if not entry:
+ tg.abort(404, "Page not found")
+ return WikiController(self.repo, entry), args
+
+ @expose()
+ def index(self):
+ tg.redirect('/wiki/FrontPage')
+
+ @expose('acmwebsite.templates.wiki_pagelist')
+ def pagelist(self):
+ pages = [entry.name[:-4] for entry in self.repo.head.peel(Tree)]
+ return dict(pages=pages)
\ No newline at end of file
diff --git a/acmwebsite/public/css/site.css b/acmwebsite/public/css/site.css
new file mode 100644
index 0000000..e69de29
diff --git a/acmwebsite/public/css/style.css b/acmwebsite/public/css/style.css
index 2aba695..7ac1c36 100644
--- a/acmwebsite/public/css/style.css
+++ b/acmwebsite/public/css/style.css
@@ -80,7 +80,7 @@
}
/* Logo */
-.acm-logo {
+.logo {
margin: 20px 0;
max-width: 400px;
width: 100%;
diff --git a/acmwebsite/templates/archives.xhtml b/acmwebsite/templates/archives.xhtml
index f4f91e0..4ddc3c8 100644
--- a/acmwebsite/templates/archives.xhtml
+++ b/acmwebsite/templates/archives.xhtml
@@ -5,7 +5,7 @@