Skip to content

Commit

Permalink
Merge pull request #52 from terabytesoftw/Terawidget
Browse files Browse the repository at this point in the history
Widgets
  • Loading branch information
samdark committed Sep 4, 2019
2 parents e039ceb + 5aa3a9d commit 9e00c63
Show file tree
Hide file tree
Showing 22 changed files with 1,603 additions and 421 deletions.
2 changes: 2 additions & 0 deletions config/common.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<?php

use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Asset\AssetConverter;
use Yiisoft\Asset\AssetConverterInterface;
use Yiisoft\Asset\AssetManager;
use Yiisoft\Factory\Definitions\Reference;
use Yiisoft\Log\Logger;
use Yiisoft\Widget\Widget;

return [
Aliases::class => [
Expand Down
27 changes: 19 additions & 8 deletions config/tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
use Yiisoft\Factory\Definitions\Reference;
use Yiisoft\Log\Logger;
use Yiisoft\View\Theme;
use Yiisoft\View\View;
use Yiisoft\View\WebView;
use Yiisoft\Widget\Widget;

$tempDir = sys_get_temp_dir();

return [
ContainerInterface::class => function (ContainerInterface $container) {
return $container;
},

Aliases::class => [
'@root' => dirname(__DIR__, 1),
'@public' => '@root/tests/public',
Expand Down Expand Up @@ -70,13 +74,20 @@
'__class' => Theme::class,
],

View::class => [
'__class' => View::class,
WebView::class => function (ContainerInterface $container) {
$aliases = $container->get(Aliases::class);
$eventDispatcher = $container->get(EventDispatcherInterface::class);
$theme = $container->get(Theme::class);
$logger = $container->get(LoggerInterface::class);

return new WebView($aliases->get('@view'), $theme, $eventDispatcher, $logger);
},

Widget::class => [
'__class' => Widget::class,
'__construct()' => [
'basePath'=> $tempDir . DIRECTORY_SEPARATOR . 'views',
'theme'=> Reference::to(Theme::class),
'eventDispatcher' => Reference::to(EventDispatcherInterface::class),
'logger' => Reference::to(LoggerInterface::class)
],
Reference::to(EventDispatcherInterface::class),
Reference::to(WebView::class),
]
],
];
64 changes: 45 additions & 19 deletions src/View/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class View implements DynamicContentAwareInterface
* content. You can call {@see beginBlock()} and {@see endBlock()} to capture small fragments of a view.
* They can be later accessed somewhere else through this property.
*/
public $blocks;
private $blocks;

/**
* @var ViewContextInterface the context under which the {@see {renderFile()} method is being invoked.
Expand Down Expand Up @@ -141,6 +141,35 @@ public function setLanguage(string $language): void
$this->language = $language;
}

/**
* {@see blocks}
*
* @param string $id
* @param string $value
*
* @return void
*/
public function setBlocks(string $id, string $value): void
{
$this->blocks[$id] = $value;
}

/**
* {@see blocks}
*
* @param string $value
*
* @return string
*/
public function getBlock(string $value): string
{
if (isset($this->blocks[$value])) {
return $this->blocks[$value];
}

throw new \InvalidArgumentException('Block: ' . $value. ' not found.');
}

/**
* Renders a view.
*
Expand Down Expand Up @@ -170,7 +199,7 @@ public function setLanguage(string $language): void
*
* {@see renderFile()}
*/
public function render($view, $params = [], $context = null)
public function render($view, $params = [], $context = null): string
{
$viewFile = $this->findTemplateFile($view, $context);
return $this->renderFile($viewFile, $params, $context);
Expand Down Expand Up @@ -234,9 +263,10 @@ protected function findTemplateFile(string $view, $context = null): string
* @param object $context the context that the view should use for rendering the view. If null, existing [[context]]
* will be used.
*
* @throws ViewNotFoundException if the view file does not exist
*
* @return string the rendering result
* @throws \Throwable
*
* @throws ViewNotFoundException if the view file does not exist
*/
public function renderFile(string $viewFile, array $params = [], object $context = null): string
{
Expand Down Expand Up @@ -268,7 +298,7 @@ public function renderFile(string $viewFile, array $params = [], object $context
$renderer = $this->renderers[$ext] ?? new PhpTemplateRenderer();
$output = $renderer->render($this, $viewFile, $params);

$this->afterRender($viewFile, $params, $output);
$output = $this->afterRender($viewFile, $params, $output);
}

array_pop($this->viewFiles);
Expand Down Expand Up @@ -347,7 +377,7 @@ protected function getRequestedViewFile()
public function beforeRender(string $viewFile, array $params): bool
{
$event = new BeforeRender($viewFile, $params);
$this->eventDispatcher->dispatch($event);
$event = $this->eventDispatcher->dispatch($event);

return !$event->isPropagationStopped();
}
Expand All @@ -366,7 +396,7 @@ public function beforeRender(string $viewFile, array $params): bool
public function afterRender(string $viewFile, array $params, &$output): string
{
$event = new AfterRender($viewFile, $params, $output);
$this->eventDispatcher->dispatch($event);
$event = $this->eventDispatcher->dispatch($event);

return $event->getResult();
}
Expand Down Expand Up @@ -475,7 +505,7 @@ public function evaluateDynamicContent(string $statements)
*
* @return DynamicContentAwareInterface[] class instances supporting dynamic contents.
*/
public function getDynamicContents()
public function getDynamicContents(): array
{
return $this->cacheStack;
}
Expand Down Expand Up @@ -515,13 +545,11 @@ public function popDynamicContent(): void
*
* @return Block the Block widget instance
*/
public function beginBlock($id, $renderInPlace = false): Block
public function beginBlock(string $id, $renderInPlace = false): Block
{
return Block::begin([
'id' => $id,
'renderInPlace' => $renderInPlace,
'view' => $this,
]);
return Block::begin()
->id($id)
->renderInPlace($renderInPlace);
}

/**
Expand Down Expand Up @@ -556,11 +584,9 @@ public function endBlock(): void
*/
public function beginContent(string $viewFile, array $params = []): ContentDecorator
{
return ContentDecorator::begin([
'viewFile' => $viewFile,
'params' => $params,
'view' => $this,
]);
return ContentDecorator::begin()
->params($params)
->viewFile($viewFile);
}

/**
Expand Down
7 changes: 3 additions & 4 deletions src/View/WebView.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,13 @@ protected function registerAssetFiles(string $name): void
public function registerAssetBundle(string $name, ?int $position = null): AssetBundle
{
if (!isset($this->assetBundles[$name])) {
$am = $this->getAssetManager();
$bundle = $am->getBundle($name);
$bundle = $this->getAssetManager()->getBundle($name);

$this->assetBundles[$name] = false;

// register dependencies

$pos = isset($bundle->jsOptions['position']) ? $bundle->jsOptions['position'] : null;
$pos = $bundle->jsOptions['position'] ?? null;

foreach ($bundle->depends as $dep) {
$this->registerAssetBundle($dep, $pos);
Expand All @@ -341,7 +340,7 @@ public function registerAssetBundle(string $name, ?int $position = null): AssetB
}

if ($position !== null) {
$pos = isset($bundle->jsOptions['position']) ? $bundle->jsOptions['position'] : null;
$pos = $bundle->jsOptions['position'] ?? null;

if ($pos === null) {
$bundle->jsOptions['position'] = $pos = $position;
Expand Down
69 changes: 58 additions & 11 deletions src/Widget/Block.php
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
<?php
declare(strict_types = 1);

namespace Yiisoft\Widget;

/**
* Block records all output between [[begin()]] and [[end()]] calls and stores it in [[\yii\base\View::$blocks]].
* for later use.
* Block records all output between {@see begin()} and {@see end()} calls and stores it in
* {@see \Yiisoft\View\View::$blocks}.
*
* {@see \Yiisoft\View\View} component contains two methods {\Yiisoft\View\View::beginBlock()} and
* {[\Yiisoft\View\View::endBlock()}.
*
* [[\yii\base\View]] component contains two methods [[\yii\base\View::beginBlock()]] and [[\yii\base\View::endBlock()]].
* The general idea is that you're defining block default in a view or layout:
*
* ```php
* <?php $this->beginBlock('messages', true) ?>
* <?php $this->beginBlock('index') ?>
* Nothing.
* <?php $this->endBlock() ?>
* ```
*
* And then overriding default in sub-views:
* And then overriding default in views:
*
* ```php
* <?php $this->beginBlock('username') ?>
* <?php $this->beginBlock('index') ?>
* Umm... hello?
* <?php $this->endBlock() ?>
* ```
*
* in subviews show block:
*
* <?= $this->getBlock('index') ?>
*
* Second parameter defines if block content should be outputted which is desired when rendering its content but isn't
* desired when redefining it in subviews.
*
* @method static Block begin()
* @method static Block end()
*/
class Block extends Widget
{
/**
* @var bool whether to render the block content in place. Defaults to false,
* meaning the captured block content will not be displayed.
* @var string $id
*/
private $id;

/**
* @var bool whether to render the block content in place. Defaults to false, meaning the captured block content
* will not be displayed.
*/
public $renderInPlace = false;
private $renderInPlace = false;

/**
* Starts recording a block.
Expand All @@ -42,7 +57,7 @@ public function init(): void
parent::init();

ob_start();
ob_implicit_flush(false);
ob_implicit_flush(0);
}

/**
Expand All @@ -54,11 +69,43 @@ public function init(): void
public function run(): string
{
$block = ob_get_clean();

if ($this->renderInPlace) {
return $block;
}
$this->view->blocks[$this->getId()] = $block;

if (!empty($block)) {
$this->getView()->setBlocks($this->id, $block);
}

return '';
}

/**
* {@see renderInPlace}
*
* @param string $value
*
* @return $this
*/
public function id(string $value): self
{
$this->id = $value;

return $this;
}

/**
* {@see renderInPlace}
*
* @param boolean $value
*
* @return $this
*/
public function renderInPlace(bool $value): self
{
$this->renderInPlace = $value;

return $this;
}
}
Loading

0 comments on commit 9e00c63

Please sign in to comment.