How to retrieve localization string from nested array in Laravel 8 - laravel-blade

I started to prepare localization strings for my application based on Laravel 8.19, and I found that nested arrays are not working.
I copied auth.php from \resources\lang\en to \resources\lang\ru and added few strings in nested array
'login' => 'Войти',
'logout' => 'Выйти',
'password' => [
'definition' => 'пароль',
'forgot' => 'Забыли пароль?',
],
'remember' => 'Запомнить меня',
'failed' => 'Учетные данные не совпадают с нашими записями.',
'password' => 'Пароль неверный.',
'throttle' => 'Слишком много попыток входа. Пожалуйста попробуйте снова через :seconds секунд.',
Then in login page \resources\views\auth\login.blade.php I try to echo lang strings.
<div class="flex items-center justify-end mt-4">
#if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 hover:text-gray-900"
href="{{ route('password.request') }}">
{{ __('auth.password.forgot') }}
</a>
#endif
<x-button class="ml-3">
{{ __('auth.login') }}
</x-button>
</div>
But auth.password.definition and auth.password.forgot are not working. I see "auth.password.definition" on the page like I don't have this string defined in the auth.php file. What can be wrong?
I found in my old project on Laravel 5 that I used the trans() function to retrieve localization strings, and it also worked with nested arrays like above. Now trans() cannot help with that.

It seems that nested arrays notation for localization strings replaced with simple DOT delimiter in KEY name, because I tried like that and it works.
'password.forgot' => 'Забыли пароль?',

Related

Symfony 6: embedded form collection, add only new elements and omit existing elements

I have a FormType which contains an embedded collection of another FormType, all is working properly and done according to How to Embed a Collection of Forms.
My embedded FormType is an attachment list, which has title and file upload.
AttachmentType:
builder
->add('title', null, ['label' => 'Title', 'required' => true])
->add('attachmentFile', FileType::class, [
'label' => 'File',
'mapped' => false,
'required' => true,
'constraints' => [
new File([
'maxSize' => '1024k',
])
],
])
The problem is, when editing the parent object, I want to allow new attachments but I don't want to edit previous attachments, as it would be forcing me to upload the same files every time I edit the parent object.
All elements and javascript are done according to the docs linked, I don't find any property for CollectionType that would allow add but wouldn't allow edit or something similar. The javascript seems too dependent on external stuff to allow some modification.
Javascript
// assets/controllers/form-collection_controller.js
import { Controller } from '#hotwired/stimulus';
export default class extends Controller {
static targets = ["collectionContainer"]
static values = {
index : Number,
prototype: String,
}
addCollectionElement(event)
{
const item = document.createElement('li');
item.innerHTML = this.prototypeValue.replace(/__name__/g, this.indexValue);
this.collectionContainerTarget.appendChild(item);
this.indexValue++;
}
}
Twig template
<div {{ stimulus_controller('form-collection') }}
data-form-collection-index-value="{{ form.attachments|length > 0 ? form.attachments|last.vars.name + 1 : 0 }}"
data-form-collection-prototype-value="{{ form_widget(form.attachments.vars.prototype)|e('html_attr') }}"
>
<ul {{ stimulus_target('form-collection', 'collectionContainer') }}></ul>
<button type="button" class="btn btn-secondary" {{ stimulus_action('form-collection', 'addCollectionElement') }}>Añadir adjunto</button>
</div>

Symfony DateTime format errors - datatransformation (external datepicker)

I'm working with Symfony 6 and a TempusDomini datepicker.
I have read (amongst many others) the symfony documentation, https://symfony.com/doc/current/reference/forms/types/datetime.html.
Based on the documentation I found I initially implemented the form builder as followed:
->add('TextDateField')
->add('RegistrationDateTime', DateTimeType::class, [
'required' => false,
'widget' => 'single_text',
'format' => 'm/d/Y, h:i a',
'attr' => [
'class' => 'datetimepicker-input',
'data-target' => '#datetimepicker1'
],
'html5' => false,
])
The "TextDateField" is for troubleshooting, see explanation below.
And the actual TWIG file looks like this (for the TextDateField I have a similar datapicker block as the one for RegistrationDateTime):
{{form_start(form)}}
{{form_row(form.username)}}
<div class>
<label for="datetimepicker1Input" class="form-label">Simple picker</label>
<div class="input-group" id="datetimepicker1" data-td-target-input="nearest" data-td-target-toggle="nearest">
<input id="user_creation_form_RegistrationDateTime" name="user_creation_form[RegistrationDateTime]" type="text" class="form-control" data-td-target="#datetimepicker1">
<span class="input-group-text" data-td-target="#datetimepicker1" data-td-toggle="datetimepicker">
<span class="fa-solid fa-calendar"></span>
</span>
</div>
<script type="text/javascript">
const picker = new tempusDominus.TempusDominus(document.getElementById('datetimepicker1'));
</script>
</div>
{{form_row(form.roles)}}
{{form_row(form._token)}}
{{form_row(form.submit)}}
What I notice is that the dates are correctly given from a datepicker to the controller if passed via Text.
Please see this dump where you can see 2 datepicker values as passed to the controller, both for the same dates (6 may 2022)
App\Entity\TUser^ {#361
-id: null
-username: "scdsqd"
-roles: array:2 [
0 => "ROLE_USER"
1 => "ROLE_ADMIN"
]
-TextDateField: "05/06/2022, 12:42 PM"
-RegistrationDateTime: DateTime #1640599500 {#828
date: 2021-12-27 11:05:00.0 Europe/Berlin (+01:00)
}
}
So as you can see the text is passed correctly for the "text" datepicker but using the symfony DateTimeType::class messes it up by giving a seemingly random date.
Using other formats as datetime (for example timestamp) is not possible.
So how can I pass the value correctly to the database?
One possible "solution" is to work with TextType::class but since I want to keep the field RegistrationDateTime in the database as a DateTimeType this is not the best solution either since that would mean I have to transform the data.
Maybe I'm not looking at the right place, but it seems to me as if Symfony is not well adjusted to use external datepickers.
I have found tons of post with people struggling to implement a datepicker...
Is the approach I use correct?
How can I "force" symfony to "understand" the datepicker provided dates?
If the only way is to use TextType in the form-builder, how do I tackle the datatransformations to make sure that via doctrine I save in the datetime format?
Any pointers in the right direction are welcome... I'm getting rather frustrated by it since I've struggled on it an embarrassingly long time now...

