Skip to content

Creating a Custom DokuWiki Template — From Scratch Development Guide

DodaTech Updated 2026-06-28 7 min read

In this tutorial, you'll learn how to create a custom DokuWiki template from scratch, including planning the design, creating template files, building the layout, adding CSS, and testing across browsers.

What You'll Learn

  • Planning a custom template design
  • Creating the template directory and manifest
  • Building the main.php layout
  • Adding CSS for styling
  • Handling template inheritance
  • Testing and debugging templates

Why It Matters

Pre-built templates like Bootstrap3 are powerful, but they are also complex. A custom template gives you complete control. You can create a minimal, fast-loading template that matches your brand exactly. You understand every line of code. No unused CSS, no unnecessary JavaScript, no dependency on third-party frameworks.

Real-World Use

A developer creates a custom template for a documentation wiki. The template is minimal — just CSS, no JavaScript framework. It loads in under 200ms (vs 800ms for Bootstrap3). The design matches the company's main website exactly. The template has no unused code, making it easy to maintain and update.

Learning Path

flowchart LR
  A[Bootstrap Template] --> B[Custom Template]
  B --> C[Template Configuration]
  C --> D[Caching]
  D --> E[SEO]
  E --> F[Multi-Language]

Planning Your Template

Before writing code, design your template:

Create a Wireframe

+----------------------------------------------------+
| HEADER: Logo | Search | User Menu                  |
+------------+---------------------------------------+
| SIDEBAR    | MAIN CONTENT                          |
| Navigation |                                       |
| Tags       |                                       |
| Recent     |                                       |
+------------+---------------------------------------+
| FOOTER: Copyright | Links | License               |
+----------------------------------------------------+

Define Your CSS Requirements

  • Color scheme (primary, secondary, background, text)
  • Typography (headings, body, code)
  • Layout (fixed width or fluid)
  • Breakpoints for Responsive Design
  • Component styles (buttons, tables, forms)

Creating the Template Structure

# Create template directory
mkdir -p lib/tpl/mytemplate/{css,images,lang/en}

# Create required files
touch lib/tpl/mytemplate/template.info.txt
touch lib/tpl/mytemplate/main.php
touch lib/tpl/mytemplate/css/style.css

The template.info.txt Manifest

base    mytemplate
author  Your Name
email   your@email.com
date    2026-06-28
name    My Custom Template
desc    A minimal, clean template for documentation
url     https://example.com/mytemplate

The main.php Layout

<?php
if (!defined('DOKU_INC')) die();

?><!DOCTYPE html>
<html lang="<?php echo $lang['lang'] ?>" dir="<?php echo $lang['dir'] ?>">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php echo hsc($title) ?></title>
    <?php tpl_metaheaders() ?>
    <?php echo tpl_favicon() ?>
</head>
<body>
    <div id="dw__container">
        <header id="dw__header" role="banner">
            <div class="dw-header-inner">
                <div class="dw-logo">
                    <a href="<?php echo wl('start') ?>">
                        <img src="<?php echo tpl_url() ?>/images/logo.png" alt="Logo" height="40">
                        <span class="dw-wiki-title"><?php echo hsc($conf['title']) ?></span>
                    </a>
                </div>
                <nav class="dw-user-menu">
                    <?php tpl_userinfo() ?>
                </nav>
            </div>
            <nav class="dw-navbar" role="navigation">
                <ul>
                    <li><a href="<?php echo wl('start') ?>">Home</a></li>
                    <li><a href="<?php echo wl('projects:start') ?>">Projects</a></li>
                    <li><a href="<?php echo wl('guides:start') ?>">Guides</a></li>
                    <li><a href="<?php echo wl('about') ?>">About</a></li>
                </ul>
                <div class="dw-search">
                    <?php tpl_searchform() ?>
                </div>
            </nav>
        </header>

        <div id="dw__wrapper" class="dw-clearfix">
            <aside id="dw__sidebar" role="complementary">
                <?php tpl_sidebar() ?>
            </aside>
            <main id="dw__content" role="main">
                <?php tpl_flush() ?>
                <?php tpl_content() ?>
            </main>
        </div>

        <footer id="dw__footer" role="contentinfo">
            <div class="dw-footer-inner">
                <p>&copy; <?php echo date('Y') ?> <?php echo hsc($conf['title']) ?></p>
                <p><?php tpl_license() ?></p>
            </div>
        </footer>
    </div>
</body>
</html>

CSS Styling

/* lib/tpl/mytemplate/css/style.css */

/* Reset */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* Layout */
#dw__container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

.dw-clearfix::after {
    content: "";
    display: table;
    clear: both;
}

/* Header */
#dw__header {
    padding: 20px 0;
    border-bottom: 2px solid #333;
}

.dw-header-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.dw-logo a {
    text-decoration: none;
    color: #333;
    font-size: 24px;
    font-weight: bold;
}

.dw-wiki-title {
    margin-left: 10px;
}

/* Navigation */
.dw-navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #f5f5f5;
    padding: 10px;
    border-radius: 4px;
}

.dw-navbar ul {
    list-style: none;
    display: flex;
    gap: 20px;
}

.dw-navbar a {
    text-decoration: none;
    color: #333;
    padding: 5px 10px;
}

.dw-navbar a:hover {
    background: #ddd;
    border-radius: 3px;
}

