Skip to content

Commit

Permalink
[TASK] Improve backend modules
Browse files Browse the repository at this point in the history
- Rootline now shown for storage selectors
- Authors are now linked
- Filtering and search improved
- Styling improved
- Icons shown for pages and storages
- Entrypoints from setup to posts and comments

Fixes: #107
  • Loading branch information
benjaminkott committed Mar 4, 2020
1 parent d17e2a4 commit 569c2ff
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 94 deletions.
1 change: 1 addition & 0 deletions Classes/Controller/BackendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public function initializeAction(): void

public function initializeSetupWizardAction(): void
{
$this->initializeDataTables();
$this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Blog/SetupWizard');
}

Expand Down
17 changes: 6 additions & 11 deletions Classes/Service/SetupService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;

class SetupService
{
Expand Down Expand Up @@ -46,9 +47,14 @@ public function determineBlogSetups(): array
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogUid, \PDO::PARAM_INT)))
->execute()
->fetchColumn();
$rootline = array_reverse(GeneralUtility::makeInstance(RootlineUtility::class, $blogUid)->get());
$setups[$blogUid] = [
'uid' => $blogUid,
'title' => $title,
'path' => implode(' / ', array_map(function ($page) {
return $page['title'];
}, $rootline)),
'rootline' => $rootline,
'articleCount' => $blogRootPage['cnt'],
];
}
Expand All @@ -57,17 +63,6 @@ public function determineBlogSetups(): array
return $setups;
}

public function getBlogRecordAsArray(int $uid): array
{
$queryBuilder = $this->getQueryBuilderForTable('pages');
return $queryBuilder
->select('*')
->from('pages')
->where($queryBuilder->expr()->eq('uid', $uid))
->execute()
->fetch();
}

