From f9aa8673d5c85736283d8a11703b7543280a3277 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 19 Dec 2020 18:05:46 +0100 Subject: [PATCH] feat: implement a custom footer link Ref: https://github.com/silverstripe/api.silverstripe.org/issues/65 --- CHANGELOG.md | 3 +- README.rst | 34 ++++++++ src/Doctum.php | 6 ++ src/Project.php | 22 ++++++ .../themes/default/layout/layout.twig | 9 +++ tests/AbstractTestCase.php | 7 +- tests/ProjectTest.php | 77 ++++++++++++++++++- 7 files changed, 152 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bde701d8..faa73353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed: "Error: The ProgressBar is not started" (#19) - Fixed: ""3" @param tags are expected but only "4" found" (#21) - Reworked the `@param` tag error detection and added new error messages -- Added: A shebang to all the new PHARs distributed. +- Added: A shebang to all the new PHARs distributed +- Added: Support for a custom `footer_link` configuration ## [5.2.1] - 2020-11-30 diff --git a/README.rst b/README.rst index 7a2d4e59..7359129f 100644 --- a/README.rst +++ b/README.rst @@ -143,6 +143,40 @@ And here is how you can configure different versions: 'default_opened_level' => 2, ]); + +And here is how you can configure a footer link below the Doctum link: + +All `footer_link` keys are optional. + +.. code-block:: php + + files() + ->name('*.php') + ->exclude('Resources') + ->exclude('Tests') + ->in($dir); + + return new Doctum($iterator, [ + 'title' => 'yourlib API', + 'source_dir' => dirname($dir) . '/', + 'remote_repository' => new GitHubRemoteRepository('yourorg/yourlib', dirname($dir)), + 'footer_link' => [ + 'href' => 'https://github.com/code-lts/doctum', + 'rel' => 'noreferrer noopener', + 'target' => '_blank', + 'before_text' => 'You can edit the configuration', + 'link_text' => 'on this', // Required if the href key is set + 'after_text' => 'repository', + ], + ]); + You can find more configuration examples under the ``examples/`` directory of the source code. diff --git a/src/Doctum.php b/src/Doctum.php index eaf2eb81..b05d742f 100644 --- a/src/Doctum.php +++ b/src/Doctum.php @@ -188,6 +188,11 @@ class Doctum implements ArrayAccess /** @var AbstractRemoteRepository|null */ private $remote_repository = null; + /** + * @var array|null + */ + private $footer_link = null; + /** * include parent properties and methods on class pages * @@ -376,6 +381,7 @@ private function getBuiltProject(): Project 'title' => $this->title, 'source_url' => $this->source_url, 'insert_todos' => $this->insert_todos, + 'footer_link' => $this->footer_link, 'sort_class_properties' => $this->sort_class_properties, 'sort_class_methods' => $this->sort_class_methods, 'sort_class_constants' => $this->sort_class_constants, diff --git a/src/Project.php b/src/Project.php index 9e84a9fd..ff2dc6da 100644 --- a/src/Project.php +++ b/src/Project.php @@ -520,4 +520,26 @@ public function getViewSourceUrl($relativePath, $line) return ''; } + + public function hasFooterLink(): bool + { + return $this->getConfig('footer_link') !== null && is_array($this->getConfig('footer_link')); + } + + /** + * @return array + * @phpstan-return array{href: string, rel: string, target: string, before_text: string, link_text: string, after_text: string} + */ + public function getFooterLink(): array + { + $link = $this->getConfig('footer_link'); + return [ + 'href' => $link['href'] ?? '', + 'target' => $link['target'] ?? '', + 'rel' => $link['rel'] ?? '', + 'before_text' => $link['before_text'] ?? '', + 'link_text' => $link['link_text'] ?? '', + 'after_text' => $link['after_text'] ?? '', + ]; + } } diff --git a/src/Resources/themes/default/layout/layout.twig b/src/Resources/themes/default/layout/layout.twig index 26ccc922..19d9f48d 100644 --- a/src/Resources/themes/default/layout/layout.twig +++ b/src/Resources/themes/default/layout/layout.twig @@ -75,5 +75,14 @@ {{ 'Generated by %sDoctum, a API Documentation generator and fork of Sami%s.'|trans|format( '', '' )|raw }} + {%- if project.hasFooterLink() -%} + {% set link = project.getFooterLink() %} +
+ {{- link.before_text }} + {%- if link.href is not empty -%} + {{ " " }}{{ link.link_text }}{{ " " }} + {%- endif -%} + {{ link.after_text -}} + {%- endif -%} {%- endblock -%} diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php index 79280ab1..c52bae35 100644 --- a/tests/AbstractTestCase.php +++ b/tests/AbstractTestCase.php @@ -11,10 +11,13 @@ */ abstract class AbstractTestCase extends TestCase { - protected function getProject(): Project + /** + * @param array $config + */ + protected function getProject(array $config = []): Project { $store = new ArrayStore(); - return new Project($store); + return new Project($store, null, $config); } protected function getTestConfigFilePath(): string diff --git a/tests/ProjectTest.php b/tests/ProjectTest.php index c718a7ef..3fbed923 100644 --- a/tests/ProjectTest.php +++ b/tests/ProjectTest.php @@ -2,13 +2,12 @@ namespace Doctum\Tests; -use PHPUnit\Framework\TestCase; use Doctum\Project; use Doctum\Reflection\ClassReflection; use Doctum\Store\ArrayStore; use Doctum\Version\Version; -class ProjectTest extends TestCase +class ProjectTest extends AbstractTestCase { public function testSwitchVersion(): void { @@ -45,8 +44,80 @@ public function testSwitchVersion(): void [ 'C21\\C2' => $class2, 'C31\\C32\\C3' => $class3, - ], + ], $project->getProjectClasses() ); } + + public function testHasFooterLink(): void + { + $project = $this->getProject(); + + $this->assertFalse($project->hasFooterLink()); + + $project = $this->getProject([ + 'footer_link' => [ + 'href' => 'https://github.com/code-lts/doctum', + 'rel' => 'noreferrer noopener', + 'target' => '_blank', + 'before_text' => 'You can edit the configuration', + 'link_text' => 'on this', // Required if the href key is set + 'after_text' => 'repository', + ], + ]); + + $this->assertTrue($project->hasFooterLink()); + + $project = $this->getProject([ + 'footer_link' => [], + ]); + + $this->assertTrue($project->hasFooterLink()); + + $project = $this->getProject([ + 'footer_link' => null, + ]); + + $this->assertFalse($project->hasFooterLink()); + + $project = $this->getProject([ + 'footer_link' => 'https://example.com', + ]); + + $this->assertFalse($project->hasFooterLink()); + } + + public function testGetFooterLink(): void + { + $project = $this->getProject(); + + $this->assertSame($project->getFooterLink(), [ + 'href' => '', + 'target' => '', + 'rel' => '', + 'before_text' => '', + 'link_text' => '', + 'after_text' => '', + ]); + + $project = $this->getProject([ + 'footer_link' => [ + 'href' => 'https://github.com/code-lts/doctum', + 'rel' => 'noreferrer noopener', + 'target' => '_blank', + 'before_text' => 'You can edit the configuration', + 'link_text' => 'on this', // Required if the href key is set + 'after_text' => 'repository', + ], + ]); + + $this->assertSame($project->getFooterLink(), [ + 'href' => 'https://github.com/code-lts/doctum', + 'target' => '_blank', + 'rel' => 'noreferrer noopener', + 'before_text' => 'You can edit the configuration', + 'link_text' => 'on this', + 'after_text' => 'repository', + ]); + } }