Typo3 disable drag and drop in page tree - drag-and-drop

Working with typo3 v 10.4, I have the requirement of some back-end user groups not to be allowed to move pages around. I was able to hide the arrow-actions shown in the page list view using the RecordListHookInterface. But drag and drop in the page tree still allows moving pages. Is there any TypoScript setting I can use to disable drag 'n' drop functionality of the page tree?

Unfortunately, there is no TypoScript configuration for this. But this can be done extending the "TreeController" from core with the "XClass" method:
<?php
namespace My\Namespace\XClass;
use TYPO3\CMS\Backend\Controller\Page\TreeController;
class XPageTreeController extends TreeController {
protected function isDragMoveAllowed(): bool {
if (!parent::isDragMoveAllowed()) {
return false;
}
$beUser = $this->getBackendUser();
return $beUser->isAdmin() || $beUser->isMemberOfGroup(123)
|| $beUser->isMemberOfGroup(234);
}
}
XClasses must be registered in the ext_localconf.php like so:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][TYPO3\CMS\Backend\Controller\Page\TreeController::class] = [
'className' => My\Namespace\XClass\XPageTreeController::class
];
Note that extending core classes has some disadvantages. For example, when switching to a newer Typo3 version, functionality might silently fail.

Related

Visual Studio Code: How to add checkbox in view container