/* Sidebar */
#dw__sidebar {
    float: left;
    width: 250px;
    padding: 20px;
    background: #fafafa;
    min-height: 400px;
}

/* Main Content */
#dw__content {
    margin-left: 270px;
    padding: 20px;
    min-height: 400px;
}

/* Footer */
#dw__footer {
    padding: 20px 0;
    border-top: 1px solid #ccc;
    text-align: center;
    color: #666;
}

/* Typography */
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    line-height: 1.6;
    color: #333;
}

h1, h2, h3, h4 {
    margin: 20px 0 10px;
    color: #222;
}

a {
    color: #0066cc;
}

a:hover {
    color: #004499;
}

/* Responsive */
@media (max-width: 768px) {
    #dw__sidebar {
        float: none;
        width: 100%;
        min-height: auto;
    }

    #dw__content {
        margin-left: 0;
    }

    .dw-navbar {
        flex-direction: column;
        gap: 10px;
    }

    .dw-navbar ul {
        flex-direction: column;
        align-items: center;
    }
}

Additional Template Files

detail.php

For media detail pages, create a minimal detail.php:

<?php
if (!defined('DOKU_INC')) die();
?><!DOCTYPE html>
<html lang="<?php echo $lang['lang'] ?>" dir="<?php echo $lang['dir'] ?>">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php echo hsc($title) ?></title>
    <?php tpl_metaheaders() ?>
</head>
<body>
    <div id="dw__detail">
        <?php tpl_content() ?>
    </div>
</body>
</html>

Optional HTML Files

Create header.html and footer.html for content that can be edited without modifying PHP:

lib/tpl/mytemplate/
├── header.html       # Included before main content
├── footer.html       # Included after main content

These files contain plain HTML and are included using tpl_includeFile().

Testing Your Template

1. Enable the Template

<?php
// conf/local.php
$conf['template'] = 'mytemplate';

2. Test All Page Types

  • Normal page view
  • Edit mode
  • History / diff view
  • Search results
  • Media manager
  • Admin pages
  • 404 / non-existent page
  • Sidebar-enabled pages
  • Media detail page

3. Check Browser Compatibility

Test in:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)
  • Mobile Safari and Chrome

Template Inheritance

If your template is based on another template, use the parent field:

base    mychildtemplate
parent  dokuwiki          # Inherit from default template

Files in your child template override files from the parent template. For files not present in your template, DokuWiki falls back to the parent.

This is useful for making small customizations without duplicating an entire template.

Common Mistakes

  1. Not resetting CSS: Browsers have default styles that vary. Always include a CSS reset or normalize to ensure consistent rendering.
  2. Forgetting tpl_metaheaders(): Without this function call, CSS and JavaScript from plugins and DokuWiki itself are not loaded.
  3. Hard-coding page IDs: Use wl('start') instead of /wiki/start. This ensures links work even if the wiki is moved to a different URL.
  4. Not testing edit mode: Edit mode has different layout requirements than view mode. Test both.
  5. Skipping responsive design: More than 50% of web traffic is mobile. A template that does not work on mobile is a broken template.

Practice Questions

  1. What are the mandatory files for a custom DokuWiki template?
  2. Why is tpl_metaheaders() essential in main.php, and what happens if it is omitted?
  3. How does template inheritance work, and when would you use it instead of writing a template from scratch?
  4. Challenge: Create a complete custom template from scratch. The template should include: a fixed-width container (max 960px), a top header with logo and search, a left sidebar (250px) for navigation, a main content area, a footer with copyright and license info, responsive design that collapses the sidebar on screens under 768px, custom colors matching a given brand (#2c3e50 header, #ecf0f1 text), and proper handling of edit mode, history, and media pages. Test the template on all major browsers and at least two mobile devices.

FAQ

Do I need to create a detail.php file?

If you do not create one, DokuWiki falls back to the default template's detail.php when viewing media detail pages. For complete consistency, create a detail.php that matches your main.php design.

{{< faq "How do I add JavaScript to my template?" "Add script tags in the head section of main.php, or create a script.js file in your template directory and include it: <script src=\"<?php echo tpl_url() ?>/js/script.js\"></script>." >}}

Can I use a CSS framework like Tailwind in my template?

Yes. Include the framework's CSS file in your template's head section. Note that DokuWiki's own CSS (from tpl_metaheaders) will also be loaded, so you may need to handle conflicts.

How do I add Google Fonts to my template?

Add the Google Fonts link tag in the head section of main.php, then reference the font in your CSS: font-family: 'Roboto', sans-serif;.

What is the best way to debug template issues?

Enable debug mode in DokuWiki, check the browser console for JavaScript errors, use browser developer tools to inspect HTML structure and CSS, and test each page type individually.

Mini Project

Goal: Build and test a complete custom template.

  1. Plan a template design (draw a wireframe)
  2. Create the template directory structure
  3. Write template.info.txt
  4. Build main.php with header, sidebar, content, and footer
  5. Create detail.php for media pages
  6. Write CSS for all components (layout, typography, navigation, responsive)
  7. Add a logo placeholder
  8. Enable the template and test every page type
  9. Fix any layout issues
  10. Document your template structure

What's Next

Your custom template is live. Learn how to configure templates with user CSS, settings, and inheritance for maintainable designs.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro