In DjangoCMS Can I have an HTMLField which has use of the cmsplugins? - django-cms

I'm buidling a site with DjangoCMS 3.1, using a mix of traditional Django Models with fields and DjangoCMS placeholders. This is fine in principal, but it doesn't really allow for a clean workflow for the site administrators as they have to edit half of a model in the more traditional admin interface, and then the placeholder via the front-end editor interface. As I don't really need the full front-end-editing interface to simplify things such I wanted to convert all of the fields defined as PlaceHolderField's into HTMLFields.
Having done this I am having problems accessing the CMSplugins from within CKEditor in the admin interface; the appropriate button shows up in CKEditor, but the drop down menu is empty:
This is my (simplified) model description:
class Project(models.Model):
start_date = models.DateField('Start Date', blank=True, null=True)
end_date = models.DateField('End Date', blank=True, null=True)
subtitle = models.CharField('Sub Title', max_length=512, blank=True, null=True)
contents = HTMLField('Contents')
Admin declaration:
class ProjectAdmin(FrontendEditableAdminMixin, reversion.VersionAdmin):
fieldsets = [
(None,
{'fields':
[
'title',
'type',
'start_date',
'end_date',
'subtitle',
'summary',
'contents',
]
}
),
('Meta Information',{
'classes': ('collapse',),
'fields':
[
'slug',
'legacy_id',
'created_date',
'modified_date',
],
}
)
]
frontend_editable_fields = (
'title',
'start_date',
'end_date',
'lead_image',
'subtitle',
'summary',
'contents'
)
Settings.py
CKEDITOR_SETTINGS = {
'language': '{{ language }}',
'toolbar_HTMLField': [
['Undo', 'Redo'],
['cmsplugins', '-', 'ShowBlocks'],
['Format', 'Styles'],
['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'],
['Maximize', ''],
'/',
['Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
['NumberedList', 'BulletedList', 'Blockquote', '-', 'Table'],
['Source']
],
'skin': 'moono',
}
I've tried declaring CMS_PLACEHOLDER_CONF inside of settings.py just in case:
CMS_PLACEHOLDER_CONF = {
'contents': {
'name' : 'Contents',
'plugins': ['TextPlugin', 'PicturePlugin', 'VideoPlugin', 'LinkPlugin'],
'text_only_plugins': ['LinkPlugin'],
'default_plugins':[
{
'plugin_type':'TextPlugin',
'values':{
'body':'<p></p>'
},
},
],
'child_classes': {
'TextPlugin': ['PicturePlugin', 'VideoPlugin', 'LinkPlugin'],
},
'parent_classes': {
'LinkPlugin': ['TextPlugin'],
},
}
}
Looking at the source that shouldn't affect it, only the definition of PlaceHolderFields. I've tried adding the PlaceholderAdminMixin to the admin class declaration as well.
I'm accessing the admin interface via modal dialogs launched via {% render_model project 'contents' %} so to some extent it is within the DjangoCMS context, but it's not using the full front end interface.
Is this even possible? That is can I access the DjangoCMS Plugins via CKEditor in the Django Admin interface, without reverting to using the PlaceholderField/ full Front end editing interface?

The supported way to do this is to use PlaceholderField (where you're trying to use HTMLField.
See http://docs.django-cms.org/en/develop/how_to/placeholders.html for more information.

Related

drupal 8 conditional field with link field

I am trying to work a conditional field based on the value input in a link field. For example, based on an external or internal link. I couldn't find a proper example, but the ones I found, I have tried this, no luck. Any idea how this can work -
$form['field_test_1']['#states'] = [
'visible' => [
':input[name="field_test_2[widget][0][uri][#default_value]"]' => 'https://www.google.com',
],
];
ok so I have worked it out, it should be like this -
$form['field_test_1']['#states'] = [
'visible' => [
':input[name="field_test_2[0][uri]"]' => [ 'value' => 'https://www.google.com' ],
],
];

Using the link wizard in a Typo3 backend module

I'm pulling my hair out over this.
I created a T3-Extension - backend module - using Extension Builder.
Now I want to provide the user with the link-wizard, so she/he can select an internal link from the T3-Tree.
I created a TCA-Entry for this:
'url' => [
'label' => 'Link',
'exclude' => 1,
'config' => [
'type' => 'input',
'size' => '50',
'max' => '256',
'eval' => 'trim',
'renderType' => 'inputLink',
'fieldControl' => [
'linkPopup' => [
'options' => [
'blinkLinkOptions' => 'mail,page,spec,url,folder',
'blindLinkFields' => 'class,params,target,title',
'allowedExtensions' => 'html,php'
],
],
],
'fieldWizard' => [
'localizationStateSelector' => [
'disabled' => false,
]
]
],
],
In the fluid-template (the view) I'm simply using this:
<f:form.textfield property="url" />
According to the docs, the TCA-config should add a button after the input field.
But that's not the case.
Am I doing something wrong or is this simply not working?
I also tried using flux in my templates (which has a link-browser view helper), but when I use <flux:...> nothing is rendered in the form.
Using Typo3 8.7
I finally found a solution for this.
This is in the controller of my extension
$options = [
'renderType' => 'inputLink',
'tableName' => 'myTable',
'fieldName' => 'url',
'databaseRow' => [
'uid' => $myModel->getUid(),
'pid' => 0
],
'parameterArray' => [
'fieldConf' => [
'label' => 'URL',
'config' => [
'eval' => 'trim',
'size' => 1024,
],
],
'itemFormElValue' => $myModel->getUrl(),
'itemFormElName' => 'data[myTable][editform][url]',
'itemFormElID' => 'data[mytable][editform][url]',
'field' => 'url',
'fieldChangeFunc' => [
'TBE_EDITOR_fieldChanged' => "TBE_EDITOR.fieldChanged('mytable','editform','url','data[mytable][editform][url]');"
],
]
];
$nodeFactory = new NodeFactory();
$linkField = new InputLinkElement($nodeFactory, $options);
$urlField = $linkField->render();
$this->view->assign('renderedUrlField', $urlField['html']);
Where «mytable» is the table the controller uses, «editform» is the form-name and «url» is the database-field that's been used to store the value.
For some reason, you need to name your form «editform», since a sysext-JS refers to that.
You need to add this to your controller to make this working:
use TYPO3\CMS\Backend\Form\Element\InputLinkElement;
use TYPO3\CMS\Backend\Form\NodeFactory;
And in the fluid-template, you have to use:
<f:format.raw>{renderedUrlField}</f:format.raw>
because it returns html-code.
Now initialize the FormEngine
Add this to your Default.html in the section <f:be.container...>:
includeJsFiles="{
1:'/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js',
3:'/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js',
4:'/typo3/sysext/backend/Resources/Public/JavaScript/backend.js'
}"
includeRequireJsModules="{
0:'{f:uri.resource(path:\'JavaScript/ckeditor/ckeditor.js\')}',
4:'TYPO3/CMS/Backend/FormEngine',
5:'TYPO3/CMS/Backend/FormEngineValidation',
7:'TYPO3/CMS/Backend/ContextMenu',
8:'TYPO3/CMS/Backend/FormEngineReview',
9:'{f:uri.resource(path:\'JavaScript/main.js\')}'
}"
I included ckeditor as well here.
And now, you need to initialize the FormEngine. I did this in main.js:
TYPO3.settings.FormEngine = {"formName":"editform"};
define(['jquery', 'TYPO3/CMS/Backend/FormEngine'], function($){
'use strict';
$(function(){
TYPO3.FormEngine.initialize();
});
});
The first line is important, otherwise, the JS will throw an error.
Hope this helps somebody.
My answer will not help if you want to create the link wizard with Fluid, but it answers a part of the question and adds additional information.
Setting the link wizard for a field via TCA will not magically make the link wizard appear in Fluid. It will however make the link wizard available if you directly edit a record in the backend (with the list view).
Example: you create a table tx_myext_domain_model_mydata with the field url, set the TCA to use the link wizard. Then use the list view to create and edit records.
You can see examples of records with a link wizard in the extension styleguide. It is good to use this extension, because it is a semi-official demo of various backend functionality. The extension "news" for example also makes use of editing news records (tx_news_domain_model_news.internalurl).
Install "styleguide" extension, create sample records, select "elements basic" and look at for example "input_29 link" (for TYPO3 8). See source code and TCA Reference renderType inputLink.