I've been searching non-stop for this on the documentation but haven't been able to find any sort of information. I would like to know how to add checkboxes in my custom view container, similar to the breakpoints' checkboxes.
You can simulate the checkbox by playing with the icon, create a new TreeItem with a different icon when clicked.
Somehow they have knowledge on where on the TreeItem you click.
Looking with the dev tools, it is an <input type="checkbox"/>.
This means that you can do more with TreeItems than the docs explain.
Looking at the source code the BreakpointView is not implemented with a TreeItemProvider, it extends the ViewPane class and uses some kind of templates to render an item. Beside a checkbox it is also possible to have a combobox (SelectBox class).
I have added a feature request (101175) to extend the vscode API so extension developers can write Views with ViewItems that have additional UI-Elements like the Breakpoint view.
You can do this in the proposed api: treeItemCheckbox in Insiders v1.72 now and since it is a fairly simple new api I suspect it will be released with Stable 1.72.
You can play with this now, see using the proposed apis.
Instead of extending TreeItem you will extend TreeItem2 (which extends TreeItem) if you want to use checkboxes. Here is some sample code I put together:
export class TreeTab extends vscode.TreeItem2 {
...
if (tab.isActive) {
this.iconPath = new vscode.ThemeIcon("arrow-small-right", new vscode.ThemeColor("tab.unfocusedActiveBackground"));
this.checkboxState = vscode.TreeItemCheckboxState.Checked;
// this.checkboxState = {state: vscode.TreeItemCheckboxState.Checked, tooltip: "my nifty checkbox tooltip"};
}
...
and elsewhere in your code if you want to detect when that checkbox is clicked/unclicked:
// use your TreeView variable instead of 'tabView'
// from this.tabView = vscode.window.createTreeView(...);
const checkBoxListener = this.tabView.onDidChangeCheckboxState(async event => {
// event = {item: Array(n)}, which TreeItem's checkbox was clicked and its state after clicking:0/1 = on/off
console.log(event);
});

TYPO3 - hook / signal after page rendered

Is there any hook/signal or anything else so that I can modify final HTML code of frontend page rendered by TYPO3?
My use case is:
I want to apply some regex and logging for links that are displayed across whole website - no matter if the link is rendered via tt_content bodytext (typolink or hardcoded) or by frontend plugin or comes via typoscript or possibly any other way.
The PAGE object in TypoScript has stdWrap, so you can use userFunc there.
page = PAGE
page {
...
stdWrap.userFunc = Your\NameSpace\YourClass->doStuff
}
If you prefer to use real hooks instead of stdWrap you can look at the function generatePage_postProcessing which has three hooks. In the CoreApi Documentation you can find the way how to use hooks.
In your ext_localconf.php you can define your hook usage. As example:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] = My\NameSpace\Hooks\PageGenerateHooks::class . '->contentPostProcAll'
Now in your hook class you can modify the content:
<?php
namespace My\Namespace\Hooks;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
class PageGenerateHooks
{
/*
* \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $pObj
*/
public function contentPostProcAll(TypoScriptFrontendController $pObj)
{
$pObj->content = preg_replace('#mySearch#i','myTerm', $pObj->content;
}
}

No default link classes in typo3 8 anymore?

In V7 all internal/external/download links got an additional class by default, like 'internal-link' or 'download'.
Looks like in V8 with the new CKEditor this feature is gone.
Is there a way to reimplement it via typoScript or some kind of yaml RTE config?
An automatic solution, not the solution where the user have to pick a custom style, thats our current workaround.
If these classes should be applied automatically to specific link types without enabling the editors to change those classes, you should go for TypoScript parseFunc:
https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Parsefunc.html?highlight=parsefunc
Especially makeLinks, tags and typolink should be useful here:
https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Makelinks.html#makelinks
https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Tags.html#tags
https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Typolink.html#atagparams
For example you would assign a specific class to an external http link automatically created by makelink like this:
parseFunc {
makelinks = 1
makelinks {
http {
keep = path
extTarget = _blank
ATagParams = class="external-link"
}
}
}

Typo3 Extension PHP View

Using the infos in this link:
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/8-Fluid/9-using-php-based-views.html
I try to create an action to output a JSON.
I have a normal controller with the list action:
public function listAction()
{
$storelocators = $this->storelocatorRepository->findAll();
$this->view->assign('storelocators', $storelocators);
}
And in ext/my_storelocator/Classes/View/Storelocator I have a class List.php:
<?
class Tx_MyStorelocator_View_Storelocator_List extends Tx_Extbase_MVC_View_AbstractView {
public function render() {
return 'Hello World';
}
}
All I get is:
Sorry, the requested view was not found.
The technical reason is: No template was found. View could not be resolved for action "list" in class "My\MyStorelocator\Controller\StorelocatorController".
So I guess there is something wrong with the paths. Or where is the Problem?
Edit: Extensioninfos
Vendor: My
key: my_storelocator
controller: NOT SURE (I created it with the extension_builder so I guess my controllers name is Storelocator)
action: list
From my understanding a classname like Tx_MyStorelocator_View_Storelocator_List should be correct. But its not working
You will need to create an empty file for the HTML view for your controller, e.g. Resources/Private/Template/Storelocator/List.html, even if you do not plan to use the HTML view or if you just return the content yourself (which is perfectly fine).
The reason for this is simply technical limitation.
First of all, TYPO3 now has a built-in JSON view, described thoroughly here: https://usetypo3.com/json-view.html. It lets you easily define which properties you'd like to render.
The error message means that your Controller is still pointing to the TemplateView - because thats the error the TemplateView throws if it can't find the defined template file.
You can specify which view to use to render within your controller. You can either set a default view via the $defaultViewObjectName property, like so:
/**
* #var string
*/
protected $defaultViewObjectName = '\TYPO3\CMS\Fluid\View\TemplateView';
You can also set it from within the Controller inside initialization actions like so:
public function initializeExportPDFAction(){
$this->defaultViewObjectName = 'Vendor\Extension\View\FileTransferView';
}
(I have, however, not yet found a way to define the template from within actions, any tips in the comments would be appreciated)
Your path syntax is probably out of date. Instead of writing a render() function in Classes/View/Storelocator/List.php, try writing a listAction() function in a Classes/Controller/StorelocatorController.php file. Extension Builder should have created this file for you, if you made an aggregate model with the usual "list, create, edit ..." and such actions.
Review A journey through the Blog Example and the following chapter, Creating a first extension, for tips.
Keep in mind that there is a mismatch between the documentation and the Extension Builder generated PHP code files. Developing TYPO3 Extensions with Extbase and Fluid has some parts up to date, and other parts still using old syntax.

Adding a form field that is not in the schema to Doctrine form Symfony 1.4

I have an image upload form and at the bottom, I'd like to have a checkbox that the user must check before submitting the form, certifying that they have the right to distribute the photo. I've tried adding it as a Widget in the Form class, but it is not displaying. What is the best way to accomplish this?
For validation, you can add this to your form class to allow fields outside the model:
$this->validatorSchema->setOption('allow_extra_fields', true);
$this->validatorSchema->setOption('filter_extra_fields', false); // true or false
Other than that, just adding the widget in the standard way should work fine.
Adding a new widget to your form should be the right way.
class ImageForm extends BaseImageForm
{
public function configure()
{
$this->widgetSchema['copyright'] = new sfWidgetFormInputCheckbox();
}
}
For conditional validation, check this cookbook page should still be valid.