# Themes
A DJ Press theme is a collection of Django template files and static assets that control the look and feel of your blog.
This guide explains how to use existing themes, customise them, or create your own theme from scratch.
## Theme Structure
### Template Files
Template files must be placed in: `./templates/djpress/{{ your_theme_name }}/`
At minimum, a theme needs an `index.html` template. If this is the only template you provide, it will be used for all
views. For more specialised layouts, you can create these additional templates:
| Template Name | Used For | Example URL |
|-----------------|---------------------|--------------------------------------------|
| `home.html` | Home page | `https://yourblog.com/` |
| `single.html` | Individual posts | `https://yourblog.com/2024/05/20/my-post/` |
| `page.html` | Static pages | `https://yourblog.com/about/` |
| `archives.html` | Date-based archives | `https://yourblog.com/2024/` |
| `category.html` | Category pages | `https://yourblog.com/category/news/` |
| `tag.html` | Tag pages | `https://yourblog.com/tag/python/` |
| `author.html` | Author pages | `https://yourblog.com/author/sam/` |
When a specific template isn't available, DJ Press falls back to `index.html`.
### Static Files
Static files (CSS, JavaScript, images) should be placed in: `./static/djpress/{{ your_theme_name }}/`
Recommended organisation:
- `./static/djpress/{{ your_theme_name }}/css/`
- `./static/djpress/{{ your_theme_name }}/js/`
- `./static/djpress/{{ your_theme_name }}/img/`
Access static files in your templates using the Django `static` tag:
```django
{% load static %}
```
## Activating a Theme
To use a theme, set the `THEME` setting in your Django project's settings:
```python
DJPRESS_SETTINGS = {
"THEME": "mytheme",
}
```
The theme name must match the directory name under `templates/djpress/` and `static/djpress/`.
## Creating a Custom Theme
Creating a custom theme involves these steps:
1. Create the necessary directories:
```bash
mkdir -p templates/djpress/mytheme
mkdir -p static/djpress/mytheme/css
mkdir -p static/djpress/mytheme/js
mkdir -p static/djpress/mytheme/img
```
2. Create an `index.html` template (minimum requirement):
```django
{% load static %}
{% load djpress_tags %}
{% endfor %}
{% pagination_links %}
{% endif %}
```
3. Create a basic CSS file (`static/djpress/mytheme/css/style.css`):
```css
/* Basic styling for the theme */
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
display: grid;
grid-template-columns: 1fr 300px;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
gap: 20px;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
grid-area: header;
border-bottom: 1px solid #eee;
padding-bottom: 20px;
margin-bottom: 20px;
}
main {
grid-area: main;
}
aside {
grid-area: sidebar;
background: #f7f7f7;
padding: 20px;
border-radius: 5px;
}
footer {
grid-area: footer;
border-top: 1px solid #eee;
padding-top: 20px;
margin-top: 20px;
text-align: center;
}
article {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
}
h1, h2, h3 {
color: #333;
}
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.meta {
color: #666;
font-size: 0.9em;
margin-bottom: 15px;
}
.taxonomy {
font-size: 0.9em;
margin-top: 15px;
}
```
4. Activate your theme in settings:
```python
DJPRESS_SETTINGS = {
"THEME": "mytheme",
}
```
## Template Context
DJ Press provides these context variables to your templates:
| Context Variable | Type | Available In | Description |
|------------------|---------------------|------------------------|------------------------------------------|
| `post` | Post object | Single post/page views | The current post or page |
| `posts` | Paginator Page | Index views | Collection of posts for the current page |
| `category` | Category object | Category views | The current category |
| `author` | User object | Author views | The current author |
| `tags` | List of Tag objects | Tag views | The current tag(s) |
## Conditional Template Logic
You can use conditional logic to create different layouts based on the view type:
```django
{% if post %}
{# Single post/page view #}
{{ post.title }}
{% elif category %}
{# Category view #}
Category: {{ category.title }}
{% elif author %}
{# Author view #}
Posts by {{ author.get_full_name }}
{% else %}
{# Home or archive view #}
Blog Posts
{% endif %}
```
## Built-in Themes
DJ Press includes two reference themes:
1. **default** - A minimalist theme with a single `index.html` template
2. **simple** - A basic theme that demonstrates using different template types
You can use these as starting points for your own themes.
## Recommended Workflow
1. Start by copying one of the built-in themes
2. Modify templates and styles to match your design
3. Test with different content types (posts, pages, archives)
4. Optimise for mobile devices with responsive CSS
## Advanced Theme Techniques
### Template Inheritance
For more maintainable themes, use Django's template inheritance:
```django
{# base.html #}
{% block title %}{% site_title %}{% endblock %}
{% block head %}{% endblock %}
{% block header %}{% endblock %}{% block content %}{% endblock %}
```
```django
{# single.html #}
{% extends "djpress/mytheme/base.html" %}
{% block title %}{{ post.title }} | {% site_title %}{% endblock %}
{% block content %}
{{ post.content_markdown }}
{% endblock %}
```
### Custom Filters
You can create custom template filters for your theme by creating a `templatetags` directory in your app. But if there
are missing tags, then it would help us to raise an [issue on GitHub](https://github.com/stuartmaxwell/djpress/issues)
so we can consider adding them in DJ Press core.