Skip to content

Commit

Permalink
Merge bb8ad94 into beda1e1
Browse files Browse the repository at this point in the history
  • Loading branch information
becquerel committed Jun 23, 2019
2 parents beda1e1 + bb8ad94 commit 58ee472
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 6 deletions.
12 changes: 12 additions & 0 deletions Entities/Block.php
Expand Up @@ -6,6 +6,13 @@
use Illuminate\Database\Eloquent\Model;
use Laracasts\Presenter\PresentableTrait;

/**
* Class Block
* @property string $name
* @property bool $online
* @property string $body
* @property string $shortcode
*/
class Block extends Model
{
use Translatable, PresentableTrait;
Expand Down Expand Up @@ -33,4 +40,9 @@ public function __call($method, $parameters)
#i: No relation found, return the call to parent (Eloquent) to handle it.
return parent::__call($method, $parameters);
}

public function getShortcodeAttribute()
{
return sprintf('[[BLOCK(%s)]]', $this->name);
}
}
59 changes: 59 additions & 0 deletions Http/Middleware/RenderBlock.php
@@ -0,0 +1,59 @@
<?php

namespace Modules\Block\Http\Middleware;

use Illuminate\Http\Response;
use Modules\Block\Repositories\BlockRepository;

class RenderBlock
{
/** @var BlockRepository */
private $blockRepository;

public function __construct(BlockRepository $blockRepository)
{
$this->blockRepository = $blockRepository;
}

public function handle($request, \Closure $next)
{
/** @var Response $response */
$response = $next($request);

// do not replace shortcodes and render blocks on backend
if (app('asgard.onBackend') === true) {
return $response;
}

// if this is not a standard Response, return right away
if(!$response instanceof Response) {
return $response;
}

$response->setContent($this->replaceShortcodes($response->getContent()));

return $response;
}

/**
* replaces all block shortcodes from the response HTML with the actual block body
* @param string $html
* @return string
*/
private function replaceShortcodes($html)
{
preg_match_all('/\[\[BLOCK\((.*)\)\]\]/U', $html, $matches);
$replaceBlocks = [];
foreach ($matches[1] as $blockIndex => $blockName) {
// prevent loading same block twice
if (isset($replaceBlocks[$matches[0][$blockIndex]])) {
continue;
}

$replaceBlocks[$matches[0][$blockIndex]] = $this->blockRepository->get($blockName);
}

return str_replace(array_keys($replaceBlocks), $replaceBlocks, $html);

}
}
4 changes: 2 additions & 2 deletions Repositories/BlockRepository.php
Expand Up @@ -14,9 +14,9 @@ interface BlockRepository extends BaseRepository
public function allOnlineInLang($lang);

/**
* Get a block by its name if it's online
* Get a block body by its name if it's online
* @param string $name
* @return object
* @return string
*/
public function get($name);
}
4 changes: 2 additions & 2 deletions Repositories/Cache/CacheBlockDecorator.php
Expand Up @@ -33,9 +33,9 @@ function () use ($lang) {
}

/**
* Get a block by its name if it's online
* Get a block body by its name if it's online
* @param string $name
* @return object
* @return string
*/
public function get($name)
{
Expand Down
4 changes: 2 additions & 2 deletions Repositories/Eloquent/EloquentBlockRepository.php
Expand Up @@ -64,9 +64,9 @@ public function allOnlineInLang($lang)
}

/**
* Get a block by its name if it's online
* Get a block body by its name if it's online
* @param string $name
* @return object
* @return string
*/
public function get($name)
{
Expand Down
1 change: 1 addition & 0 deletions Resources/lang/en/blocks.php
Expand Up @@ -24,6 +24,7 @@
],
'online' => 'Online',
'name' => 'Name',
'shortcode' => 'Shortcode',
'body' => 'Body',
'list resource' => 'List blocks',
'create resource' => 'Create blocks',
Expand Down
5 changes: 5 additions & 0 deletions Resources/views/admin/blocks/index.blade.php
Expand Up @@ -31,6 +31,7 @@
<th>Id</th>
<th>{{ trans('block::blocks.online') }}</th>
<th>{{ trans('block::blocks.name') }}</th>
<th>{{ trans('block::blocks.shortcode') }}</th>
<th>{{ trans('core::core.table.created at') }}</th>
<th data-sortable="false">{{ trans('core::core.table.actions') }}</th>
</tr>
Expand All @@ -54,6 +55,9 @@
{{ $block->name }}
</a>
</td>
<td>
<pre>{{ $block->shortcode }}</pre>
</td>
<td>
<a href="{{ route('admin.block.block.edit', [$block->id]) }}">
{{ $block->created_at }}
Expand All @@ -74,6 +78,7 @@
<th>Id</th>
<th>{{ trans('block::blocks.online') }}</th>
<th>{{ trans('block::blocks.name') }}</th>
<th>{{ trans('block::blocks.shortcode') }}</th>
<th>{{ trans('core::core.table.created at') }}</th>
<th>{{ trans('core::core.table.actions') }}</th>
</tr>
Expand Down
45 changes: 45 additions & 0 deletions readme.md
Expand Up @@ -51,6 +51,51 @@ After this, you'll be able to get the content of a block with the following code
{!! Block::get('block-name') !!}
```

Each block also receives a shortcode that can be used instead of the code mentioned above. Shortcode looks like this `[[BLOCK(block-name)]]`.
This is very useful if you for example want to allow users to reuse and enter blocks into content of the WYSIWYG editor (page or blog article body)

If you want to use shortcodes in your app, you need to register `RenderBlock` middleware responsible for parsing the response and replacing the shortcodes
with the actual block content. It can be done globally by editing `app/Http/Kernel.php` file and adding `\Modules\Block\Http\Middleware\RenderBlock::class`
into the `$middlewareGroups` `web` group (this way, block shortcodes will be automatically replaced in all `web` routes on frontend):
```php

<?php
// app/Http/Kernel.php
...
protected $middlewareGroups = [
'web' => [
...
\Modules\Block\Http\Middleware\RenderBlock::class,
]
...
}
```

There are some drawbacks to this approach, specifically that each response will be parsed and searched for the shortcodes before returning
back to the user, which may slightly slow down your application. If you know that you do not need to use shortcodes in the whole app,
middleware can be applied selectively only to some routes or route groups in your application:

```php
<?php
// Modules/YourModule/Http/frontendRoutes.php
...
// middleware will be applied to this specific route
$router->get('your-url', 'YourController@method')
->middleware(\Modules\Block\Http\Middleware\RenderBlock::class);
...
// middleware will be applied to whole group
$router->group(['middleware' => \Modules\Block\Http\Middleware\RenderBlock::class], function(Router $router) {
$router->get('your-url', 'YourController@method');
...
});
...
?>

```

Keep in mind that by allowing users to put blocks/shortcodes anywhere, you are creating a potential security issue, so
use this functionality carefully.


### Hooks

Expand Down

0 comments on commit 58ee472

Please sign in to comment.