Initial commit
This commit is contained in:
108
typo3conf/ext/vhs/Classes/ViewHelpers/TryViewHelper.php
Normal file
108
typo3conf/ext/vhs/Classes/ViewHelpers/TryViewHelper.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
/**
|
||||
* ### Try ViewHelper
|
||||
*
|
||||
* Attempts to render child content. If an Exception is encountered
|
||||
* while rendering, instead the `f:else` child node is rendered,
|
||||
* if it is present. If `f:else` is not used, no output is returned.
|
||||
*
|
||||
* Can be used to perform complex translations of Exception messages
|
||||
* which can occur. Can naturally also be used to provide a great
|
||||
* deal of additional information about every possible Exception-type
|
||||
* error which Fluid can encounter (and there are many).
|
||||
*
|
||||
* Note that this is a Condition ViewHelper which means you can use
|
||||
* the `f:then` child node but it differs from regular Conditions by
|
||||
* also allowing the template developer to skip the `f:then` child
|
||||
* node and use the direct tag content as the "TRUE" condition and
|
||||
* add an `f:else` which is only rendered in case of an Exception
|
||||
* during rendering.
|
||||
*
|
||||
* Also note that you can use the `then` and `else` attributes; the
|
||||
* `then` attribute is what is attempted rendered and the `else`
|
||||
* attribute is what is rendered if retrieving the `then` attribute's
|
||||
* value fails. Which clearly only makes sense if for example complex
|
||||
* inline ViewHelpers are used in the attributes.
|
||||
*
|
||||
* ### Example usage
|
||||
*
|
||||
* #### Please note that this is a theoretical example!
|
||||
*
|
||||
* The example is theoretical in one major aspect: v:format.json.decode
|
||||
* throws an Exception which Fluid displays as a string always - abstract
|
||||
* from this and imagine that a plain Exception happens on errors.
|
||||
*
|
||||
* <v:try>
|
||||
* <!-- assume that the variable {badJson} contains the string "DontDecodeMe"
|
||||
* which if course is invalid JSON and cannot be decoded. The default
|
||||
* behavior is to simply output a simple "cannot decode" string. -->
|
||||
* <v:variable.set name="decodedBadJson" value="{badJson -> v:format.json.decode()}" />
|
||||
* Displayed only if the JSON decode worked. Much more code and many more
|
||||
* ViewHelpers can go here. Now, imagine that this block spans so much code
|
||||
* that potentially there could come an Exception from many additional places
|
||||
* (for example from Widgets) and you cannot be sure where the Exception comes
|
||||
* from but still want to tell the user what exactly went wrong and provide
|
||||
* an error code which makes sense to send to developers if problems persist:
|
||||
* <f:else>
|
||||
* <h4>
|
||||
* Error in "{exception.trace.0.class
|
||||
* -> v:iterator.explode(glue: '_')
|
||||
* -> v:iterator.pop()
|
||||
* -> v:format.replace(substring: 'ViewHelper', replacement: ''}"
|
||||
* <small>{exception.code}</small>
|
||||
* <!-- Output example: "Error in Decode <small>1358440054</small>" -->
|
||||
* </h4>
|
||||
* <p>
|
||||
* {exception.message}
|
||||
* <!-- Output example: "The provided argument is invalid JSON" -->
|
||||
* </p>
|
||||
* <pre>
|
||||
* Value: ``{exception.trace.0.args.0}´´
|
||||
* <!-- Output example: "Value: ``DontDecodeMe´´" which is quite nice
|
||||
* for developers to know as part of a bug report from users. -->
|
||||
* </pre>
|
||||
* </f:else>
|
||||
* </v:try>
|
||||
* ...or if you want a shorter version...
|
||||
* <!-- Tries to encode an object, if it fails, falls back by returning a proper JSON
|
||||
* value, thus preventing breakage by the JSON consumer whatever it may be. -->
|
||||
* {v:try(then: '{badObject -> v:format.json.encode()}', else: '{"validJson": "validValue"')}
|
||||
* <!-- Note: be VERY careful about the inline JSON syntax! It's very close to Fluids. Always
|
||||
* double quote your object variables' names, that prevents almost all issues! -->
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers
|
||||
*/
|
||||
class TryViewHelper extends AbstractConditionViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
try {
|
||||
$content = $this->renderThenChild();
|
||||
if (TRUE === empty($content)) {
|
||||
$content = $this->renderChildren();
|
||||
}
|
||||
} catch (\Exception $error) {
|
||||
$content = $this->renderChildrenWithVariables(array('exception' => $error));
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user