Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# CHANGELOG

This changelog references the relevant changes done between versions.

To get the diff for a specific change, go to https://github.com/LIN3S/PatternLibraryBuilder/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/LIN3S/PatternLibraryBuilder/compare/v0.1.0...v0.2.0

* 0.2.0
* [BC break] Renderers. Changed configuration yml structure to adapt to new renderer (#12).
To upgrade check renderers documentation.

* 0.1.0
* Initial release
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
# PatternLibraryBuilder
> Library that provides an elegant and easy way to develop a pattern library for your front-end components

## Requirements
PHP >= 7.1</br>
## Features

* YAML config driven pattern library builder
* Opinated and extensible default template
* Use already existing renderers to list colors, typography, iconography
* Render twig templates in responsive viewports and with autogenerated twig "include" method and HTML output
* Easily create your renderer to adapt it to your needs
* Standalone PHP library with built-in Symfony integration

## Installation

The easiest way to install this bundle is using [Composer][1]
```bash
$ composer require lin3s/pattern-library-builder
```

## Documentation
All the documentation is stored in the `docs` folder.

[Show me the docs!](PatternLibraryBuilder/docs/index.md)
* First use
* [Installing and configuring](docs/first_use_installing_and_configuring.md)
* [Your first page](docs/first_use_your_first_page.md)
* Renderers
* [Using renderers](docs/renderers_usage.md)
* [Creating custom renderers](docs/renderers_create_custom.md)
* Theme
* [Customizing default theme](docs/theme_customize_default.md)
* Symfony integration
* [Configuration reference](docs/symfony_configuration_reference.md)

> All the documentation is stored in the `docs` folder.

## Tests
This library is completely tested by **[PHPSpec][2], SpecBDD framework for PHP**.
This library is tested by **[PHPSpec][2], SpecBDD framework for PHP**.

Run the following command to launch tests:
```bash
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"phpspec/phpspec": "^3.3",
"symfony/asset": "^3.3",
"symfony/console": "^3.3",
"symfony/debug-bundle": "^3.3",
"symfony/twig-bundle": "^3.3",
"symfony/var-dumper": "^3.3",
"symfony/web-server-bundle": "^3.3",
Expand Down
3 changes: 3 additions & 0 deletions docs/first_use_installing_and_configuring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Installing and configuring

> TODO
3 changes: 3 additions & 0 deletions docs/first_use_your_first_page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Your first page

For this example we are showing
3 changes: 3 additions & 0 deletions docs/renderers_create_custom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Creating custom renderers

> TODO
3 changes: 3 additions & 0 deletions docs/renderers_usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Using renderers

> TODO
3 changes: 3 additions & 0 deletions docs/symfony_configuration_reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Symfony Configuration reference

> TODO
3 changes: 3 additions & 0 deletions docs/theme_customize_default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Customizing default theme

> TODO
79 changes: 79 additions & 0 deletions src/LIN3S/PatternLibraryBuilder/Config/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

/*
* This file is part of the Pattern Library Builder library.
*
* Copyright (c) 2017-present LIN3S <info@lin3s.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace LIN3S\PatternLibraryBuilder\Config;

/**
* @author Gorka Laucirica <gorka.lauzirika@gmail.com>
*/
final class Config
{
private $config;

public function __construct(array $config)
{
$this->config = $config;
}

public function allInHierarchy(): array
{
return $this->config;
}

public function allInPlain(): array
{
return $this->findAllItemsRecursively($this->config);
}

public function get(string $slug): ?array
{
return $this->findBySlugRecursively($slug, $this->config);
}

private function findBySlugRecursively(string $slug, array $config): ?array
{
if ($config['index'] && $config['index']['slug'] === $slug) {
return $config['index'];
}

foreach ($config['pages'] as $page) {
if ($page['slug'] === $slug) {
return $page;
}
}

foreach ($config['children'] as $child) {
$children = $this->findBySlugRecursively($slug, $child);
if ($children) {
return $children;
}
}

return null;
}

private function findAllItemsRecursively(array $config, array $items = []): array
{
foreach ($config as $child) {
if (isset($child['config'])) {
$items[] = $child;
}

if (isset($child['children'])) {
$items = array_merge($items, $this->findAllItemsRecursively($child['children'], $items));
}
}

return $items;
}
}
118 changes: 118 additions & 0 deletions src/LIN3S/PatternLibraryBuilder/Config/ConfigLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

/*
* This file is part of the Pattern Library Builder library.
*
* Copyright (c) 2017-present LIN3S <info@lin3s.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace LIN3S\PatternLibraryBuilder\Config;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\Yaml\Yaml;

/**
* @author Gorka Laucirica <gorka.lauzirika@gmail.com>
*/
final class ConfigLoader
{
const INDEX_YML = 'index.yml';

private $itemsPath;

public function __construct(string $itemsPath)
{
$this->itemsPath = realpath($itemsPath);
}

public function loadConfig(): Config
{
$items = $this->getDirectoryContent($this->itemsPath);

return new Config($items);
}

private function getDirectoryContent($path): array
{
$finder = new Finder();
$childDirs = $finder->directories()->in($path)->depth(0);

$childConfig = [];

/** @var SplFileInfo $childDir */
foreach ($childDirs as $childDir)
{
$childConfig[] = $this->getDirectoryContent($childDir->getPathname());
}

return [
'title' => $this->titleFromPath($path),
'slug' => $this->slugFromPath($path),
'index' => $this->indexForDirectory($path),
'children' => $childConfig,
'pages' => $this->pagesInDirectory($path)
];
}

private function titleFromPath(string $path): string
{
$fileInfo = pathinfo($path);

return $fileInfo['filename'];
}

private function slugFromPath(string $path): string
{
$slug = str_replace($this->itemsPath, '', $path);
$slug = str_replace('index.yml', '', $slug);
$slug = ltrim($slug, '/');
return str_replace('.yml', '', $slug);
}

private function indexForDirectory(string $path)
{
$indexFilePath = $path . '/' . self::INDEX_YML;
$indexFile = @file_get_contents($indexFilePath);

if(!$indexFile) {
return null;
}

$itemConfig = Yaml::parse($indexFile);

return $this->serializeItemConfig($itemConfig, $indexFilePath);

}

private function pagesInDirectory(string $path): array
{
$finder = new Finder();
$pages = $finder->files()->in($path)->depth(0)->notName(self::INDEX_YML);

$pagesConfig = [];

foreach ($pages as $page) {
$itemConfig = Yaml::parse(file_get_contents($page->getRealPath()));

$pagesConfig[] = $this->serializeItemConfig($itemConfig, $page->getRealPath());
}

return $pagesConfig;
}

private function serializeItemConfig(array $itemConfig, string $configFilePath): array
{
return [
'title' => $this->titleFromPath($configFilePath),
'slug' => $this->slugFromPath($configFilePath),
'config' => $itemConfig,
'status' => $itemConfig['status'],
];
}
}
66 changes: 20 additions & 46 deletions src/LIN3S/PatternLibraryBuilder/Controller/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

namespace LIN3S\PatternLibraryBuilder\Controller;

use LIN3S\PatternLibraryBuilder\Loader\StyleguideConfigLoader;
use LIN3S\PatternLibraryBuilder\Config\ConfigLoader;
use LIN3S\PatternLibraryBuilder\Renderer\RendererRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Expand All @@ -25,69 +26,42 @@
class IndexController
{
private $loader;
private $rendererRegistry;
private $twig;
private $twigFile;

public function __construct(
StyleguideConfigLoader $loader,
\Twig_Environment $twig,
string $twigFile = '@Lin3sPatternLibraryBuilder/pages/architecture.html.twig'
ConfigLoader $loader,
RendererRegistry $rendererRegistry,
\Twig_Environment $twig
) {
$this->loader = $loader;
$this->rendererRegistry = $rendererRegistry;
$this->twig = $twig;
$this->twigFile = $twigFile;
}

public function __invoke(Request $request, string $slug = '') : Response
{
if (!$slug) {
return $this->renderHomepage();
}
$config = $this->loader->loadConfig();

$item = $config->get($slug);

$itemConfig = $this->loader->get($slug);
if (!$itemConfig) {
if (!$item) {
throw new NotFoundHttpException();
}

$media = $request->query->get('media');
if ($media) {
$paramsId = $request->query->get('id');
$renderer = $this->rendererRegistry->get($item['config']['renderer']['type']);

return $this->renderIFrame($media, $itemConfig, $paramsId);
}
$content = $renderer->render($item);

return $this->renderItemPage($itemConfig, $slug);
}

private function renderHomepage() : Response
{
return new Response(
$this->twig->render('@Lin3sPatternLibraryBuilder/pages/home.html.twig', [
'menu' => $this->loader->allInHierarchy(),
])
);
}

private function renderIFrame($media, $item, $paramsId) : Response
{
return new Response($this->twig->render(
sprintf('@Lin3sPatternLibraryBuilder/pages/iframe/%s.html.twig', $media), [
'item' => $item,
'params_id' => $paramsId,
]
));
}

private function renderItemPage($item, string $slug) : Response
{
$twigTemplate = isset($item['template'])
? '@Lin3sPatternLibraryBuilder/pages/' . $item['template'] . '.html.twig'
: $this->twigFile;
if($request->query->has('content_only')) {
return new Response($content);
}

return new Response($this->twig->render($twigTemplate, [
'item' => $item,
'menu' => $this->loader->allInHierarchy(),
return new Response($this->twig->render('@Lin3sPatternLibraryBuilder/pattern_library.html.twig', [
'menu' => $config->allInHierarchy(),
'breadcrumbs' => $this->generateBreadcrumbs($slug),
'content' => $content,
'item' => $item['config']
]));
}

Expand Down
Loading