public function createBlogSetup(array $data): bool
{
$title = array_key_exists('title', $data) ? (string)$data['title'] : null;
Expand Down
76 changes: 76 additions & 0 deletions Classes/ViewHelpers/Link/Be/AuthorViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
declare(strict_types = 1);

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

namespace T3G\AgencyPack\Blog\ViewHelpers\Link\Be;

use T3G\AgencyPack\Blog\Domain\Model\Author;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;

class AuthorViewHelper extends AbstractTagBasedViewHelper
{
public function __construct()
{
$this->tagName = 'a';
parent::__construct();
}

/**
* Arguments initialization.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerUniversalTagAttributes();
$this->registerTagAttribute('target', 'string', 'Target of link');
$this->registerTagAttribute('itemprop', 'string', 'itemprop attribute');
$this->registerTagAttribute('rel', 'string', 'Specifies the relationship between the current document and the linked document');

$this->registerArgument('author', Author::class, 'The author to link to');
$this->registerArgument('returnUri', 'bool', 'return only uri', false, false);
}

/**
* @return string Rendered page URI
*
* @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
* @throws \InvalidArgumentException
*/
public function render(): string
{
/** @var Author $author */
$author = $this->arguments['author'];
$authorUid = $author !== null ? (int)$author->getUid() : 0;

$routingUriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$uri = $routingUriBuilder->buildUriFromRoute('record_edit', ['edit[tx_blog_domain_model_author][' . $authorUid . ']' => 'edit']);
$arguments = GeneralUtility::_GET();
$route = $arguments['route'];
unset($arguments['route'], $arguments['token']);
$uri .= '&returnUrl=' . rawurlencode((string)GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoutePath($route, $arguments));
if ($uri !== '') {
if ($this->arguments['returnUri']) {
return $uri;
}
$linkText = $this->renderChildren() ?: $author->getName();
$this->tag->addAttribute('href', $uri);
$this->tag->setContent($linkText);
$result = $this->tag->render();
} else {
$result = $this->renderChildren();
}

return $result;
}
}
48 changes: 19 additions & 29 deletions Resources/Private/JavaScript/backend/Datatables.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,44 @@ import 'datatables.net';
import 'datatables.net-bs';

$('.dataTables').DataTable({
"columns": function() {
"columns": function () {
return $(this).data('columns')
},
"pageLength": 10,
"pageLength": 25,
"initComplete": function () {
this.api().columns().every( function () {
this.api().columns().every(function () {
var column = this;
if ($(column.header()).data('filter') === true) {
var select = $('<select><option value="">' + $(column.header()).text() + '</option></select>')
.appendTo( $(column.header()).empty() )
.on('click', function(e) {
.appendTo($(column.header()).empty())
.on('click', function (e) {
e.stopPropagation();
})
.on( 'change', function () {
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? val : '', true, false )
.draw();
} );
column.search(val ? val : '', true, false).draw();
});

var values = [];
column.data().each(function(d, j) {
var $object = $(d);
if ($object.find('li').length > 0) {
$object.find('li').each(function() {
var str = $(this).text().trim();
if (str !== '') {
values.push(str);
}
column.nodes().each(function (content) {
var filter = $(content).data('filter');
if (typeof filter !== "undefined") {
var entries = filter.split(',');
entries.forEach(function (entry) {
if (entry.trim() !== '') values.push(entry.trim());
});
} else {
if (d !== '') {
var str = $('<span>').text(d).text().trim();
if (str !== '') {
values.push(str);
}
}
}
});
values = values.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
$(values).sort().each(function() {
$(values).sort().each(function () {
var value = this;
select.append( '<option value="'+value+'">'+value+'</option>' )
} );
select.append('<option value="' + value + '">' + value + '</option>')
});
}
} );
});
}
});
4 changes: 2 additions & 2 deletions Resources/Private/Language/locallang.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,10 @@
<source>Actions</source>
</trans-unit>
<trans-unit id="backend.table.title" xml:space="preserve">
<source>Articles</source>
<source>Title</source>
</trans-unit>
<trans-unit id="backend.table.author" xml:space="preserve">
<source>Author</source>
<source>Authors</source>
</trans-unit>
<trans-unit id="backend.table.categories" xml:space="preserve">
<source>Categories</source>
Expand Down
11 changes: 10 additions & 1 deletion Resources/Private/Partials/Backend/BlogFilter.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
<f:form class="form-inline" action="{action}">
<div class="form-group">
<label for="blogSetup"><f:translate key="label.blog" /></label>
<f:form.select class="form-control" name="blogSetup" id="blogSetup" value="{activeBlogSetup}" options="{blogSetups}" optionLabelField="title" optionValueField="uid" prependOptionLabel="{f:translate(key: 'label.all')}" prependOptionValue="" />
<f:form.select
class="form-control"
name="blogSetup"
id="blogSetup"
value="{activeBlogSetup}"
options="{blogSetups}"
optionLabelField="path"
optionValueField="uid"
prependOptionLabel="{f:translate(key: 'label.all')}"
prependOptionValue="" />
</div>
<button type="submit" class="btn btn-default"><f:translate key="label.choose_blog" /></button>
</f:form>
21 changes: 0 additions & 21 deletions Resources/Private/Scss/backend/backend.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,6 @@
.table-fit {
margin-top: 1rem;
}
table.table a {
color: #e3612a;
}
table.table a:hover {
color: #e3612a;
}

/**
* List Inline
*/
.list-inline {
margin-bottom: 0;
li {
&:after {
content: ", ";
}
&:last-child:after {
content: "";
}
}
}

/**
* List Filter
Expand Down
14 changes: 10 additions & 4 deletions Resources/Private/Templates/Backend/Comments.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h1><f:translate key="backend.headline.comments" /></h1>
<f:form class="form-inline" action="updateCommentStatus">
<f:form.hidden name="filter" value="{activeFilter}" />
<f:form.hidden name="blogSetup" value="{activeBlogSetup}" />
<table class="table table-striped table-bordered table-comments dataTables" data-columns='[{"searchable": false, "orderable": false}, {"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "num"}]'>
<table class="table table-striped table-hover table-comments dataTables" data-columns='[{"searchable": false, "orderable": false}, {"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "num"}]'>
<thead>
<tr>
<th><f:translate key="backend.table.actions" /></th>
Expand All @@ -24,16 +24,22 @@ <h1><f:translate key="backend.headline.comments" /></h1>
<tbody>
<f:for each="{comments}" as="comment">
<tr>
<td class="actions"><f:render section="Actions" arguments="{_all}" /></td>
<td data-search="{comment.name}" data-filter="{comment.name}"><strong>{comment.name}</strong></td>
<td class="actions">
<f:render section="Actions" arguments="{_all}" />
</td>
<td data-search="{comment.name}" data-filter="{comment.name}">
{comment.name}
</td>
<td>{comment.comment}</td>
<td data-search="{comment.post.title}" data-filter="{comment.post.title}">
<f:if condition="{comment.post}">
<f:then><blogvh:link.be.post post="{comment.post}" /></f:then>
<f:else><f:translate key="backend.message.nopost" /></f:else>
</f:if>
</td>
<td data-order="{f:format.date(format: 'U', date: comment.crdate)}"><f:format.date format="d.m.Y">{comment.crdate}</f:format.date></td>
<td data-order="{f:format.date(format: 'U', date: comment.crdate)}">
<f:format.date format="d.m.Y">{comment.crdate}</f:format.date>
</td>
</tr>
</f:for>
</tbody>
Expand Down
72 changes: 56 additions & 16 deletions Resources/Private/Templates/Backend/Posts.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ <h1><f:translate key="backend.headline.posts" /></h1>
<f:if condition="{f:count() -> posts} > 0">
<f:then>

<table class="table table-striped table-bordered dataTables" data-columns='[{"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "num"}]'>
<table class="table table-striped table-hover dataTables" data-columns='[{"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "string"}, {"type": "num"}]'>
<thead>
<tr>
<th><f:translate key="backend.table.title" /></th>
Expand All @@ -21,23 +21,63 @@ <h1><f:translate key="backend.headline.posts" /></h1>
<tbody>
<f:for each="{posts}" as="post">
<tr>
<td data-search="{post.title}" data-filter="{post.title}"><blogvh:link.be.post post="{post}" /></td>
<td data-search="{post.authors.0.name}" data-filter="{post.authors.0.name}">{post.authors.0.name}</td>
<td>
<f:if condition="{post.categories}">
<ul class="list-inline">
<f:for each="{post.categories}" as="category"><li><blogvh:link.be.category category="{category}" /></li></f:for>
</ul>
</f:if>

<td class="nowrap" data-search="{post.title}" data-filter="{post.title}">
<blogvh:link.be.post post="{post}">
<core:icon identifier="record-blog-post" />
{post.title}
</blogvh:link.be.post>
</td>
<td>
<f:if condition="{post.tags}">
<ul class="list-inline">
<f:for each="{post.tags}" as="tag"><li><blogvh:link.be.tag tag="{tag}" /></li></f:for>
</ul>
</f:if>

<f:variable name="authorString" value="" />
<f:if condition="{post.authors}">
<f:for each="{post.authors}" as="author" iteration="{iteration}">
<f:variable name="authorString" value="{authorString}{author.name}" />
<f:if condition="{iteration.isLast}">
<f:else><f:variable name="authorString" value="{authorString}," /></f:else>
</f:if>
</f:for>
</f:if>
<td class="nowrap" data-search="{authorString}" data-filter="{authorString}">
<f:for each="{post.authors}" as="author" iteration="iteration">
<blogvh:link.be.author author="{author}" /><f:if condition="{iteration.isLast}"><f:else>, </f:else></f:if>
</f:for>
</td>
<td data-order="{f:format.date(format: 'U', date: post.publishDate)}"><f:format.date format="d.m.Y">{post.publishDate}</f:format.date></td>

<f:variable name="categoryString" value="" />
<f:if condition="{post.categories}">
<f:for each="{post.categories}" as="category" iteration="{iteration}">
<f:variable name="categoryString" value="{categoryString}{category.title}" />
<f:if condition="{iteration.isLast}">
<f:else><f:variable name="categoryString" value="{categoryString}, " /></f:else>
</f:if>
</f:for>
</f:if>
<td data-search="{categoryString}" data-filter="{categoryString}">
<f:for each="{post.categories}" as="category" iteration="iteration">
<blogvh:link.be.category category="{category}" class="label label-info" />
</f:for>
</td>

<f:variable name="tagString" value="" />
<f:if condition="{post.tags}">
<f:for each="{post.tags}" as="tag" iteration="{iteration}">
<f:variable name="tagString" value="{tagString}{tag.title}" />
<f:if condition="{iteration.isLast}">
<f:else><f:variable name="tagString" value="{tagString}," /></f:else>
</f:if>
</f:for>
</f:if>
<td data-search="{tagString}" data-filter="{tagString}">
<f:for each="{post.tags}" as="tag" iteration="iteration">
<blogvh:link.be.tag tag="{tag}" class="label label-info" />
</f:for>
</td>

<td data-order="{f:format.date(format: 'U', date: post.publishDate)}">
<f:format.date format="d.m.Y">{post.publishDate}</f:format.date>
</td>

</tr>
</f:for>
</tbody>
Expand Down
Loading

0 comments on commit 569c2ff

Please sign in to comment.