Typo3 Neos: Filefield in Custom Content Type - neoscms

I want to make a custom content type with the possibility to edit a download file. In my NodeTypes.yaml I have:
'Vendor.Prefix:MyContentType':
superTypes: ['TYPO3.Neos:Content']
ui:
label: My Content Type
icon: 'icon-file-text'
inspector:
groups:
'props':
label: Properties
properties:
'title':
type: string
defaultValue: 'Example Title'
ui:
label: 'Title'
inlineEditable: TRUE
Now - how do I create a file upload field? I only found working examples for image fields:
'chapterImage':
type: 'TYPO3\Media\Domain\Model\ImageVariant'
ui:
label: 'Chapter image'
reloadIfChanged: TRUE
inspector:
group: 'document'
In the same folder, there are classes for file uploads, but this doesn't work:
'grundriss':
type: 'TYPO3\Media\Domain\Model\Document'
ui:
label: 'Grundriss'
editor: 'TYPO3.Neos/Inspector/Editors/FileUpload'
inspector:
group: 'props'
Neither with nor without the 'editor' line. It leads to the JavaScript error:
Uncaught TypeError: Cannot read property 'editor' of undefined
Uncaught Error: You cannot modify child views while in the inBuffer state
And to an empty property inspector.
Has anyone a tip for me?

True enough this was not working. We have merged a way to link to all kinds of asset files in the current 1.1 beta release. Maybe check that.

Related

How to fix validation of optional fields using Switch component (material-ui) with Formik

I'm trying to fix a bug in a form. The form is built with Formik and a custom react component called GenericForm which basically handles the validation and maps an array of objects into the form sub-component renders.
const advancedFields = [
{
label: "Power Factor",
id: "powerFactor",
type: "number",
value: "",
isRequired: useAdvancedOptions,
},
{
label: "Efficiency",
id: "efficiency",
type: "number",
value: "",
isRequired: useAdvancedOptions,
},
];
The variable useAdvancedOptions is part of the component state, updated with the new react hook and a Switch component.
<FormControlLabel control={ <Switch onChange={
() => setUseAdvancedOptions(!useAdvancedOptions)
}color={"primary"}/>}label="Advanced Options"/>
So the bug... when I toggle advancedOptions on and off with the switch, if the field has been touched, the submit button won't validate if there are no values inside the two advanced fields, even when the fields have been excluded from the form.
When I use Chrome debugger and inspect the variable useAdvancedOptions inside the field objects, it appears that the boolean values for isRequired are updating as anticipated, so I'm not sure why the button is still trying to require the field.
Validation was broken, when it would read one of the values that existed in formic and filter it, the iteration that was taking the removed advanced option value would take null into the switch case and fail. I wrote a conditional to return before the switch statement if the iteration filter resulted in null.

CKeditor: How to build a custom plugin?

