Smug is built in the Django framework. If you aren't familiar with Django, I highly recommend that you familiarize yourself with the Django documentation. I'll repeat some of the steps here, but it's really best if you're already familiar with the process.
Smug is a Django app and will need to be installed somewhere on your PYTHONPATH. If you don't know what this means, create a "python" directory in your home directory. This python directory will contain both Smug and your Django project module.
To create a Django project module, go to the python directory and run "django-admin.py startproject mysite", where "mysite" can be replaced by whatever name you wish to call your project (just don't call it "django" or "smug"). This will create a directory with a few configuration files. Edit the basic settings in the settings.py file. The Django documentation contains instructions about modifying this file.
Next, check out Smug. Go to the python directory and run "git clone git://mcnabbs.org/smug.git". This will create a directory called smug that has all of the Smug source code.
If you're using the Django development server, you must make sure that your PYTHONPATH is set appropriately before proceeding further. Otherwise, Python wouldn't be able to find either "mysite" or "smug".
If you're using the Django development server, just add "export PYTHONPATH=$HOME/python" to your bashrc (and load your changes). You can then cd to "mysite", run "python manage.py runserver", and go to "http://localhost:8000/" in a web browser. Note that the Django documentation has a lot of information about setting this up.
If you're using Apache, you will need to set Python as the handler. You might have something like the following in httpd.conf (and if you want authenticated sessions to go over SSL, as I recommend, it should also go in ssl.conf).
<Location "/you/pick/the/location/">
SetHandler python-program
PythonPath "['/path/to/pythonpath/directory'] + sys.path"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
#PythonDebug On
</Location>
In this example, it really is important to have both "mysite" and "smug" in "/path/to/pythonpath/directory". Otherwise, Python won't know where to find these modules.
The Git repository you use for Smug should be a bare repository.
If you are using Apache, you should probably create a system group containing both your username and "apache". To create the repository, you should probably run the following:
mkdir /path/to/smug_html.git cd /path/to/smug_html.git git --bare init --shared=group chgrp -R shared_group_name .
where /path/to/smug_html.git and shared_group_name are replaced by the values you choose. If you don't want a group, then leave off the "--shared=group" option.
Before you actually use the repository in Smug or even clone it with Git, it must have an initial commit. To do this, go into some other repository and do:
git push /path/to/smug_html.git master
Changes to settings.py:
Smug needs entries in urlpatterns in urls.py: one for the smug app, and one for each repository. The following statement should be in urls.py:
from smug.urls import smugurl
Add one of the following lines to urlpatterns in urls.py to add the urls for the Smug app. The first is for using Smug for your whole site, and the second is for putting Smug in a subsection of the site:
url(r'', include('smug.urls'))
url(r'^where/smug/goes/', include('smug.urls'))
There also needs to be a urls entry for each repository. Note that the url pattern for the repository needs to be after the url pattern for the Smug app. If you have multiple repositories, you will need to have several urlpattern entries. They need to be ordered from most specific pattern to least specific. Here are a few examples:
smugurl(r'^path/to/repo/', repo='repo3') smugurl(r'^path/', repo='other_repo') smugurl(r'', repo='myrepo')
a complete example urls.py file with Django's admin activated, multiple Smug repositories, and a Django application other than Smug also installed might look like this:
from django.conf.urls.defaults import *
from django.contrib import admin
from smug.urls import smugurl
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/(.*)', admin.site.root),
url(r'', include('smug.urls')),
url(r'^otherDjangoApp/', include('other.app.urls')),
smugurl(r'^path/to/repo/', repo='repo3'),
smugurl(r'^path/', repo='other_repo'),
smugurl(r'', repo='myrepo'),
)
Optional Settings:
Smug will need to have some filters defined in order to actually serve anything other than flat files. Filters give smug a lot of power. If a content of a particular type is needed, a filter can be designated, and smug can perform the conversions on the fly as needed.
Filters are defined with a .smug file. The syntax is very basic. This is the filter that I use for presenting ReST as html:
convert from .rst to .html using rst2html
When smug receives a request for a document with the .html extension, and the file doesn't exist in the git repository, it looks for a filename with the same name, but the .rst extension. It reads the .rst file from the git repo, and runs it through the rst2html filter, which results in html content.
The .smug file works in a similar way to .htaccess files in apache. These filter directives apply to the directory in which they reside, as well as any subdirectories contained in the same parent directory.
The other directive that a .smug file supports is directory_index. This simply tells smug what file to look for if it receives a request for a path that is a directory. A common directory_index is index.html. The way to define index.html with smug is to put the following into your .smug file:
directory_index index.html
Currently those are the only two directives that smug supports. Eventually, it may support more complex things like per-directory or per-file permission definitions.
Smug templates use the Django template language. Smug filters provide three special variables for templates: title, content, and baseurl. The first two are self-explanatory. The baseurl variable holds the url to the base of the repository containing the current page (for example, "/path/to/repo/". Templates can also use Django's reverse URL mechanism to provide a link to a specific file in a given repository. For example, to link to a file called "abc/xyz.html" in the repository called "myrepo", use the following template tag:
{% url repo-myrepo "abc/xyz.html" %}
Note that the "baseurl" variable and the "url" tag have different semantics. The "baseurl" variable contains a url for the current repository, while the "url" tag creates a link for a specified repository. On a multiple-repo site, the distinction can be very important.