Symfony 4 - Organize layout of fields

Using Symfony 4, I wonder if there a simple way to organize the layout of how display my fields.
For now, I template everything in my views (to have 2 columns for example) :
<div class="row">
<div class="col-md-6">
{{ form_row(form.name) }}
</div>
<div class="col-md-6">
{{ form_row(form.company) }}
</div>
</div>
{{ form_rest(form) }}
But, I don't want to do this, I just want to render whole form in my view, and manage the template in my FormBuilder. I would like to write something like :
$builder
->add('<div class="row"><div class="col-md-6">', HtmlType::class)
->add('name', TextType::class, [
'label' => 'Nom'
])
->add('</div><div class="col-md-6">', HtmlType::class)
->add('company', TextType::class, [
'label' => 'Société cliente'
])
->add('</div></div>', HtmlType::class);
I looked at the documentation, but it's pretty poor, it shows how to inerhit from existing fields.
Is there a way to create this HtmlType to just handle simple Html tags ? or a better way ?
You should be able to do something like that :
$builder->add('your_field', YourFieldClass::class, [
'attr' => ['class' => 'your css class'],
]);
The best solution would be to create a custom form theme. Reference to the documentation is here. I haven't done this myself for creating custom grid but I guess you can create some custom type options using the OptionResolver that will tell your template how to organize your fields and then based on that you can organize your custom form theme however you want.

How to render specific form elements Drupal 8

I am using Drupal 8 and would like to customize how form elements are being displayed. Specifically, I don't like how uneditable, populated textfields are displayed as plain text. I would have it being displayed as an editable textfield (or have the text look like it is in an uneditable textfield). I have looked at various hook functions to try and achieve this but nothing seems to work.
I figure the best way to go about this is if I can render the form fields individually myself and then create a twig file that displays the individual fields as I would like them to be displayed. Here is what I would like the twig field to look like:
<div class="from">
{{ form.mail }}
</div>
<div class="message">
{{ form.message }}
</div>
<div class="actions">
{{ form.actions }}
</div>
In your .module file
function your_module_theme($existing, $type, $theme, $path) {
return [
'custom_theme' => [
'variables' => [
'form' => NULL
],
'render element' => 'form',
]
];
}
In your CustomForm.php file
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
[...your fields ...]
return $form
}
In your custom module templates directory
custom-theme.html.twig
{{ form.your_field }}

allow new methods in sandbox policy in twig (drupal 8)

I am getting this error when using the "field collection" module :
Twig_Sandbox_SecurityError: Calling "uri" method on a "Drupal\field_collection\Entity\FieldCollectionItem" object is not allowed in "themes/communitylife/templates/content/node.html.twig" at line 83. in Drupal\Core\Template\TwigSandboxPolicy->checkMethodAllowed() (line 99 of core/lib/Drupal/Core/Template/TwigSandboxPolicy.php).
the code that causes the problem is this one :
<div class=" title-col col-md-7">
<a href="{{file_url(node.field_pressemappe_bildmaterial[key].getFieldCollectionItem().field_presse_bild_file.entity.uri.value)}}" target="_blank"> <strong> {{node.field_pressemappe_bildmaterial[key].getFieldCollectionItem().field_presse_bild_description.value}}
<span class="file-type"> ({{node.field_pressemappe_bildmaterial[key].getFieldCollectionItem().field_presse_bild_file.entity.uri.value | slice(-3) }} </span>, <span class="file-size"> {{node.field_pressemappe_bildmaterial[key].getFieldCollectionItem().field_presse_bild_file.entity.size }}) </span>
</strong></a>
</div>
what is the best way to fix this ? is it by adding (uri) to the allowed methods in the sandbox policy ? if yes then how I can do that ?
I read in the twig documentation that I can do something like this :
$policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
but I didn't understand how or where to put this code.
Thanks in advance
Drupal's twig sandbox policy (defined in core/lib/Drupal/Core/Template/TwigSandboxPolicy.php) reads from the global $settings array so you can define your own in your settings.php i.e.
// Override default twig method whitelist.
$settings['twig_sandbox_whitelisted_methods'] = [
// Defaults:
'id',
'label',
'bundle',
'get',
'__toString',
'toString',
// Additions:
'url',
];

Resources