I have a yml file for the user form validation (a form like many others):
# src/User/RegBundle/Resources/config/validation.yml
User\RegBundle\Entity\User:
properties:
name:
- NotBlank: ~
- Length:
min: 2
max: 255
minMessage: error_min_message
maxMessage: error_max_message
The form is rendered into the twig like below
//...
{{ form_row(form.name) }}
{{ form_row(form.surname) }}
{{ form_row(form.gender) }}
{{ form_row(form.email) }}
//...
My symfony2 website has a multilanguage structure and there are the messages.mylang.xliff file for the words translation.
All works right.
My question is whether there's a way to insert the "error_min_message" into the messages.mylang.xliff or there are others ways to translate that messages.
Validation strings go to validators.LANG.FORMAT instead of messages.LANG.FORMAT. Don't forget to clear the cache after you add a new translation file.
Related
I am very new to Drupal.
Can anyone tell me how to display the custom fields content type into twig template?
Thank you
I used below code with content and nodes.
{{ content.field_a }}
You'll have to follow these steps :
Step 1) Custom template for a content type
Suppose, you have to create a new template for content type i.e. Article ( machine_name : article ). Just make a copy of node.html.twig and rename with node--article.html.twig
Step 2) Call custom field
In this template, you can display content of your field like {{ content.field_test_field }}
Step 3) Clear Cache
If you're looking to create a full page template for an Article for example, you can create a file called : page--node--article.html.twig
Any custom content type would follow the pattern, for example if the content type is called Machine Product, the template would be: page--node--machine-product.html.twig (1 dash between spaces of the content type name.
For Drupal 8, this is my typical mapping for this filetype :
Blocks:
{{ page.REGIONNAME }}
Title:
{{ node.title.value }}
Taxonomy Terms/Dropdown Selects in Create Content:
{{ node.field_FIELDNAME.0.entity.label }}
General Text Fields:
{{ node.field_FIELDNAME.value }}
Images/Files:
{{ file_url(node.field_FIELDNAME.entity.fileuri')) }}
I install a configuration for rails that looks like this (simplified):
production:
secret_key_base: 800afb35d5086b2c60ebd35c01b2bd2b522c2492
db_username: ...
db_password: ...
and so it gets installed from a template file
{{ role }}:
secret_key_base: {{ secret_key }}
db_username: {{ db_user }}
db_password: {{ db_pass }}
And the role and db user/pass get pulled from pillar and installed in that file. The secret_key it would make sense to generate randomly, e.g., {{ salt['random.get_str'](length=80) }}. But I want to generate it once, not every time the template is rendered. (Changing the secret key invalidates cookies, not something to do on each salt run.)
The only solution I've found is two-phase: I have a template.in file
{{ role }}:
secret_key_base: ||secret_key_base||
db_username: {{ db_user }}
db_password: {{ db_pass }}
that I sed into my template file on any given minion:
/srv/salt/rails/secrets.yml:
cmd.run:
# Fill in the secret key base (used for cookies). We can't use
# jinja2 for this, since jinja would complain about the other
# variables that it doesn't know how to replace. We want our
# output to be a jinja template.
- name: |
cat /srv/salt/rails/secrets.yml.in | \
sed -e 's/||secret_key_base||/{{ salt['random.get_str'](length=80) }}/;' | \
cat > /srv/salt/rails/secrets.yml
chmod 400 /srv/salt/rails/secrets.yml
- creates: /srv/salt/rails/secrets.yml
- runas: root
/var/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: host_role
db_username: m_u
db_password: m_p
This works but has the disadvantage that a change to secrets.yml.in would not be propagated on to secrets.yml. (Suppose we add another key to the secrets file.) It also feels clunkier than necessary.
Is there a better way?
A better way
As noted in the comments, a better way is to just generate the secret by hand (after all, it's only done at host setup) and store it in pillar, where we anyway have to say a few things about each host.
Here is what the working code eventually looked like, unsimplified for those who might want to see something more complex. Much of the complexity is my host_credentials pillar data, which tries to characterise all that we need to know about each host.
{% set fqdn = grains.get('fqdn', 'unknown-host-fqdn') %}
{% set host_role = pillar['host_credentials']
[grains.get('fqdn')]
['role'] %}
{% set examplecom_web_app = pillar['host_credentials']
[grains.get('fqdn')]
['examplecom-web-app'] %}
{% set mysql_server_host = examplecom_web_app.mysql.host %}
{% set mysql_server_database = examplecom_web_app.mysql.database %}
{% set mysql_server_role = examplecom_web_app.mysql.role %}
{% set mysql_server_spec = pillar['host_credentials']
[mysql_server_host]
['mysql'] %}
{% set mongodb_server_host = examplecom_web_app.mongodb.host %}
{% set mongodb_server_spec = pillar['host_credentials']
[mongodb_server_host]
['mongodb'] %}
/var/examplecom/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: {{ host_role }}
secret_key_base: {{ examplecom_web_app.secret_key_base }}
mysql_hostname: {{ mysql_server_host }}
mysql_username: {{ mysql_server_spec[mysql_server_database]
[mysql_server_role]
['username'] }}
mysql_password: {{ mysql_server_spec[mysql_server_database]
[mysql_server_role]
['password'] }}
mongodb_hostname: {{ mongodb_server_host }}
mongodb_username: {{ mongodb_server_spec.username }}
mongodb_password: {{ mongodb_server_spec.password }}
As an aside, I was happy to discover that jinja2 is white-space agnostic, which helps enormously with readability on such lookups.
I recommend putting the secret in a pillar and generate the value once (manually) on the master. That way you can avoid doing the stateful on-the-fly-magic in your SLS file.
jma updated his question to include an example solution.
Do I understand you correctly:
- this is salt-masterless run?
- you generate some template file on masterless node (to have some static parts generated once)
- you apply file.managed state to previously generated file?
Assuming my understandings:
First of all it will be propagated to another states if you set proper watch/require statements but in your case this would be harder to achieve as you've used cmd.run for template parsing (you must add stateful argument to express that there is some potential state changes underlying)
Remarks:
- did you see file.blockreplace? it seems that you can use this to replace first cmd.run and get file change detection "for free"
- as for one time password generation, there is nice trick to do this simply by using grains.get_or_set_hash
As the generated password is not changing for given minion (you master-less node in your case) the file.blockreplace won't report any changes unless you add changes to the template
Having said this, I think we can go further and your state actually can be as simple as this (template changes will be propagated always, key will be generated once):
/var/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: host_role
db_username: m_u
db_password: {{ salt['grains.get_or_set_hash']('some:place:secret_key_base') }}
How can i render a field directly in the page.html.twig?
When i try to render it like:
{{ node.field_my_field.value }}
I get:
Exception: Object of type Drupal\entity_reference_revisions\EntityReferenceRevisionsFieldItemList cannot be printed
When i add a .value, it does still not render right (well i use paragraphs with subfields) but get following error:
User error: "target_id" is an invalid render array key in
Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).
User error: "target_revision_id" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).
User error: "_loaded" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).
User error: "_accessCacheability" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).
So how can i render it?
In Drupal 8 & Twig you can render a lot of stuff such:
Render field value
For example, the node title
{{ node.title.value }}
Render field entity value
For example, a field of taxonomy term categories
{{ node.field_categories.entity.name.value }}
Render field value of Paragraph (entity)
You can't print a Paragraph entity in Twig, but you can print every fields
{{ node.field_my_field.entity.field_title.value }}
In the previous example, field_title is a field of my Paragraph.
To go further, you could render a display mode using the module Bamboo Twig.
- Project page
- Article about Bamboo Twig
- Official Documentation
Render entity with display mode using Bamboo Twig
After installing the module and enable the submodule bamboo_twig_loader.
{# Render node with nid 1 #}
{{ bamboo_render_entity('node', 1) }}
{# Render the teaser of node with nid 2 #}
{{ bamboo_render_entity('node', 2, 'teaser') }}
Render field using Bamboo Twig
{# Render the title of node 1 #}
{{ bamboo_render_field('title', 'node', 1) }}
Hopes it will help you !
In order to render the field in a twig template, you will need a contrib module; unless you go with the hook_preprocess_page() implementation.
Using Bamboo Twig definitely does your job, as already mentioned in the suggested answer. It seems a bit awkward at first that you have to enable one of its submodules in order to achieve this though.
An alternative and more common solution is to use the Twig Tweak module with which you could do the following (copying from their cheat sheet):
{{ drupal_field('field_image', 'node', 1) }}
{{ drupal_field('field_image', 'node', 1, 'teaser') }}
{{ drupal_field('field_image', 'node', 1, {type: 'image_url', settings: {image_style: 'large'}}) }}
I have several states that are almost the same. All of them deploy project, create virtualenv and configure supervisor. Difference is only in repo, project name and some additional actions.
A lot of code is duplicated. Is it possible to put the same parts into file and include it with additional variables?
In Ansible it can be done this way:
tasks:
- include: wordpress.yml
vars:
wp_user: timmy
ssh_keys:
- keys/one.txt
- keys/two.txt
This question looks similar to this one
If I understood your question correctly - I believe the best way to achieve what you want is to use Salt Macros.
With this most of your state will go to macros with placeholders being parameters like:
# lib.sls
{% macro create_user(user, password) %}
{{user}}:
user.present:
- home: /home/{{user}}
- password: {{password}}
{% endmacro %}
Then your state will look like:
# john.sls
{% from 'lib.sls' import create_user with context %}
{{ create_user('john', '<password hash>') }}
and:
# jane.sls
{% from 'lib.sls' import create_user with context %}
{{ create_user('john', '<password hash>') }}
As I found out there is another way to archive it without messing with templates (more Ansible way). Create an abstract state "python-project". Create concrete roles then and provide different pillars to these roles:
salt/top.sls:
base:
'roles:python-project-1':
- match: grain
- python-project
'roles:python-project-2':
- match: grain
- python-project
pillar/top.sls:
base:
'roles:python-project-1':
- match: grain
- common-pillars
- pillars-for-the-first
'roles:python-project-2':
- match: grain
- common-pillars
- pillars-for-the-second
Structure:
pillar/top.sls
pillar/common-pillars/init.sls
pillar/pillars-for-the-first/init.sls
pillar/pillars-for-the-second/init.sls
salt/top.sls
salt/python-project/init.sls
You can use Jinja imports to do that:
top.sls
{% set user = 'john' %}
{% include 'config.sls' %}
config.sls
file.managed:
- name: '/Users/{{ user }}/.config
- user: {{ user }}
I wish to limit the amount of text displayed from a mysql statement. So for example, in my database I have a page where there are 1000 words contained in the content field, I want to be able to just display 200 of those words.
How can this be done using TWIG?
Cheers!
Sounds like your are looking for the "truncate" filter.
In your app/config/config.yml add::
services:
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags:
- { name: twig.extension }
Then you can do in your templates:
{{ var.foo | truncate(200) }}
{{ "Hello good Sir!" | truncate(4) }}