CKEditor Plugin 'save' (egeloen / ivoryckeditor) in Symfony 3 not showing the save button

I successfully installed and integrated the CKEditor (4.7.3) in my Symfony 3.3.10 project using the ckeditor-bundle from egeloen (ivoryckeditor).
I am now trying to get the "Save" Plugin to work.
I copied the plugin folder into my web-folder.
This is my test configuration in config.yml
ivory_ck_editor:
inline: true
autoload: false
async: false
configs:
ckeditor_config_1:
toolbar: [ [ "Save", "Cut", "Copy" ] ]
extraPlugins: "save"
plugins:
save:
path: "/bundles/ivoryckeditor/plugins/save/"
filename: "plugin.js"
Thats how I create the ckeditor form to pass to twig for rendering:
$ckeditForm = $this->get('form.factory')->createNamedBuilder('ckedit_form', CKEditorType::class, $content, array(
'label' => false,
'config' => array(
'config_name' => 'ckeditor_config_1',
'inline' => true,
),
))->getForm();
Unfortunately the "Save" Button is not showing up.
Any ideas about the cause of the button not showing up are very welcome.
OK - The save plugin is just not working in inline mode. Could be documented somewhere - couldn't find any hint to that...

CollectionType element validation error message location

I'm working with a CollectionType field.
$builder->add('urls', CollectionType::class, [
'allow_add'=>true,
'entry_type'=>UrlType::class,
'constraints'=>new All([
'constraints'=>[
new Url()
]
])
]);
It works as I expected. Except the message if field has an invalid content.
Validator works but error message is a bit confusing: Field.0 - This value is not a valid URL address. What do I need is to simply make a parent field invalid - bind error to urls field.
Of course, I could create a form listener and perform validation there. But - IMO - it's a workaround.
How to achieve this in a "pure" way? I've tried playing error_bubbling in many ways but it's still not something satisfying.
try, so you for force validation on each UrlType and have it bubble the error upwards to the parent form, the CollectionType
$builder->add('urls', CollectionType::class, [
'allow_add'=>true,
'entry_type'=>UrlType::class,
'constraints'=>new All([
'constraints'=>[
new Url()
]
]),
'cascade_validation' => true,
'entry_options' => array('error_bubbling' => true)
]);
I think that you need to set error_mapping:
$builder->add('urls', CollectionType::class, [
'allow_add'=>true,
'entry_type'=>UrlType::class,
'constraints'=>new All([
'constraints'=>[
new Url()
]
]),
'cascade_validation' => true,
'error_bubbling' => false,
'error_mapping' => [
'your_parent_form_alias.field_name' => 'field_name',
]
]);
and then in UrlValidator when you are building violation add atPath like that:
if (empty($form['field_name'])) {
$this->context->buildViolation($constraint->getMessageName())
->atPath('your_parent_form_alias.field_name')
->addViolation();
}
I'm not sure does error_mapping and error_bubbling shouldn't be mapped first for Url() and later one more time for All().
I hope it will help you

Sonata: translations with parameters

I can't seem to be able to use translations with variables in Sonata as I do in normal symfony controllers.
In my controller:
$this->setSonataFlashSuccess(
$this->get('translator')->trans('flash_create_success', [
'%link%' => 'abcd',
'%id%' => '1234'
])
);
My template:
{{ message|trans|raw }}
My translations file 'SonataAdminBundle.yml':
flash_create_success: Created with success: #%id%
The rendered HTML:
Created with success: #%id%
So the translation worked but not the replacement of the expressions Link and Id. Is there something especial about translations in Sonata? Everything works fine in the rest of the app.
When you write a translations file, you have to name it differently than the original (e.g. admin_messages.[langage].yml), otherwise the original SonataAdminBundle.[locale].yml will be used.
So, you should create a file in your bundle like :
# YourBundle/Resources/translations/admin_messages.en.yml`
flash_create_success: Created with success: #%id%
And specify it in your controller :
$this->get('translator')->trans(
'flash_create_success',
array(
'%link%' => 'abcd',
'%id%' => '1234'
),
'admin_messages', // By default looks for a "messages.[_locale].yml"
);
Note that you don't need to translate the message one more time in your template, as it is already translated in your controller.

Resources