Commit 4a201443 authored by Markus Klein's avatar Markus Klein Committed by Andreas Fernandez
Browse files

[FEATURE] Add flexible preview link configuration

We add new page TSconfig to allow flexible configuration of preview
links for any record.

Releases: master
Resolves: #66370
Change-Id: I5beac52f9383d17aac424694dd9b3011a1e06776
Reviewed-on: http://review.typo3.org/38639


Reviewed-by: Frans Saris's avatarFrans Saris <franssaris@gmail.com>
Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: Mathias Schreiber's avatarMathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber's avatarMathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: default avatarAndreas Fernandez <andreas.fernandez@aspedia.de>
Tested-by: default avatarAndreas Fernandez <andreas.fernandez@aspedia.de>
parent e004124e
......@@ -23,6 +23,7 @@ use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Frontend\Page\PageRepository;
/**
* Script Class: Drawing the editing form for editing records in TYPO3.
......@@ -386,6 +387,13 @@ class EditDocumentController {
*/
protected $signalSlotDispatcher;
/**
* Stores information needed to preview the currently saved record
*
* @var array
*/
protected $previewData = [];
/**
* Constructor
*/
......@@ -609,6 +617,18 @@ class EditDocumentController {
// Re-compile the store* values since editconf changed...
$this->compileStoreDat();
}
// If a preview is requested
if (isset($_POST['_savedokview_x'])) {
// Get the first table and id of the data array from DataHandler
$table = reset(array_keys($this->data));
$id = reset(array_keys($this->data[$table]));
if (!MathUtility::canBeInterpretedAsInteger($id)) {
$id = $tce->substNEWwithIDs[$id];
}
// Store this information for later use
$this->previewData['table'] = $table;
$this->previewData['id'] = $id;
}
$tce->printLogErrorMessages(isset($_POST['_saveandclosedok_x']) || isset($_POST['_translation_savedok_x']) ? $this->retUrl : $this->R_URL_parts['path'] . '?' . GeneralUtility::implodeArrayForUrl('', $this->R_URL_getvars));
}
// || count($tce->substNEWwithIDs)... If any new items has been save, the document is CLOSED
......@@ -676,11 +696,11 @@ class EditDocumentController {
'height' => $popupWindowHeight
),
);
$this->doc->JScode = $this->doc->wrapScriptTags('
TYPO3.configuration = ' . json_encode($t3Configuration) . ';
// Object: TS:
// passwordDummy and decimalSign are used by tbe_editor.js and have to be declared here as
// TS object overwrites the object declared in tbe_editor.js
$javascript = '
TYPO3.configuration = ' . json_encode($t3Configuration) . ';
// Object: TS:
// passwordDummy and decimalSign are used by tbe_editor.js and have to be declared here as
// TS object overwrites the object declared in tbe_editor.js
function typoSetup() { //
this.uniqueID = "";
this.passwordDummy = "********";
......@@ -706,7 +726,11 @@ class EditDocumentController {
}
return false;
}
' . (isset($_POST['_savedokview_x']) && $this->popViewId ? 'if (window.opener) { ' . BackendUtility::viewOnClick($this->popViewId, '', BackendUtility::BEgetRootLine($this->popViewId), '', $this->viewUrl, $this->popViewId_addParams, FALSE) . ' } else { ' . BackendUtility::viewOnClick($this->popViewId, '', BackendUtility::BEgetRootLine($this->popViewId), '', $this->viewUrl, $this->popViewId_addParams) . ' } ' : ''));
';
$previewCode = isset($_POST['_savedokview_x']) && $this->popViewId ? $this->generatePreviewCode() : '';
$this->doc->JScode = $this->doc->wrapScriptTags($javascript . $previewCode);
// Setting up the context sensitive menu:
$this->doc->getContextMenuCode();
$this->doc->bodyTagAdditions = 'onload="window.scrollTo(0,' . MathUtility::forceIntegerInRange(GeneralUtility::_GP('_scrollPosition'), 0, 10000) . ');"';
......@@ -714,6 +738,103 @@ class EditDocumentController {
$this->emitFunctionAfterSignal(__FUNCTION__);
}
/**
* @return string
*/
protected function generatePreviewCode() {
$currentPageId = MathUtility::convertToPositiveInteger($this->popViewId);
$table = $this->previewData['table'];
$recordId = $this->previewData['id'];
$pageTsConfig = BackendUtility::getPagesTSconfig($currentPageId);
$previewConfiguration = isset($pageTsConfig['TCEMAIN.']['preview.'][$table . '.'])
? $pageTsConfig['TCEMAIN.']['preview.'][$table . '.']
: array();
$recordArray = BackendUtility::getRecord($table, $recordId);
// find the right preview page id
$previewPageId = 0;
if (isset($previewConfiguration['previewPageId'])) {
$previewPageId = $previewConfiguration['previewPageId'];
}
// if no preview page was configured
if (!$previewPageId) {
$rootPageData = NULL;
$rootLine = BackendUtility::BEgetRootLine($currentPageId);
$currentPage = reset($rootLine);
if ((int)$currentPage['doktype'] === PageRepository::DOKTYPE_DEFAULT) {
// try the current page
$previewPageId = $currentPageId;
} else {
// or search for the root page
foreach ($rootLine as $page) {
if ($page['is_siteroot']) {
$rootPageData = $page;
break;
}
}
$previewPageId = isset($rootPageData)
? (int)$rootPageData['uid']
: $currentPageId;
}
}
$linkParameters = [
'no_cache' => 1,
];
// language handling
$languageField = isset($GLOBALS['TCA'][$table]['ctrl']['languageField'])
? $GLOBALS['TCA'][$table]['ctrl']['languageField']
: '';
if ($languageField && !empty($recordArray[$languageField])) {
$l18nPointer = isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])
? $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
: '';
if (
$l18nPointer && !empty($recordArray[$l18nPointer])
&& isset($previewConfiguration['useDefaultLanguageRecord'])
&& !$previewConfiguration['useDefaultLanguageRecord']
) {
// use parent record
$recordId = $recordArray[$l18nPointer];
}
$linkParameters['L'] = $recordArray[$languageField];
}
// map record data to GET parameters
if (isset($previewConfiguration['fieldToParameterMap.'])) {
foreach ($previewConfiguration['fieldToParameterMap.'] as $field => $parameterName) {
$value = $recordArray[$field];
if ($field === 'uid') {
$value = $recordId;
}
$linkParameters[$parameterName] = $value;
}
}
// add/override parameters by configuration
if (isset($previewConfiguration['additionalGetParameters.'])) {
$linkParameters = array_replace($linkParameters, $previewConfiguration['additionalGetParameters.']);
}
$this->popViewId = $previewPageId;
$this->popViewId_addParams = GeneralUtility::implodeArrayForUrl('', $linkParameters, '', FALSE, TRUE);
$previewPageRootline = BackendUtility::BEgetRootLine($this->popViewId);
return '
if (window.opener) {
'
. BackendUtility::viewOnClick($this->popViewId, '', $previewPageRootline, '', $this->viewUrl, $this->popViewId_addParams, FALSE)
. '
} else {
'
. BackendUtility::viewOnClick($this->popViewId, '', $previewPageRootline, '', $this->viewUrl, $this->popViewId_addParams)
. '
}';
}
/**
* Main module operation
*
......
......@@ -349,6 +349,7 @@ class BackendUtility {
'uid' => $val['uid'],
'pid' => $val['pid'],
'title' => $val['title'],
'doktype' => $val['doktype'],
'TSconfig' => $val['TSconfig'],
'is_siteroot' => $val['is_siteroot'],
'storage_pid' => $val['storage_pid'],
......@@ -383,7 +384,7 @@ class BackendUtility {
$row = $getPageForRootline_cache[$ident];
} else {
$db = static::getDatabaseConnection();
$res = $db->exec_SELECTquery('pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_stage,backend_layout_next_level', 'pages', 'uid=' . (int)$uid . ' ' . self::deleteClause('pages') . ' ' . $clause);
$res = $db->exec_SELECTquery('pid,uid,title,doktype,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_stage,backend_layout_next_level', 'pages', 'uid=' . (int)$uid . ' ' . self::deleteClause('pages') . ' ' . $clause);
$row = $db->sql_fetch_assoc($res);
if ($row) {
$newLocation = FALSE;
......
========================================================
Feature: #66370 - Add flexible Preview URL configuration
========================================================
Description
===========
It is now possible to configure the preview link generated for the save+view button in Backend.
This allows to have different preview URLs depending on the record type.
Common usecase is to have previews for blog or news records, but this feature now allows you to
define a different preview page for content elements as well, which might be handy if those are stored
in a sysfolder.
Impact
======
New page TSconfig is introduced. The options are:
.. code-block:: typoscript
TCEMAIN.preview {
<table name> {
previewPageId = 123
useDefaultLanguageRecord = 0
fieldToParameterMap {
uid = tx_myext_pi1[showUid]
}
additionalGetParameters {
tx_myext_pi1[special] = HELLO
}
}
}
The ``previewPageId`` is the uid of the page to use for preview. If this setting is omitted the current page will be used.
If the current page is not a normal page, the root page will be chosen.
The ``useDefaultLanguageRecord`` defaults to ``1`` and ensures that translated records will use the uid of the default record
for the preview link. You may disabled this, if your extension can deal with the uid of translated records.
The ``fieldToParameterMap`` is a mapping which allows you to select fields of the record to be included as GET-parameters in
the preview link. The key specifies the field name and the value specifies the GET-parameter name.
Finally ``additionalGetParameters`` allow you to add arbitrary GET-parameters and even to override others.
Predefined GET-parameters
^^^^^^^^^^^^^^^^^^^^^^^^^
The Core automatically sets the ``no_cache`` and the ``L`` parameter. The language matches the language of the current record.
You may override each parameter by using the ``additionalGetParameters`` configuration option.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment