Generating PHP Documentation with Sami
Documenting your methods, classes, and functions is becoming second nature for everyone, so it makes sense to have a way to generate a separate documentation instead of navigating through the source code. In this article, I’m going to introduce you to Sami, the new API documentation generator.
Key Takeaways
- Sami is a new API documentation generator that can be used to create standalone documentation for PHP methods, classes, and functions, improving readability and accessibility.
- Sami can be installed either by downloading the PHAR archive and running it using PHP, or through Composer, a dependency manager for PHP.
- The configuration for Sami involves creating a configuration file that returns an instance of Sami\Sami, and includes options such as the theme, title, build directory, and cache directory.
- Sami offers the flexibility to create custom themes and add assets, allowing for customization of the look and feel of the generated documentation. It also supports Git versioning integration, allowing for documentation of different versions of the codebase.
What Is a DocBlock?
A DocBlock is a multi-line comment inserted at the top of an implementation (Class, Interface, Method, Attribute…etc). To clarify this, let’s use some code snippets from Laravel.
abstract class Manager
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* Create a new manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
}
The DocBlock must start with a /**
, end with a */
, and every line in between should start with a *
.
When defining a class attribute or a method, we write a description, and one or more annotations to define more information about the implementation. In these examples, the @param and @var annotation tags were used. You can visit the documentation for each of these annotations to view a list of annotations phpDocumentor supports.
API Documentation Generators
There are many API documentation generators out there, but one of the best is phpDocumentor. One of the main reasons I like Sami, however, is the ability to use your versioned documentation on Github, and you can also use Twig for generating the templates.
Installing Sami
There are two ways to install Sami. The first one is to download the PHAR archive and run it using php.
php sami.phar
The other way is through Composer. You can run the composer require sami/sami:3.0.*
command to add the package to your project.
php vendor/sami/sami/sami.php
Cloning Laravel’s Documentation
For our example I will generate documentation for the Laravel Illuminate package.
git clone git@github.com:laravel/framework.git docs
Now our folder structure looks like the following.
docs/
vendor/
composer.json
The update
command is responsible for refreshing the documentation and it’s used like the following.
php vendor/sami/sami/sami.php update config/config.php
Where config.php
is the file that describes your documentation structure and how the output is rendered.
Configuration
The configuration file must return an instance of Sami\Sami
. It accepts a Symfony\Component\Finder\Finder
instance and an array of options.
// config/config.php
$dir = __DIR__ . '/../docs';
$iterator = Symfony\Component\Finder\Finder::create()
->files()
->name('*.php')
->exclude('build')
->exclude('tests')
->in($dir);
$options = [
'theme' => 'default',
'title' => 'Laravel API Documentation',
'build_dir' => __DIR__ . '/../build/laravel',
'cache_dir' => __DIR__ . '/../cache/laravel',
];
$sami = new Sami\Sami($iterator, $options);
return $sami;
The $dir
variable holds our source file location. The $iterator
will get all files and select *.php
and exclude the build
and test
directories inside our source path.
The $options
variable is self explanatory. The theme
is set to default, but we will talk about making your own theme later on. The build_dir
holds our output files, and the cache_dir
is used for Twig cache, while title
is the title of the generated documentation.
Now, open your command line and run the previous update command.
php vendor/sami/sami/sami.php update config/config.php
After the command has executed, you can run the built-in PHP server to see how your documentation works. Run php -S localhost:8000 -t build/
, and visit http://localhost:8000/laravel/
to see the result.
Using Git Versioning
I mentioned before that one of the main reasons I like Sami is because of its Git versioning integration. The options['versions']
parameter accepts a Sami\Version\GitVersionCollection
which holds your Git repository configuration. As an example, let’s create the documentation for the 5.0
and 4.2
branches.
$dir = __DIR__ . '/../docs/src';
$iterator = Symfony\Component\Finder\Finder::create()
->files()
->name('*.php')
->in($dir);
$versions = Sami\Version\GitVersionCollection::create($dir)
->add('5.0', 'Master')
->add('4.2', '4.2');
$options = [
'theme' => 'default',
'versions' => $versions,
'title' => 'Laravel API Documentation',
'build_dir' => __DIR__ . '/../build/laravel/%version%',
'cache_dir' => __DIR__ . '/../cache/laravel/%version%',
];
$sami = new Sami\Sami($iterator, $options);
return $sami;
When using versions, your build_dir
and cache_dir
must contain the %version%
tag. The second parameter for the add
method is the label displayed inside a select option. You can also use the addFromTags
, setFilter
methods to filter versions.
php vendor/sami/sami/sami.php update config/config.php
Now your build directory will contain a folder for each version, and the user will have the ability to choose which one he wants to read.
Creating Themes
Until now, we’ve only used the default
theme, but Sami is flexible enough to give us the ability to create our own themes.
The vendor/sami/sami/Sami/Resources/themes
folder is where the default theme is. However, you must not place your own themes there. Sami provides a way to add your own themes path to the lookup path.
// config/config.php
$templates = $sami['template_dirs'];
$templates[] = __DIR__ . '/../themes/';
$sami['template_dirs'] = $templates;
Now we can have our themes
folder in the root of our application. To create a new theme, you need to create a folder and put a manifest.yml
file inside it.
// themes/laravel/manifest.yml
name: laravel
parent: default
Our new theme is called laravel
and it will extend the default
theme properties. As an example, we will try to add some assets to the page and override the behavior of the template.
Adding Assets
Let’s create a css
folder inside our theme folder and create a laravel.css
file inside it.
// themes/laravel/css/laravel.css
#api-tree a {
color: #F4645F;
}
// themes/laravel/manifest.yml
…
static:
'css/laravel.css': 'css/laravel.css'
The static configuration section tells Sami to copy the files as they are inside the specified destination. The build folder will contain the new file inside build/laravel/%version%/css/laravel.css
.
// themes/laravel/manifest.yml
…
global:
'layout/base.twig': 'layout/base.twig'
// themes/laravel/layout/base.twig
{% extends 'default/layout/base.twig' %}
{% block head %}
{{ parent() }}
<link rel="stylesheet" href="css/laravel.css" />
{% endblock %}
Every time Sami wants to load the base
layout, it will use the defined file inside your theme. We extend the default base layout to keep the default look and feel, and we inject our stylesheet link to the head
block. Calling The parent()
function will cause Twig to keep any existing content in the head
block, and output it before our link
tag.
// config/config.php
$options = [
'theme' => 'laravel',
//...
];
php vendor/sami/sami/sami.php render config/config.php --force
By default Sami will not reload the documentation if nothing has changed. However, using the --force
flag will force it to refresh the files. Visit the documentation page in your browser to see that the color of the left navigation links has changed.
Changing Markup
// themes/laravel/manifest.yml
global:
'namespaces.twig': 'namespaces.twig'
As the name suggests, the namespaces
file defines how our namespace content is rendered.
// themes/laravel/namespaces.twig
{% extends 'default/namespaces.twig' %}
{% from "macros.twig" %}
If you open the default/namespaces.twig
page, you’ll see that Sami is using macros to simplify the process of extending templates. We will create our own macros.twig
file to override the default markup.
Because Twig doesn’t support inheriting and overriding a function inside a macro, I’m going to copy and paste the default theme macros and start editing them.
// themes/laravel/macros.twig
{% macro render_classes(classes) -%}
<div class="container-fluid underlined">
{% for class in classes %}
<div class="row">
<div class="col-md-6">
{% if class.isInterface %}
<span class="label label-primary">I</span>
{% else %}
<span class="label label-info">C</span>
{% endif %}
{{ _self.class_link(class, true) }}
</div>
<div class="col-md-6">
{{ class.shortdesc|desc(class) }}
</div>
</div>
{% endfor %}
</div>
{%- endmacro %}
The only thing we’ve changed in this macro is the way we distinguish a class from an interface. Sami used to emphasize the interface, but we are going to insert a colored label before every item depending on its type instead.
We didn’t change much on the page, but you may want to try and use bootstrap styles on your pages, make the menu more responsive, and so on.
Now, after regenerating the documentation you can see that when you list a namespace, the classes and interfaces are preceded by labels.
Conclusion
In this article we introduced a new Symfony tool that can help you manage the documentation of your package. You can also create a unique theme for your package docs. You can find the final result of our example on Github. If you have any questions or comments you can post them below.
Frequently Asked Questions (FAQs) about Generating PHP Documentation with Sami
How do I install Sami for generating PHP documentation?
To install Sami, you need to have Composer installed on your system. Once you have Composer, you can install Sami by running the command composer global require sami/sami
. This command will install Sami globally on your system. After the installation, you can verify it by running sami --version
in your terminal. If Sami is installed correctly, it will display the version number.
How do I configure Sami for my project?
Sami uses a configuration file written in PHP. This file tells Sami where your source code is and where to generate the documentation. You can create a new configuration file using any text editor and save it with a .php
extension. The configuration file should return an instance of Sami\Sami
. You can specify the directories to parse, the theme to use, and other options in this file.
How do I generate documentation with Sami?
Once you have configured Sami, you can generate the documentation by running the command sami update /path/to/your/config.php
. This command will parse your source code and generate the documentation in the directory specified in your configuration file.
Can I customize the look and feel of the generated documentation?
Yes, Sami allows you to customize the theme of the generated documentation. You can specify the theme in your configuration file. Sami comes with a default theme, but you can also create your own theme or use third-party themes.
How do I update the generated documentation when my source code changes?
You can update the generated documentation by running the sami update /path/to/your/config.php
command again. Sami will parse your source code again and update the documentation accordingly. You can automate this process by setting up a cron job or a similar task scheduler.
Can I exclude certain files or directories from the documentation?
Yes, you can exclude certain files or directories from the documentation by specifying them in your configuration file. You can use the exclude
option to specify the files or directories to exclude.
Can I include private and protected methods in the documentation?
By default, Sami only includes public methods in the documentation. However, you can include private and protected methods by setting the default_visibility
option to private
or protected
in your configuration file.
Can I generate documentation for a specific version of my source code?
Yes, you can generate documentation for a specific version of your source code by specifying the version in your configuration file. You can use the versions
option to specify the version.
How do I link to other classes or methods in the documentation?
You can link to other classes or methods in the documentation by using the @link
tag in your PHPDoc comments. Sami will automatically create links to the specified classes or methods.
Can I use Sami with other programming languages?
Sami is specifically designed for generating documentation for PHP code. However, you can use other documentation generators for other programming languages. For example, you can use Javadoc for Java, Doxygen for C++, and Sphinx for Python.
Younes is a freelance web developer, technical writer and a blogger from Morocco. He's worked with JAVA, J2EE, JavaScript, etc., but his language of choice is PHP. You can learn more about him on his website.
Published in
·Cloud·CMS & Frameworks·Debugging & Deployment·Development Environment·PHP·December 8, 2014
Published in
·Cloud·CMS & Frameworks·Debugging & Deployment·Patterns & Practices·PHP·November 24, 2014