aleksip / plugin-data-transform

Data Transform Plugin for Pattern Lab PHP
GNU General Public License v2.0
34 stars 10 forks source link

Attribute() doesn't work #13

Closed romanovma closed 7 years ago

romanovma commented 7 years ago

Expected: render class passed inside Attribute() object

Result: error message PHP Notice: Array to string conversion in ...pattern-lab/vendor/twig/twig/lib/Twig/Environment.php(462) : eval()'d code on line 60

Pattern-Lab version:

"name":             "pattern-lab/edition-twig-standard",
"require": {
    "php": ">=5.4",
    "pattern-lab/core": "^2.0.0",
    "pattern-lab/patternengine-twig": "^2.0.0",
    "pattern-lab/styleguidekit-twig-default": "^3.0.0",
    "pattern-lab/drupal-twig-components": "^2.2",
    "aleksip/plugin-data-transform": "^1.1"
}

Twigs: child.twig

<div {{ attributes }}></div>

parent.twig

{% include "@atoms/child.twig"
  with {
    attributes: {
      "Attribute()": {
        "class": ["test"]
      }
    }
  }
%}
aleksip commented 7 years ago

Hi @romanovma. The Data Transform Plugin syntax is for Pattern Lab data files only, not Twig files. So you should have a data file:

parent.json

{
  attributes: {
    "Attribute()": {
      "class": ["test"]
    }
  }
}

parent.twig

{% include "@atoms/child.twig"
  with {
    'attributes': attributes
  }
%}

If you want to create the Attribute object in Twig, this is possible since Drupal 8.3 using the create_attribute() function.

Hope this helps!

romanovma commented 7 years ago

That totally makes sense. Thanks a lot!

aleksip commented 7 years ago

Just a quick note that the Drupal-specific create_attribute() Twig function only works in Pattern Lab if it has been implemented for the Pattern Lab Twig PatternEngine. I don't think this has been done yet.

romanovma commented 7 years ago

Yeah, create_attribute() doesn't work for me.

The problem I encountered is that I have to define Attribute() inside data file for the most parent element which sometimes doesn't make sense. Say I use drop-down in a menu and I want to set drop-down attributes inside menu twig. But then I use this menu on page or template and in this case data defined in menu twig is not considered anymore. And I have to define Attribute() for the template again and for the page again...

So I finally decided to put Attribute() object into global data.json file and then manipulate it with addClass and etc. inside each twig before passing it into include declaration.

Not sure if it is the right way though.

aleksip commented 7 years ago

I have found a global Attribute to be useful in Shila theme.

With this approach you should note that global data is considered to be pattern-specific data and will overwrite data inherited from a parent pattern. If you want to override data of an included pattern you can use the with keyword in either data or Twig files.

The best definition for 'right way' I can think of is that the Twig templates should work in Drupal (and ideally anything that uses Twig templates, e.g. a Symfony application) without any modifications. Other than that, everything can be done in more than one way, I guess.

You can check out Shila theme if you are interested in the way I've currently implemented things with Pattern Lab, Data Transform Plugin and Drupal.

romanovma commented 7 years ago

OK, I see. My approach won't work then. I thought I could manipulate global Attribute()before passing it to the child. But in the end, it will be overwritten with global empty 'Attribute()' inside child and the value I'm passing will be ignored :(

May be you could point to a good example in Shila theme where the twig with attributes parameter is included in another twig inside Pattern Lab(not inside Drupal theme)? Thanks.

aleksip commented 7 years ago

Your approach should work, if you pass the attributes variable with the with keyword. Child templates have access to the parent's variables even when the variables are not passed, and it is only in this case that the variables are overwritten by local/global data.

romanovma commented 7 years ago

@aleksip Does it work with .yml files as a data source? with this data like:

attributes:
  Attribute():
     label: optional radio 1
     id: optional-radio-1
     group: optional
     type: radio
     checked: true

and this twig:

 <input {{ option.attributes.addClass('form-radio__input') }} />

I got this HTML:

<input label="&quot;optional" radio="" 1&quot;="" id="&quot;optional-radio-1&quot;" group="&quot;optional&quot;" type="&quot;radio&quot;" checked=""
romanovma commented 7 years ago

It is actually the same with .json. Am I doing something wrong?

romanovma commented 7 years ago

OK, it works with |raw filter. Please never mind :)