Symfony : How to use widgets with i18n forms in backend (doctrine) - php

I can not manage to have both i18n and tinyMCE widgets on internationalised fields.
If i put both, i will have internationalised fields for all my objects' fields, but no tinyMCE for them. I will have as much tinyMCE fields as i declared, but thew will not correspond to any language, they will be at the beginning or at the end.
It worked perfectly before i internationalized the objects
Here is an example of code :
// config/doctrine/schema.yml
MyObject:
actAs:
I18n:
fields: [title, subtitle, intro, text]
columns:
title: {type: string(500)}
subtitle: {type: string(500)}
intro: {type: string(4000)}
text: {type: string(16000)}
// lib/form/doctrine/MyObject.class.php
public function configure()
{
$this->embedI18n(array('en', 'fr', 'es'));
$this->widgetSchema->setLabel('fr', 'Français');
$this->widgetSchema->setLabel('en', 'Anglais');
$this->widgetSchema->setLabel('es', 'Español');
$this->widgetSchema['intro'] = new sfWidgetFormTextareaTinyMCE(
array(
'width'=>600,
'height'=>100,
'config'=>'theme_advanced_disable: "anchor,image,cleanup,help"',
'theme' => sfConfig::get('app_tinymce_theme','simple'),
),
array(
'class' => 'tiny_mce'
)
);
$this->widgetSchema['text'] = new sfWidgetFormTextareaTinyMCE(
array(
'width'=>600,
'height'=>100,
'config'=>'theme_advanced_disable: "anchor,image,cleanup,help"',
'theme' => sfConfig::get('app_tinymce_theme','simple'),
),
array(
'class' => 'tiny_mce'
)
);
$js_path = sfConfig::get('sf_rich_text_js_dir') ? '/'.sfConfig::get('sf_rich_text_js_dir').'/tiny_mce.js' : '/sf/tinymce/js/tiny_mce.js';
sfContext::getInstance()->getResponse()->addJavascript($js_path);
}
So i guess when i use $this->widgetSchema['intro'], the "intro" name does not correspond to all the i18n "intro" fields. I tried both 'en_intro' and 'intro_en', but it doesn't do any magic.
So maybe you could help me ?

So i found how to do this and i thought it might interest somebody :
Instead of
$this->widgetSchema['intro'] = ...
Put
$this->widgetSchema['en']['intro'] = ...
with all the languages.

also you can use :
$this->widgetSchema->moveField('en',sfWidgetFormSchema::BEFORE,'intro');
move the i18n label and field to before intro field.

Related

Translate labels from yml to php file

