Commit 0237388d authored by Michael McAndrew's avatar Michael McAndrew

initial commit

# Usage
All CiviCRM documentation should be written in Markdown, following [mkdocs]( conventions, and stored in a git repository.
## Defining books
Books are defined with a Yaml configuration file, stored in the conf/books directory of this repository.
The config file lists the **languages** that the book is available in, with a repository for each language. For each language, the file defines:
* which edition of the book should be considered stable
* where to find the latest edits to the book
* a history of book editions of the book.
Editions of books typically editions map to versions of CiviCRM (or in the case of extensions, the version of the extension). Editions are created by creating corresponding branches in the repository.
Example Yaml file for our user guide: 'user.yml'
- repo: ''
- latest: master
- stable: 4.7
- history:
- 4.7
- 4.6
## Publishing books
Some time in the near future, books will automatically be updated when the corresponding branch is updated in the repository.
Until that happens, the update process can be manually triggered by calling a URL in the following format:
## Trouble shooting
Some rudimentary logging is available at
**Note:** these are plain text files and not that pretty right now. Using 'view source' in your browser is one way to make them easier to read.
# Requirements
* pip (sudo apt-get install python-pip)
* composer (
# Installation
1) Install mkdocs.
$ sudo pip install mkdocs
***Note:*** *Ensure that mkdocs is installed as root so that it can be accessed from the src/build.php script (typically invoked as*
2) Run composer install
$ cd /var/www/civicrm-docs
$ composer install
3) Run the civicrm-docs install script
$ cd /var/www/civicrm-docs
$ ./
4) Configure an nginx virtual host
$ cd /etc/nginx/sites-enabled
$ ln -s /var/www/civicrm-docs/conf/nginx.conf civicrm-docs
"name": "civicrm/civicrm-docs",
"description": "CiviCRM documentation infrastructure",
"license": "AGPL",
"authors": [
"name": "Michael McAndrew",
"email": ""
"require": {
"symfony/yaml": "*",
"gitonomy/gitlib": "*",
"monolog/monolog": "^1.18"
This diff is collapsed.
// Calculate the base directory
$root = explode('/', __DIR__);
$root = implode('/', $root);
server_name docs;
root /var/www/civicrm-docs/www;
rewrite ^/(user|developer)/$ /$1/en/stable permanent;
location ~ \.php$ {
root /var/www/civicrm-docs/src;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 300;
location ~ /log {
autoindex on;
text/html log;
root /var/www/civicrm-docs/;
mkdir conf/books conf/builds log repos www
sudo chgrp www-data conf/builds log repos www
require_once '../vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Dumper;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Gitonomy\Git as Gitonomy;
use Symfony\Component\Process\Process;
require_once '../conf/config.php';
//Start up a logger
$docsLog = new Logger('Docs');
$docsLog->pushHandler(new StreamHandler("$root/log/docs.log", Logger::INFO));
// These details should be pulled from the URL, or JSON or similar
$validParams = array(
//Do some basic validation here
foreach($validParams as $param){
$docsLog->addError("$param is a required parameter. Exiting...");
if(!preg_match('/^[a-z0-9\.]*$/', $_GET[$param])){
$docsLog->addError("$param ({$_GET[$param]}) is not alphanumeric. Exiting...");
$$param = $_GET[$param];
//Validate that the book is defined
$docsLog->addError("Could not find config file '$book.yml'. Exiting...");
// Load the configuration
$yaml = new Parser;
$bookConf = $yaml->parse(file_get_contents("$root/conf/books/$book.yml"));
$docsLog->addInfo("Found config file '$book.yml'.");
$repo = Gitonomy\Admin::cloneTo("$root/repos/{$book}", $bookConf[$lang], false);
$repo = new Gitonomy\Repository("$root/repos/{$book}");
$bookLog = new Logger("Docs.$book");
$bookLog->pushHandler(new StreamHandler("$root/log/$", Logger::INFO));
// Ensure that we are on the right branch to do the publishing, and that the branch is up to date
//If this branch exist locally, check it out. Else, ensure that it exists in origin, and if so check it out (also serves to validate URL parameter)
$references = $repo->getReferences();
$repo->run('checkout', array($branch));
$bookLog->addInfo("Can't find local tracking branch for $branch. Will attempt to track remote branch");
$repo->run('checkout', array($branch));
$bookLog->addError("Remote branch $branch found. Tracking remote branch.");
$bookLog->addError("Remote branch $branch not found. Exiting...");
//Update the branch by pulling in any changes from origin
//Override some settings from the yml before publishing
$mkdocsConf = $yaml->parse(file_get_contents("$root/repos/$book/mkdocs.yml"));
$dumper = new Dumper;
file_put_contents("$root/conf/builds/{$book}.{$lang}.{$branch}.yml", $dumper->dump($mkdocsConf, 2));
$command = "mkdocs build -c -f $root/conf/builds/{$book}.{$lang}.{$branch}.yml -d $root/www/$book/{$lang}/{$branch}";
$dir = "$root/repos/{$book}";
$mkdocs = New Process($command, $dir);
echo nl2br($mkdocs->getOutput());
echo nl2br($mkdocs->getErrorOutput());
echo "<a href='/{$book}/{$lang}/{$branch}'>Build successful - click here to view the result</a>";
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>CiviCRM documentation</title>
<h1>CiviCRM documentation</h1>
<li><strong>User documentation</strong> - aimed at day to day users of CiviCRM
<li><a href="/user">User guide</a></li>
<li><strong>Aministrator documentation</strong> - for system administrators
<li><a href="">Installation and upgrade guide</a></li>
<li><strong>Developer documentation</strong> - for people that are contributing code to CiviCRM via core or extensions
<li><a href="">Developer resources</a></li>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment