Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feature/rendering rework #16

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
edd6345
Move grid rendering into single template files
Sep 2, 2018
1bc3d32
Update rendering of grid system using new single template
Sep 2, 2018
063193f
Fix RowViewHelper not being compiled
Sep 3, 2018
1e46343
Generalize methods and properties from grid ViewHelpers
Sep 3, 2018
bd20886
Generalize grid ViewHelper rendering and unify render methods
Sep 3, 2018
99161e5
Fix compiling of grid ViewHelpers
Sep 3, 2018
4ebbce6
Implement a template service for the grid system templates
Sep 3, 2018
777315e
Fix code style
Sep 3, 2018
1e2927d
Move grid rendering logic from ViewHelpers into Renderer class
Sep 3, 2018
b5302ad
Empty `current` variable in column rendering
Sep 3, 2018
d2e5479
Fix code style
Sep 4, 2018
6ed4f25
Rework grid templates and the template service
Sep 4, 2018
4052f35
Update grid rendering based on the new templates
Sep 4, 2018
5189d0c
Remove row rendering method from template service
Sep 4, 2018
83e8134
Implement fluid template parser interceptor to emit PostParseEvent
Sep 4, 2018
e61c639
Implement templating ViewHelpers for grid templates
Sep 4, 2018
7c665f6
Update template service to use auto-generated row sections
Sep 4, 2018
23f986b
Improve template ContentViewHelper
Sep 7, 2018
b1583e9
Rename template content ViewHelper and update usage
Sep 7, 2018
f5eac48
Fix RowContentViewHelper compiling
Sep 7, 2018
89d1a1a
Setup cache for GridTemplateService
Sep 7, 2018
a62bfd7
Rework grid row sections rendering
Sep 7, 2018
df80807
Revert parsing based row split
Sep 7, 2018
390ef90
Add additional arguments to grid template rendering
Sep 8, 2018
d898699
Remove flexform config hydrate DataProcessor from columns
Sep 8, 2018
996e597
Setup nimut/testing-framework
Sep 9, 2018
757e614
Add ViewHelpers unit tests
Sep 9, 2018
34465be
Update rendering API to be better testable
Sep 9, 2018
dee91ae
Implement functional TestCase for template service
Sep 9, 2018
e434f0a
Update travis CI config to run tests
Sep 9, 2018
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
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ before_script:
script:
- find . -name \*.php ! -path "./.Build/*" | parallel --gnu php -d display_errors=stderr -l {} > /dev/null \;
- .Build/bin/php-cs-fixer fix --dry-run --verbose --diff-format=udiff
- .Build/bin/phpunit -c .Build/vendor/nimut/testing-framework/res/Configuration/UnitTests.xml Tests/Unit/
- >
export typo3DatabaseName="typo3";
export typo3DatabaseHost="localhost";
export typo3DatabaseUsername="root";
export typo3DatabasePassword="";
.Build/bin/phpunit -c .Build/vendor/nimut/testing-framework/res/Configuration/FunctionalTests.xml Tests/Functional/
42 changes: 0 additions & 42 deletions Classes/DataProcessing/HydrateFlexFormConfig.php

This file was deleted.

224 changes: 224 additions & 0 deletions Classes/Rendering/GridRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php
namespace Arndtteunissen\ColumnLayout\Rendering;

/*
* This file is part of the package arndtteunissen/column-layout.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use Arndtteunissen\ColumnLayout\Service\GridSystemTemplateService;
use Arndtteunissen\ColumnLayout\Utility\EmConfigurationUtility;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Service\FlexFormService;
use TYPO3Fluid\Fluid\Core\Rendering\RenderableClosure;

/**
* This class is responsible for rendering content into a grid system.
* It provides public member methods to render a row and a column. This members can be used by several integrations
* (e.g. ViewHelpers, USER content object, custom content object, etc.).
*/
class GridRenderer implements SingletonInterface
{
/**
* @var GridSystemTemplateService
*/
protected $templateService;

/**
* @var array contains the grid rendering state
*/
protected $state;

/**
* @return GridRenderer
*/
public static function getInstance()
{
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);

return $objectManager->get(static::class);
}

/**
* @param GridSystemTemplateService $templateService
*/
public function injectTemplateService(GridSystemTemplateService $templateService)
{
$this->templateService = $templateService;
}

/**
* Renders a grid row.
* Initializes a new grid state for this row.
* After its content has been rendered it automatically closes the row after the last content element.
*
* @param int $colPos backend layout colPos
* @param \Closure $renderContentClosure content inside the row
* @param array $additionalArguments passed to template rendering
* @return string row HTML
*/
public function renderRow(int $colPos, \Closure $renderContentClosure, array $additionalArguments = [])
{
if (!$this->shouldRenderRow($colPos)) {
return $renderContentClosure();
}

$output = '';

// Initialize state
if (!isset($this->state[$colPos])) {
$this->state[$colPos] = [
'enabled' => true,
'has_row_began' => false,
'has_row_end' => false
];
}

$state = &$this->state[$colPos];

$variables = [
'state' => &$state,
'arguments' => $additionalArguments
];

// Render child content
$output .= $renderContentClosure();

/*
* IV) Render closing row html, if
* 1. content has been rendered
* 2. row has been opened before
* 3. row has not been closed before
*/
if ($output
&& $state['has_row_began']
&& !$state['has_row_end']) {
$output .= $this->templateService->renderRowEndHtml($colPos, $variables);
}

// Reset state
$this->state[$colPos] = [];

return $output;
}

/**
* Decides whether a row should be rendered based on the given colPos.
*
* @param int $colPos backend layout colPos
* @return bool TRUE if it is enabled
*/
public function shouldRenderRow(int $colPos): bool
{
$emConfig = EmConfigurationUtility::getSettings();

return !in_array($colPos, $emConfig->getColPosListForDisable());
}

/**
* Renders a grid column.
* Renders row closing and opening html before the given content element based on the state.
* As this method heavily depends on the grid state it is crucial to call this only if the
* GridRenderer::renderRow method has been called before!
*
* @param array $record tt_content record of the content to be rendered
* @param \Closure $renderContentClosure content inside the column
* @param array $additionalArguments passed to template rendering
* @return string column HTML
*/
public function renderColumn(array $record, \Closure $renderContentClosure, array $additionalArguments = [])
{
if (!$this->shouldRenderColumn($record)) {
return $renderContentClosure();
}

$output = '';

// Get state
$colPos = $record['colPos'];
$state = &$this->state[$colPos];

// Fetch config for column
$currentLayoutConfig = $this->getColumnLayoutConfig($record);

$variables = [
'settings' => $currentLayoutConfig,
'state' => &$state,
'data' => $record,
'arguments' => $additionalArguments
];

/*
* I) Render the closing row html, if
* 1. a row has been opened before,
* 2. a row has not been closed before
* 3. this element requires a new row (including fullwidth)
*/
if ($state['has_row_began']
&& !$state['has_row_end']
&& ((int)$currentLayoutConfig['row_fullwidth'] === 1
|| (int)$currentLayoutConfig['row_behaviour'] === 1)) {
$output .= $this->templateService->renderRowEndHtml($colPos, $variables);
$state['has_row_began'] = false;
$state['has_row_end'] = true;
}

/*
* II) Render the opening row html, if
* 1. this is the first element, or
* 2. this element requires a new row
* 1. a row has been closed before
*/
if (!$state['has_row_began']
|| ($state['has_row_end']
&& ((int)$currentLayoutConfig['row_fullwidth'] === 1
|| (int)$currentLayoutConfig['row_behaviour'] === 1))) {
$output .= $this->templateService->renderRowBeginHtml($colPos, $variables);
$state['has_row_began'] = true;
$state['has_row_end'] = false;
}

// III) Render column wrap
$content = new RenderableClosure();
$content
->setName('column-content')
->setClosure($renderContentClosure);

$variables['column_content'] = $content;

$output .= $this->templateService->renderColumnHtml($variables);

return $output;
}

/**
* Decides whether a column should be rendered based on the grid rendering state.
*
* @param array $record
* @return bool
*/
public function shouldRenderColumn(array $record): bool
{
$colPos = $record['colPos'];

return !empty($this->state[$colPos]['enabled']);
}

/**
* Return the column layout flexform configuration from current element as array.
*
* @param array $record
* @return array
*/
protected function getColumnLayoutConfig(array $record): array
{
// TODO: implement caching
$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);

return $flexFormService->convertFlexFormContentToArray($record['tx_column_layout_column_config']);
}
}
Loading