I am trying to create a custom plugin for CKeditor following this guide. I created the files as indicated (myplugin.png, myplugin.js, plugin.js) and added
CKEDITOR_CONFIGS = {
'default': {
'extraPlugins': ','.join( [ 'myplugin' ] ),
'allowedContent' : True,
}
}
to the settings.
This is the content of my plugin.js file:
CKEDITOR.plugins.add( 'myplugin', {
icons: 'myplugin',
init: function( editor ) {
// Plugin logic goes here...
editor.addCommand( 'myplugin', new CKEDITOR.dialogCommand( 'mypluginDialog' ) );
editor.ui.addButton( 'myplugin', {
label: 'My Plugin',
command: 'myplugin',
toolbar: 'insert'
});
}
});
Yet, the icon of the custom plugin still doesn't show. I can see in the browser's tools that the plugin.js file is retrieved. I made a test by removing the icon file and it didn't create any difference (no error message, no 404). I suppose then that the file is not even called or accessed. so the initialization does not even try to render the button.
Thank you for your help.
Finally, I found the answer to the problem. It comes from the way CKEditor displays the toolbars. In the guide, the custom plugin is added to the "insert" group of the toolbars. However, this one will not be visible until it is explicitely set to be displayed.
Adding the extra plugin to the default configuration is not enough, the toolbar setting has to be specified properly (if for some reason, your platform doesn't default to null). In my case, with django-ckeditor, I had to add
'toolbar': None,
to the CKEDITOR_CONFIGS.

How to define custom class, title, and target in Link Browser for content elements and the new rte_ckeditor?

Prerequisites
[x] Can you reproduce the problem on TYPO3 8.7 LTS - YES
[x] Did you [perform a cursory search] to see if your bug or enhancement is already reported? -YES
Description
How do I configure default link target, class, and title for the Link Browser in any element link (usually element titles and images) AND in rte_ckeditor in Typo3 8 LTS? I've spent several hours trying to configure it, but no success and no documentation out there. The fields are empty as you can see on the images below.
Steps to Reproduce the problem
Create any element that you can link the title or image.
Click to open the Link Browser
The options come empty for any type of link (Page, File, Folder, External URL, Email).
Expected behavior:
I want to define default classes, link targets and titles for each type of link if they are empty.
For example External URL, I want to automatically populate with target="_blank", class "external-link", title="Link to External Website", if the link wasn't configure previously. Basically for any new link I just want to have it auto populated with my custom values and not empty values.
This used to work for rtehtmlarea only on previous Typo3 versions, but not I'm not able to set this option system wide on Typo3 8 LTS and ckeditor.
The PageTS that used to work only for rtehtmlarea was something like this:
RTE {
classesAnchor {
externalLink {
class = external-link
type = url
titleText = Opens external link in new window
target = _blank
image =
}
externalLinkInNewWindow {
class = external-link-new-window
type = url
titleText = Opens external link in new window
target = _blank
image =
}
internalLink {
class = internal-link
type = page
titleText = Opens internal link in this window
target = _top
image =
}
internalLinkInNewWindow {
class = internal-link-new-window
type = page
titleText = Opens internal link in new window
target = _blank
image =
}
folder {
class = folder
type = folder
titleText =
target =
image =
}
download {
class = download
type = file
titleText = Initiates file download
target = _blank
image =
}
mail {
class = mail
type = mail
titleText = Email Address
image =
}
}
}
I would like this to work for the new rte_ckeditor as well for any element options that I can link using the Link Browser.
There is a bug in TYPO3 8.7.8 (only) - see: https://forge.typo3.org/issues/82865
[EDIT] the classesAnchor stuff works only in version 8.7.5 to 8.7.7 and will hopefully work again in 8.7.9
But the correct answer whould be (like Ghanshyam Bhava pointed out in his comment) to switch to YAML configuration.
https://typo3worx.eu/2017/02/configure-ckeditor-in-typo3/
# Load default processing options
imports:
- { resource: "EXT:rte_ckeditor/Configuration/RTE/Default.yaml" }
classesAnchor:
externalLink:
class: 'external-link'
type: 'url'
downloadLink:
class: 'download-link'
type: 'file'
mailLink:
class: 'mail-link'
type: 'mail'
buttons:
link:
properties:
class:
allowedClasses: 'external-link,download-link,mail-link'
Link Browsers for other fields outside RTE should be possible via TCA-Overrides.
Here is the solution,
RTE.default {
# This will provide only basic tool in the text RTE
preset = default
## Bootstrap CSS
contentCSS {
20 = fileadmin/Resources/Public/Bootstrap/css/bootstrap.css
}
classesAnchor {
url {
class = externalLink
type = url
titleText = Opens external link in new window
target = _blank
image =
}
page {
class = internalLink
type = page
titleText = Opens internal link in this window
target = _top
image =
}
file {
class = download
type = file
titleText = external file
target = _blank
image =
}
folder {
class = folder
type = folder
titleText = folder file
target = _blank
image =
}
mail {
class = mail
type = mail
titleText = Email Address
image =
}
}
buttons.link{
page.properties.class.default = internalLink
url.properties.class.default = externalLink
folder.properties.class.default = folder
file.properties.class.default = download
mail.properties.class.default = mail
properties.class.allowedClasses = internalLink,externalLink,folder,mail,download
}
}
Check out this, i have added default link title as well as its targer too. you can see the output of my backend:
So after days and days and days!!! of search, trials, and errors, I finally found a way to enable the auto populated parameter of a link according to their type outside rte_ckeditor or even outside rtehtmlarea. It's not exactly what I wanted but is almost there!
Adding this to my Page TSConfig solved part of the problem:
TCEMAIN.linkHandler {
# I don't want to load the folder link handler so I reset it.
folder >
# Leaving page type empty on purpose.
page {
}
file {
addParams = onclick="jumpToUrl('?act=file&linkAttributes[target]=_blank&linkAttributes[title]=Opens or downloads file in new window&linkAttributes[class]=download&linkAttributes[params]=');return false;"
}
url {
addParams = onclick="jumpToUrl('?act=url&linkAttributes[target]=_blank&linkAttributes[title]=Opens external link in new window&linkAttributes[class]=externalLink&linkAttributes[params]=');return false;"
}
mail {
addParams = onclick="jumpToUrl('?act=mail&linkAttributes[title]=Opens email manager to send an email&linkAttributes[class]=mail&linkAttributes[params]=');return false;"
}
}
I didn't configure anything for page because if it's populated and I click on File, External Url, Email, or any other custom link handler, the attributes are passed along from the Page link handler, which defeats the purpose of the pre-populated parameters for each link handler type.
The only remaining issue is if I click for example on External URL, the target will be "_blank", title will be "Opens external link in new window" and class will be "externalLink". So far so good. Then if you click to link a File or even to link an internal Page, those parameters that pre-loaded for External URL will be passed along, which I think it shouldn't happen. Since I'm trying to pre-populate each link type, why would I want to keep the attribute of a previous link type? This might be just a matter of opinion, but I would like to have the option for force pre-populated parameters for each link type. Maybe I'm just missing a small config to achieve this behavior.
I have tested this solution in TYPO3 9 with ckeditor in my yaml configuration file to load my own defaults. It works fine except the default settings don't work as expected. The titleText, is currently overwritten by the last title of the same type. e.g. for the type 'page' the title 'Opens internal link in new window' is loaded instead of 'Opens internal link in this window'.
buttons:
link:
relAttribute:
enabled: true
page:
properties:
class:
default: internal-link
url:
properties:
class:
default: external-link-new-window
folder:
properties:
class:
default: folder
file:
properties:
class:
default: download
mail:
properties:
class:
default: mail
properties:
class:
allowedClasses: 'internal-link,internal-link-new-window,download,external-link,external-link-new-window,mail'
#Classes config
classesAnchor:
internalLink:
class: 'internal-link'
type: 'page'
titleText: 'Opens internal link in this window'
internalLinkNewWindow:
class: 'internal-link-new-window'
type: 'page'
target: '_blank'
titleText: 'Opens internal link in new window'
download:
class: 'download'
type: 'file'
target: '_blank'
titleText: 'Download file'
externalLink:
class: 'external-link'
type: 'url'
titleText: 'Opens External link in this window'
externalLinkNewWindow:
class: 'external-link-new-window'
type: 'url'
target: '_blank'
titleText: 'Opens External link in new window'
linkMail:
class: 'mail'
type: 'mail'
titleText: 'Email Address'
To configure default classes in yaml you have to add the default classes like this in your .yaml file:
classesAnchor:
page:
class: 'link-page'
type: 'page'
target: '_top'
file:
class: 'link-file'
type: 'file'
target: '_blank'
titleText: 'Download'
url:
class: 'link-external'
type: 'url'
target: '_blank'
mail:
class: 'link-mail'
type: 'mail'
titleText: 'Send email'
buttons:
link:
properties:
class:
allowedClasses: 'link-page, link-file, link-external, link-mail'
page:
properties:
class:
default: 'link-page'
file:
properties:
class:
default: 'link-file'
url:
properties:
class:
default: 'link-external'
mail:
properties:
class:
default: 'link-mail'

Save/Cancel dialog buttons not showing in Magnolia dialog

I am trying to add a dialog to my app, and while I have no issues defining the form I want the way I want, the Save and Cancel buttons simply aren't showing up and I don't know why. I'm new to Magnolia and custom apps, so sure I'm missing something, but I've gone through the sections in the documentation I can find, but from everything I've seen, this should work.
detailFeatured:
subAppClass: info.magnolia.ui.contentapp.detail.DetailSubApp
class: info.magnolia.ui.contentapp.detail.DetailSubAppDescriptor
actions:
commit:
class: info.magnolia.ui.form.action.SaveFormActionDefinition
label: "Save"
cancel:
class: info.magnolia.ui.form.action.CancelFormActionDefinition
label: "Cancel"
editor:
wide: true
actions:
- name: commit
- name: cancel
form:
tabs:
- name: featured
label: "Featured Slideshows"
fields:
- name: ogLabel
label: ""
class: info.magnolia.ui.form.field.definition.StaticFieldDefinition
value: "<strong>Hero Slideshow</strong>"
- name: hero
class: info.magnolia.ui.form.field.definition.TextFieldDefinition
required: true
label: Slideshow URI
- name: ogLabel
label: ""
class: info.magnolia.ui.form.field.definition.StaticFieldDefinition
value: ""
- name: ogLabel
label: ""
class: info.magnolia.ui.form.field.definition.StaticFieldDefinition
value: "<strong>Slideshow Carousel</strong>"
- name: carousel
class: info.magnolia.ui.form.field.definition.MultiValueFieldDefinition
required: true
label: Slideshow URIs
field:
class: info.magnolia.ui.form.field.definition.TextFieldDefinition
label: URI
nodeType:
icon: icon-files
name: mgnl:featured
contentConnector:
workspace: featured
Looks alright. Few things to do when you run across something like that:
- Check in the file that you don't have some special invisible chars in the definition instead of just spaces.
- Also make sure you have magnolia.develop=true and observe messages in the log when saving definition file. Hopefully that will tell you something useful.
- and last, best of all, go and install Magnolia 5.5 (beta available at time of writing, final should be out as of Nov 15th 2016) and once installed, look at the app via new Definitions App. It should show you all the errors it found in your definition.

Angular 2, dynamic forms; updateValue() do not update checkbox form control

I'm building a angular 2 (2.0.0-rc.4) application with the new form API (2.0.2) and i've got a problem when i'm trying to update checkbox form controls with updateValue().
This is what i've done:
I've built a dynamic form with the new form API (based on the section in the cookbook: https://angular.io/docs/ts/latest/cookbook/dynamic-form.html). I've extended the form class to also handle checkboxes:
export class FormControlCheckbox extends FormBase <string> {
controlType: string;
options: { key: string, value: string, checked: boolean } [] = [];
checked: boolean = false;
constructor(options: {} = {}) {
super( options );
this.controlType = "checkbox";
this.options = options['options'] || [];
this.checked = this.options[0].checked;
}
}
This is what it looks like when it's created:
new FormControlCheckbox({
type: "checkbox",
label: 'A label',
name: "a-name",
value: "",
description: "a description",
options: [
{
label: 'A label',
name: "a-name",
checked: false
}
],
})
When the application are loaded the form controls are created and grouped together, everything works fine and the form get submitted as intended. I only had to do a workaround to make the checkbox update on change and the markup are as followed:
<input [formControlName]="control.key" [(ngModel)]="control.checked" [id]="control.key" [type]="control.controlType" [attr.checked]="control.checked ? true : null" [value] = "control.checked" (change)="control.checked = $event.target.checked">
I've also tried this markup (it also works fine):
<input [formControlName]="control.key" [(ngModel)]="control.checked" [id]="control.key" [type]="control.controlType" [attr.checked]="control.checked ? true : null" [value] = "control.checked" (change)="control.checked = check.checked" #check>
This is where my problem occurs
I'm adding a feature that updates the control values when the form just have been loaded (the user should be able to revisit the page and update previous values). The code below update all the control values.
for (var key in new_values) {
//the form control keys are the same as the key in the list of new_values
this.form.controls[key].updateValue(new_values[key]); //works for text, select and option
this.form.controls[key].updateValueAndValidity(); //not sure if needed?
this.form.controls[key].markAsDirty();
}
Text, option and select inputs gets updated but the checkboxes are unchanged. No errors or warnings. I've searched a lot for similar problems but have not found a similar problem or a solution.
Am I missing something obvious? Or have somebody had the same problem and want to share their solution?
Thanks!
Solved the problem by changing the values before creating the control-groups (before this it's possible to change the values (ex. x.value). It solved my problem but do not solve the fact that dynamically changes to checkbox form controls are not reflected in the DOM element.