I have a YAML file with a bunch of translations, like this:
wizard
admin
title: example
And I'm calling it on the PHP file like this:
public function getTypesChart(){
$charts = array(
array(
'title' => 'wizard.admin.title'
),
);
return $charts;
}
But the only output I get it's "wizard.admin.title" instead of "example".
You need to call the translator service, like this (assuming you are in a controller, or where you have your service container):
public function getTypesChart(){
$charts = array(
array(
'title' => $this->get('translator')->trans('wizard.admin.title')
),
);
return $charts;
}
Unless you put your translation key in something automatically translated (like form's field label), you need to explicitly ask translation to do the job.
Assuming your code is in some controller you can call:
$this->get("translator")->trans("wizard.admin.title");
There are multiple problems here. First and foremost is that your input is not valid YAML:
wizard
admin
title: example
Although you can have multiline unquoted scalars in YAML, as in:
x: wizard
admin
title
(which is the same as doing x: 'wizard admin title' or x: wizard admin title) such scalars cannot be used as keys for a mapping.
Being invalid, you'll have to correct your YAML to be:
wizard:
admin:
title: example
after correcting that, make sure you call the translater
public function getTypesChart(){
$charts = array(
array(
'title' => $this->get('translator')->trans('wizard.admin.title')
),
);
return $charts;
}

Symfony 3 dynamically add attributes to form fields based on translation messages

I want to implement custom helper messages (html data attribute) for every form element. Helper messages are defined in YAML lang file (messages.en.yml) and not all form elements have helper messages.
Problem is that I am not sure can it be done using Symfony FormType or Symfony Form events.
I was thinking to create Form event as a service and inject translator service and from there manipulate data and add helper classes but I didn't find any solid example how can it be done.
Other option I was thinking is to use Trait and inject translator service in trait and from there to start developing my code but it doesn't feel so right.
Can someone share their experience and clue how to resolve this particular problem?
Here is my setup
messages.en.yml
intro:
created: Intro created!
edited: Intro has been edited successfully!
deleted: Intro has been has been deleted!
index:
title: List of all intros
new:
title: New intro
show:
title: Details of intro
edit:
title: Edit intro
form:
title: Title
content: Content
isEnabled: Is active
tooltip:
title: Please enter title
My form type:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array(
'label_format' => 'admin.intro.form.%name%',
'attr' => [
'data-helper' => 'Please enter title'
]
)
)
->add('content', TextareaType::class, array(
'label_format' => 'admin.intro.form.%name%',
'required' => false,
'attr' => [
'class' => 'mceEditor'
]
)
)
->add('isEnabled', CheckboxType::class, array(
'label_format' => 'admin.intro.form.%name%',
'required' => false,
)
You can do so by registering the form as a service and injecting the YAML configuration into the form.
config.yml
message_config:
intro:
created: Intro created!
edited: Intro has been edited successfully!
deleted: Intro has been has been deleted!
index:
title: List of all intros
new:
title: New intro
show:
title: Details of intro
edit:
title: Edit intro
form:
title: Title
content: Content
isEnabled: Is active
tooltip:
title: Please enter title
services.yml
services:
app.form.type.my_form:
class: AppBundle\Form\Type\MyForm
arguments:
- '%message_config%'
tags:
- { name: form.type }
Now you can work with the array in your FormType.
<?php
namespace AppBundle\Form\Type;
class MyForm
{
protected $messages;
public function __construct(array $messages)
{
$this->messages = $messages;
}
}
If the YAML configuration is being used by a Translator service, you would inject the translator service instead.
Update: Symfony does this with the Translator component and Twig form themes see the below comment.

How to set required false in symfony validation (yml) file

I have user.yml file in my validation folder in symfony and I am using it to validate the data. eg:
\APIBundle\Entity\User:
properties:
startDate:
- NotBlank: { message: 'Start date cannot be blank.' }
- Date: { message: 'Enter the valid start date.' }
I wanted to validate "startDate" field if user have passed it which is working now. But if user is not passed the "startDate" then I wanted to skip this validation. i.e Wanted the this validation as optional .
How to achieve this ?
I tried to set required false as following:
\APIBundle\Entity\User:
properties:
startDate:
- Required: false
- NotBlank: { message: 'Start date cannot be blank.' }
- Date: { message: 'Enter the valid start date.' }
Which is not working symfony return the error
required just affects rendering see :
If true, an HTML5 required attribute will be rendered. The corresponding label will also render with a required class.
This is superficial and independent from validation. At best, if you
let Symfony guess your field type, then the value of this option will
be guessed from your validation information.
you should use empty_data in your form like so :
$builder->add('gender', ChoiceType::class, array(
'choices' => array(
'm' => 'Male',
'f' => 'Female'
),
'required' => false,
'placeholder' => 'Choose your gender',
'empty_data' => null
));
Your entity in this case should have the property nullable=true and of course like mentionned NotBlank shouldn't be used
Just remove NotBlank
\APIBundle\Entity\User:
properties:
startDate:
- Date: { message: 'Enter the valid start date.' }
NotBlank is equivalent of reqired.
Since you're using NotBlank, that field is always required. However, you only want to validate the field if it is actually set.
I think that you won't accomplish that with Symfony's built-in validation, but you could write your custom Validation Constraint that handles this case: http://symfony.com/doc/current/cookbook/validation/custom_constraint.html

SF 1.4 How to make a form with several checkboxes and a relation between 2 models

Good morning,
In Symfony 1.4, I have two models, as in the following example :
ModelA
id
text
.
ModelB
id
name
modele_a_id
I want to create a form with checkboxes for each ModeleB entries, and a textarea for the text of ModeleA, like that :
[] modele_b_entry_name_1
[] modele_b_entry_name_2
[] modele_b_entry_name_3
text
[_______________________________]
I'm not sure of how to do that.
For the moment I have modified the ModeleAForm which was generated.
Here is the Form code :
$a_id = $this->getObject()->getId();
$query = Doctrine_Query::create()
->from('ModeleB m')
->where('m.modele_a_id = ?', $a_id);
$all_modele_b_entries = $query->execute();
$this->widgetSchema['all_modele_b_entries'] = new sfWidgetFormSelectCheckbox(array('choices' => $all_modele_b_entries));
And the template is very simple, it just shows the form.
I'm getting what I want, except that the labels of the checkboxes are the id of modele_b.
I'm wondering if I should use sfWidgetFormInputCheckbox instead of sfWidgetFormSelectCheckbox and then loop on it.
What do you think of this ? What is the best way to do it for you ?
Thank you in advance for your advices.
Edit :
Trying with the suggestion :
$this->widgetSchema['all_modele_b_entries'] = new sfWidgetFormDoctrineChoice(array(
'model' => 'ModeleB',
'expanded' => true,
'multiple' => true,
'query' => $query ));
I would use sfWidgetFormDoctrineChoice:
$this->widgetSchema['all_modele_b_entries'] = new sfWidgetFormDoctrineChoice(array(
'model' => 'ModelB'
'query' => $query
));
When the widget is rendered it uses the __toString() method of the ModelB class so make sure it's implemented and that it returns what you want. Have a look also on the different option of the choice widget as you can configure a thing or two :)

How to change text label in symfony 1.4

In my symfony 1.4 project I want to change label of form text. I can do that by following code:
$this->setWidget('first_name', new sfWidgetFormInputText(array('label' => 'First Name')));
But I can't do that if I add 'label' in the following code, as probably sfValidatorString doesn't accept 'label'.
$this->setValidator('banner_id', new sfValidatorString(array('min_length' => 9)));
How can I solve this?
Try:
$this->widgetSchema['feildname']->setLabel('Label Text');
You can also change all your fields label by using
$this->widgetSchema->setLabels(array(
"widget_name_first" => "my widget label",
"widget_name_second" => "my widget label",
));
Try this one:
$this->getWidgetSchema()->setLabel('fieldName', 'Custom label');
Or:
$this->getWidget('fieldName')->setOption('label', 'Custom label');
You can also configure your labels from the generator.yml file.
For Example:
config:
actions: ~
fields:
date:
label: Date of birth
date_format: dd/MM/yy
address:
label: Work address

Categories