Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 31 min 42 sec ago

Wunderkraut blog: Configuration Entities in Drupal 8

Mon, 07/14/2014 - 11:10
p class=field-ns-blog-post-lead With the overhaul of many API#039;s in Drupal 8, one of the new kids on the block is the configuration system with its integration with the entity API. This means that we can now define configuration entities (that work much like the regular content entities) for the purpose of managing more complex configuration. For example, a View is a configuration entity and so is a field or an image style. /p div class=field-ns-blog-post-body clearfix div class=field-item even pIn this article we will look at how to define a configuration entity type that will serve a simple purpose, describe dummy emflower/em configuration entities. We will do so in a module called emflower/em and will use the alpha13 release of Drupal 8 to do it./p pBefore we get started, let's define a practical goal for this tutorial. As I said, we will have a flower config entity type with a couple of properties: name, number of petals, color and season. And by the end, we will have a fully fledged UI to create and manage them. The final code you can also find in a href=https://github.com/upchuk/drupal-8-config-entities target=_blankthis repository/a./p pSo let's begin./p h2The configuration entity interface/h2 pThe first thing we need to do is define an interface our emFlower/em entity type class can implement and that extends the default a href=https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Config%21Entity%21ConfigEntityInterface.php/interface/ConfigEntityInterface/8ConfigEntityInterface/a. So inside of our module's emsrc//em folder, create a file called emFlowerInterface.php/em with the following interface:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * @file * Contains \Drupal\flower\FlowerInterface. *//span nbsp; span style=color: #000000; font-weight: bold;namespace/span Drupal\flowerspan style=color: #339933;;/span nbsp; span style=color: #000000; font-weight: bold;use/span Drupal\Core\Config\Entity\ConfigEntityInterfacespan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * Provides an interface defining a flower entity type. *//span span style=color: #000000; font-weight: bold;interface/span FlowerInterface span style=color: #000000; font-weight: bold;extends/span ConfigEntityInterface span style=color: #009900;#123;/span nbsp; span style=color: #009900;#125;/span/pre/div pAs you can see, we are just extending the default configuration entity interface without adding any methods to it (which is possible)./p h2The configuration entity class/h2 pNext, we will focus on the crux of defining our own configuration entity class. Go ahead and create a folder inside the emsrc//em directory called emEntity/em, and within it, a file called emFlowerEntity.php/em:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * @file * Contains \Drupal\flower\Entity\FlowerEntity. *//span nbsp; span style=color: #000000; font-weight: bold;namespace/span Drupal\flower\Entityspan style=color: #339933;;/span nbsp; span style=color: #000000; font-weight: bold;use/span Drupal\Core\Config\Entity\ConfigEntityBasespan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Config\Entity\ConfigEntityInterfacespan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\flower\FlowerInterfacespan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * Defines a Flower configuration entity class. * * @ConfigEntityType( * id = quot;flowerquot;, * label = @Translation(quot;Flowerquot;), * fieldable = FALSE, * controllers = { * quot;list_builderquot; = quot;Drupal\flower\FlowerListBuilderquot;, * quot;formquot; = { * quot;addquot; = quot;Drupal\flower\Form\FlowerFormquot;, * quot;editquot; = quot;Drupal\flower\Form\FlowerFormquot;, * quot;deletequot; = quot;Drupal\flower\Form\FlowerDeleteFormquot; * } * }, * config_prefix = quot;flowerquot;, * admin_permission = quot;administer site configurationquot;, * entity_keys = { * quot;idquot; = quot;idquot;, * quot;labelquot; = quot;namequot; * }, * links = { * quot;edit-formquot; = quot;flower.editquot;, * quot;delete-formquot; = quot;flower.deletequot; * } * ) *//span span style=color: #000000; font-weight: bold;class/span FlowerEntity span style=color: #000000; font-weight: bold;extends/span ConfigEntityBase implements FlowerInterface span style=color: #009900;#123;/span nbsp; span style=color: #009933; font-style: italic;/** * The ID of the flower. * * @var string *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000088;$id/spanspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * The flower name. * * @var string *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000088;$name/spanspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * The flower color. * * @var string *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000088;$color/spanspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * The number of petals. * * @var int *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000088;$petals/spanspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * The season in which this flower can be found. * * @var string *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000088;$season/spanspan style=color: #339933;;/span nbsp; span style=color: #009900;#125;/span/pre/div pWhat we have here is a simple class defining the entity properties we want (name, id, color, number of petals and season). This class extends the default a href=https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Config%21Entity%21ConfigEntityBase.php/class/ConfigEntityBase/8ConfigEntityBase/a class and implements our interface. What happens above the class definition is what's interesting though./p pUsing a href=https://api.drupal.org/api/drupal/core!modules!system!system.api.php/group/annotation/8annotations/a, we are basically telling Drupal about our emFlower/em entity type./p pThe em@ConfigEntityType/em tells Drupal that this is a configuration entity type (as opposed to a plugin or something else). Within its definition, we have an array-like structure with the following information (I will only mention the keys that are not super obvious):/p ulliemlabel/em - the label of the entity type passed through the translation system./li liemfieldable/em - the configuration entities are not fieldable, but the content entities are. Since we are using the same entity API, we can specify this./li liemcontrollers/em - all the classes needed to manage these entities. The emlist_builder/em class will provide an admin overview interface of the entities, whereas the emform/em classes are used to perform the CRUD operations through the UI./li liemconfig_prefix/em - a configuration identifier/li liementity keys/em - mapping of the main entity keys to the entity properties we defined. For instance, when we call the emlabel()/em method on the entity object, it will return the flower name./li liemlinks/em - administration links for editing and deleting entities with values referencing routes. Specifying them here will make Drupal add them automatically to the emoperations/em column on the entity overview page (we'll see this in a minute)./li /ulpFor more information about the structure of an entity class annotation, follow this a href=https://drupal.org/node/2207559documentation page/a./p h2The entity forms/h2 pThe next thing we need to do is create the forms we referenced in the annotations above: for adding, editing and deleting flower entities. The cool thing is that the form for emadding/em can be reused for emediting/em as well. For delete, we extend a special class that gives us all we need for a confirmation form. But first, the add/edit form (emFlowerForm.php/em) inside of the emsrc/Form//em folder:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * @file * Contains \Drupal\flower\Form\FlowerForm. *//span nbsp; span style=color: #000000; font-weight: bold;namespace/span Drupal\flower\Formspan style=color: #339933;;/span nbsp; span style=color: #000000; font-weight: bold;use/span Drupal\Core\Entity\EntityFormspan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Entity\EntityInterfacespan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Entity\EntityTypeInterfacespan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Urlspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * Class FlowerForm * * Form class for adding/editing flower config entities. *//span span style=color: #000000; font-weight: bold;class/span FlowerForm span style=color: #000000; font-weight: bold;extends/span EntityForm span style=color: #009900;#123;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span formspan style=color: #009900;#40;/spana href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #000088;$form/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #339933;amp;/spanspan style=color: #000088;$form_state/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span nbsp; span style=color: #000088;$form/span span style=color: #339933;=/span parentspan style=color: #339933;::/spanspan style=color: #004000;form/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$form/spanspan style=color: #339933;,/span span style=color: #000088;$form_state/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #000088;$flower/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;entity/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// Change page title for the edit operation/span span style=color: #b1b100;if/span span style=color: #009900;#40;/spanspan style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;operation/span span style=color: #339933;==/span span style=color: #0000ff;'edit'/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'#title'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Edit flower: @name'/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'@name'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span nbsp; span style=color: #666666; font-style: italic;// The flower name./span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'name'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'#type'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'textfield'/spanspan style=color: #339933;,/span span style=color: #0000ff;'#title'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Name'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#maxlength'/span span style=color: #339933;=gt;/span span style=color: #cc66cc;255/spanspan style=color: #339933;,/span span style=color: #0000ff;'#default_value'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #339933;,/span span style=color: #0000ff;'#description'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;quot;Flower name.quot;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#required'/span span style=color: #339933;=gt;/span span style=color: #009900; font-weight: bold;TRUE/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// The unique machine name of the flower./span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'id'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'#type'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'machine_name'/spanspan style=color: #339933;,/span span style=color: #0000ff;'#maxlength'/span span style=color: #339933;=gt;/span EntityTypeInterfacespan style=color: #339933;::/spanspan style=color: #004000;BUNDLE_MAX_LENGTH/spanspan style=color: #339933;,/span span style=color: #0000ff;'#default_value'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;id/spanspan style=color: #339933;,/span span style=color: #0000ff;'#disabled'/span span style=color: #339933;=gt;/span span style=color: #339933;!/spanspan style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;isNew/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#machine_name'/span span style=color: #339933;=gt;/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'source'/span span style=color: #339933;=gt;/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'name'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'exists'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'flower_load'/span span style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// The flower color./span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'color'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'#type'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'textfield'/spanspan style=color: #339933;,/span span style=color: #0000ff;'#title'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Color'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#maxlength'/span span style=color: #339933;=gt;/span span style=color: #cc66cc;255/spanspan style=color: #339933;,/span span style=color: #0000ff;'#default_value'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;color/spanspan style=color: #339933;,/span span style=color: #0000ff;'#description'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;quot;Flower color.quot;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#required'/span span style=color: #339933;=gt;/span span style=color: #009900; font-weight: bold;TRUE/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// The number of petals./span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'petals'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'#type'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'textfield'/spanspan style=color: #339933;,/span span style=color: #0000ff;'#title'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Petals'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#maxlength'/span span style=color: #339933;=gt;/span span style=color: #cc66cc;255/spanspan style=color: #339933;,/span span style=color: #0000ff;'#default_value'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;petals/spanspan style=color: #339933;,/span span style=color: #0000ff;'#description'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;quot;The number of petals.quot;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#required'/span span style=color: #339933;=gt;/span span style=color: #009900; font-weight: bold;TRUE/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// The season./span span style=color: #000088;$form/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'season'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'#type'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'select'/spanspan style=color: #339933;,/span span style=color: #0000ff;'#options'/span span style=color: #339933;=gt;/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'Spring'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'Spring'/spanspan style=color: #339933;,/span span style=color: #0000ff;'Summer'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'Summer'/spanspan style=color: #339933;,/span span style=color: #0000ff;'Automn'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'Automn'/spanspan style=color: #339933;,/span span style=color: #0000ff;'Witer'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'Winter'/span span style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#title'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Season'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#maxlength'/span span style=color: #339933;=gt;/span span style=color: #cc66cc;255/spanspan style=color: #339933;,/span span style=color: #0000ff;'#default_value'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;season/spanspan style=color: #339933;,/span span style=color: #0000ff;'#description'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;quot;The season in which this flower grows.quot;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;,/span span style=color: #0000ff;'#required'/span span style=color: #339933;=gt;/span span style=color: #009900; font-weight: bold;TRUE/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #b1b100;return/span span style=color: #000088;$form/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span savespan style=color: #009900;#40;/spana href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #000088;$form/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #339933;amp;/spanspan style=color: #000088;$form_state/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span nbsp; span style=color: #000088;$flower/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;entity/spanspan style=color: #339933;;/span nbsp; span style=color: #000088;$status/span span style=color: #339933;=/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;save/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #b1b100;if/span span style=color: #009900;#40;/spanspan style=color: #000088;$status/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #666666; font-style: italic;// Setting the success message./span drupal_set_messagespan style=color: #009900;#40;/spanspan style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Saved the flower: @name.'/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'@name'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span span style=color: #b1b100;else/span span style=color: #009900;#123;/span drupal_set_messagespan style=color: #009900;#40;/spanspan style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'The @name flower was not saved.'/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/span span style=color: #0000ff;'@name'/span span style=color: #339933;=gt;/span span style=color: #000088;$flower/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #339933;,/span span style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span span style=color: #000088;$url/span span style=color: #339933;=/span span style=color: #000000; font-weight: bold;new/span Urlspan style=color: #009900;#40;/spanspan style=color: #0000ff;'flower.list'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #000088;$form_state/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'redirect'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$url/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;toString/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #009900;#125;/span nbsp; span style=color: #009900;#125;/span /pre/div pIn our emFlowerForm/em class we are extending the Drupal a href=https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityForm.php/class/EntityForm/8EntityForm/a class and implementing 2 of its methods: emform()/em and emsave()/em. In the first one, we define a regular Form API form very similar to what we do in Drupal 7. But there are a few cool new things happening there as well:/p ulliWe extend the parent form and add our elements to that definition./li liWe get the configuration entity object from the ementity/em property of the parent class./li liWe check the operation being performed on the entity and if the user is editing it, we change the title of the page to reflect this/li liInstead of using the procedural emt()/em function, we access em$this-gt;t()/em on the parent class for a href=https://www.drupal.org/node/2079611best practice/a./li liWe access the config entity public properties and set them as the defaults in the form elements' definition./li liFor the emmachine_name/em, we use the emflower_load()/em helper function (that we will need to define in our em.module/em file) in order to automatically check whether an entity with that ID already exists./li /ulpIn the emsave()/em method we perform the simple operation of saving the entity object to the configuration system. Couldn't get simpler than this. And after the save is performed, we redirect to the flower entity overview page. Here we use the a href=https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/class/Url/8Url/a class to build a url object based on a route (that we will define later)./p pNext, let's quickly create the delete form./p pInside the same emsrc/Form//em folder, create a emFlowerDeleteForm.php/em file with the following class:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * @file * Contains \Drupal\flower\Form\FlowerDeleteForm. *//span span style=color: #000000; font-weight: bold;namespace/span Drupal\flower\Formspan style=color: #339933;;/span nbsp; span style=color: #000000; font-weight: bold;use/span Drupal\Core\Entity\EntityConfirmFormBasespan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Urlspan style=color: #339933;;/span nbsp; span style=color: #009933; font-style: italic;/** * Form that handles the removal of flower entities. *//span span style=color: #000000; font-weight: bold;class/span FlowerDeleteForm span style=color: #000000; font-weight: bold;extends/span EntityConfirmFormBase span style=color: #009900;#123;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span getQuestionspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #b1b100;return/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Are you sure you want to delete this flower: @name?'/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'@name'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span getCancelRoutespan style=color: #009900;#40;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #b1b100;return/span span style=color: #000000; font-weight: bold;new/span Urlspan style=color: #009900;#40;/spanspan style=color: #0000ff;'flower.list'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span getConfirmTextspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #b1b100;return/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Delete'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span submitspan style=color: #009900;#40;/spana href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #000088;$form/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/a span style=color: #339933;amp;/spanspan style=color: #000088;$form_state/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span nbsp; span style=color: #666666; font-style: italic;// Delete and set message/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;delete/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span drupal_set_messagespan style=color: #009900;#40;/spanspan style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'The flower @label has been deleted.'/spanspan style=color: #339933;,/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'@label'/span span style=color: #339933;=gt;/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;name/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #000088;$form_state/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'redirect_route'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;getCancelRoute/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #009900;#125;/span span style=color: #009900;#125;/span/pre/div pWith this form class we are extending the Drupal a href=https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityConfirmFormBase.php/class/EntityConfirmFormBase/8EntityConfirmFormBase/a that provides us with all we need for a delete confirmation form. By implementing these self-explanatory methods, we take care of the entity delete process. Finally, it's time to define the admin overview page./p h2The entity list builder/h2 pAs we declared when defining the config entity class, we now need a class file responsible for building the overview page of our entities. So straight in the emsrc//em folder of our module you can create a emFlowerListBuilder.php/em class file with the following class:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * @file * * Contains Drupal\flower\FlowerListBuilder *//span nbsp; span style=color: #000000; font-weight: bold;namespace/span Drupal\flowerspan style=color: #339933;;/span nbsp; span style=color: #000000; font-weight: bold;use/span Drupal\Core\Config\Entity\ConfigEntityListBuilderspan style=color: #339933;;/span span style=color: #000000; font-weight: bold;use/span Drupal\Core\Entity\EntityInterfacespan style=color: #339933;;/span nbsp; nbsp; span style=color: #000000; font-weight: bold;class/span FlowerListBuilder span style=color: #000000; font-weight: bold;extends/span ConfigEntityListBuilder span style=color: #009900;#123;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span buildHeaderspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #000088;$header/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'label'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Name'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #000088;$header/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'color'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Color'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #000088;$header/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'petals'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Number of petals'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #000088;$header/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'season'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'Season'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #b1b100;return/span span style=color: #000088;$header/span span style=color: #339933;+/span parentspan style=color: #339933;::/spanspan style=color: #004000;buildHeader/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span buildRowspan style=color: #009900;#40;/spanEntityInterface span style=color: #000088;$entity/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span nbsp; span style=color: #666666; font-style: italic;// Label/span span style=color: #000088;$row/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'label'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;getLabel/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$entity/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// Color/span span style=color: #000088;$row/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'color'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;color/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// Petals/span span style=color: #000088;$row/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'petals'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;petals/spanspan style=color: #339933;;/span nbsp; span style=color: #666666; font-style: italic;// Season/span span style=color: #000088;$row/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'season'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$entity/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;season/spanspan style=color: #339933;;/span nbsp; span style=color: #b1b100;return/span span style=color: #000088;$row/span span style=color: #339933;+/span parentspan style=color: #339933;::/spanspan style=color: #004000;buildRow/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$entity/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span nbsp; span style=color: #009933; font-style: italic;/** * {@inheritdoc} *//span span style=color: #000000; font-weight: bold;public/span span style=color: #000000; font-weight: bold;function/span renderspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span nbsp; span style=color: #000088;$build/span span style=color: #339933;=/span parentspan style=color: #339933;::/spanspan style=color: #004000;render/spanspan style=color: #009900;#40;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span nbsp; span style=color: #000088;$build/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'#empty'/spanspan style=color: #009900;#93;/span span style=color: #339933;=/span span style=color: #000088;$this/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;t/spanspan style=color: #009900;#40;/spanspan style=color: #0000ff;'There are no flowers available.'/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #b1b100;return/span span style=color: #000088;$build/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span nbsp; span style=color: #009900;#125;/span /pre/div pIn this class that extends the a href=https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Config!Entity!ConfigEntityListBuilder.php/class/ConfigEntityListBuilder/8ConfigEntityListBuilder/a, we implement three methods. The embuildHeader()/em method is responsible for creating the table header of our overview page whereas embuildRow()/em will create the rows based on the number of entities and their values. Lastly, we are overriding the emrender()/em method so that we can specify a custom message to display in case there are no entities to show (personal preference). And that's basically it with the list builder class./p h2Miscellaneous/h2 pThere are a few more things we need to take care of in order to round up our configuration entity type. The first one has a href=https://www.drupal.org/node/2288297just became kind of mandatory/a so I'll start with that: a href=https://www.drupal.org/node/1905070the configuration schema/a. So let's quickly create the folder structure inside our module (emconfig/schema//em) and inside a file called emflower.schema.yml/em we can have the following:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #666666; font-style: italic;# Schema for the configuration files of the Flower module. /span flowerspan style=color: #339933;./spanflowerspan style=color: #339933;.*:/span typespan style=color: #339933;:/span mapping labelspan style=color: #339933;:/span span style=color: #0000ff;'Flower'/span mappingspan style=color: #339933;:/span idspan style=color: #339933;:/span typespan style=color: #339933;:/span string labelspan style=color: #339933;:/span span style=color: #0000ff;'Flower identifier'/span uuidspan style=color: #339933;:/span typespan style=color: #339933;:/span string labelspan style=color: #339933;:/span span style=color: #0000ff;'UUID'/span namespan style=color: #339933;:/span typespan style=color: #339933;:/span label labelspan style=color: #339933;:/span span style=color: #0000ff;'Name'/span colorspan style=color: #339933;:/span typespan style=color: #339933;:/span string labelspan style=color: #339933;:/span span style=color: #0000ff;'Color'/span translatablespan style=color: #339933;:/span span style=color: #009900; font-weight: bold;true/span petalsspan style=color: #339933;:/span typespan style=color: #339933;:/span integer labelspan style=color: #339933;:/span span style=color: #0000ff;'Number of petals'/span seasonspan style=color: #339933;:/span typespan style=color: #339933;:/span string labelspan style=color: #339933;:/span span style=color: #0000ff;'Season'/span translatablespan style=color: #339933;:/span span style=color: #009900; font-weight: bold;true/span/pre/div pOn the first line (after the comment) we start defining the schema for the em(flower module).(flower configuration entity type).(all flower configuration entities)/em. And it follows to map all the entity properties and specify what data type they are. Although the emuuid/em property was not defined by us, Drupal adds it by default and we can specify it here./p pAs far as I could tell, the emlabel/em-typed properties become translatable automatically whereas for all the rest we want translatable we can specify emtranslatable: true/em. Translation is one of the biggest reasons for which we use these schemas for configuration entities./p pAnd now that the schema is taken care of, it's time for some finishing touches. First, let's create our routes so that we can access everything in the browser. Inside of a file called emflower.routing.yml/em in the module root folder, add the following:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;flowerspan style=color: #339933;./spana href=http://www.php.net/listspan style=color: #990000;list/span/aspan style=color: #339933;:/span pathspan style=color: #339933;:/span span style=color: #0000ff;'/admin/structure/flowers'/span defaultsspan style=color: #339933;:/span _entity_listspan style=color: #339933;:/span span style=color: #0000ff;'flower'/span _titlespan style=color: #339933;:/span span style=color: #0000ff;'Flowers'/span requirementsspan style=color: #339933;:/span _permissionspan style=color: #339933;:/span span style=color: #0000ff;'administer site configuration'/span flowerspan style=color: #339933;./spanaddspan style=color: #339933;:/span pathspan style=color: #339933;:/span span style=color: #0000ff;'/admin/structure/flowers/add'/span defaultsspan style=color: #339933;:/span _entity_formspan style=color: #339933;:/span span style=color: #0000ff;'flower.add'/span _titlespan style=color: #339933;:/span span style=color: #0000ff;'Add a new flower'/span requirementsspan style=color: #339933;:/span _permissionspan style=color: #339933;:/span span style=color: #0000ff;'administer site configuration'/span flowerspan style=color: #339933;./spaneditspan style=color: #339933;:/span pathspan style=color: #339933;:/span span style=color: #0000ff;'/admin/structure/flowers/edit/{flower}'/span defaultsspan style=color: #339933;:/span _entity_formspan style=color: #339933;:/span span style=color: #0000ff;'flower.edit'/span _titlespan style=color: #339933;:/span span style=color: #0000ff;'Edit flower'/span requirementsspan style=color: #339933;:/span _permissionspan style=color: #339933;:/span span style=color: #0000ff;'administer site configuration'/span flowerspan style=color: #339933;./spandeletespan style=color: #339933;:/span pathspan style=color: #339933;:/span span style=color: #0000ff;'/admin/structure/flowers/delete/{flower}'/span defaultsspan style=color: #339933;:/span _entity_formspan style=color: #339933;:/span span style=color: #0000ff;'flower.delete'/span _titlespan style=color: #339933;:/span span style=color: #0000ff;'Delete flower'/span requirementsspan style=color: #339933;:/span _permissionspan style=color: #339933;:/span span style=color: #0000ff;'administer site configuration'/span/pre/div pFor more information about the structure of a route file (and what the above keys actually mean), please consult a href=https://www.drupal.org/node/2092643this documentation page/a. But an important take-away are the paths we defined at emadmin/structure/flowers/em./p pSecond, on the flower overview page, we'd probably like a link to add new flowers to the site. So let's create another YML file in the root of our module called emflower.local_actions.yml/em to define that link:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;flowerspan style=color: #339933;./spanaddspan style=color: #339933;:/span route_namespan style=color: #339933;:/span span style=color: #0000ff;'flower.add'/span titlespan style=color: #339933;:/span span style=color: #0000ff;'Add flower'/span appears_onspan style=color: #339933;:/span span style=color: #339933;-/span flowerspan style=color: #339933;./spana href=http://www.php.net/listspan style=color: #990000;list/span/a/pre/div pThis is a simple local action link definition called emflower.add/em that uses the emflower.add/em route and appears on the page given by the route emflower.list/em. For more information about defining local actions, consult a href=https://www.drupal.org/node/2133247this documentation page/a./p pThird, we can create a menu link under the emStructure/em admin menu that will take us to the flower overview page. So inside of a file called emflower.menu_links.yml/em in the module root folder, add the following:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;flowerspan style=color: #339933;./spana href=http://www.php.net/listspan style=color: #990000;list/span/aspan style=color: #339933;:/span titlespan style=color: #339933;:/span Flowers descriptionspan style=color: #339933;:/span span style=color: #0000ff;'Administer the flower entities'/span parentspan style=color: #339933;:/span a href=http://www.php.net/systemspan style=color: #990000;system/span/aspan style=color: #339933;./spanadmin_structure route_namespan style=color: #339933;:/span flowerspan style=color: #339933;./spana href=http://www.php.net/listspan style=color: #990000;list/span/a/pre/div pHere we create a link called emflower.list/em found under the emsystem.admin_structure/em link and that uses the emflower.list/em route name. Simple./p pFinally, we need to create the auto loader function that will be used by the emmachine_name/em form element to check whether an entity with a given machine name already exists (on the flower emadd/em form). So inside the emflower.module/em file, create this function:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #009933; font-style: italic;/** * Menu argument loader. Returns a flower entity * * @param $id * @return \Drupal\Core\Entity\EntityInterface|static *//span span style=color: #000000; font-weight: bold;function/span flower_loadspan style=color: #009900;#40;/spanspan style=color: #000088;$id/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/span span style=color: #b1b100;return/span FlowerEntityspan style=color: #339933;::/spanspan style=color: #004000;load/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$id/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span span style=color: #009900;#125;/span/pre/div pAnd don't forget to emuse/em the emFlowerEntity/em class at the top of the file:/p div class=geshifilterpre class=php geshifilter-php style=font-family:monospace;span style=color: #000000; font-weight: bold;use/span \Drupal\flower\Entity\FlowerEntityspan style=color: #339933;;/span/pre/div pAnd that should be about it. Clear the caches, make sure the module is enabled, and start poking at it. Navigate to em/admin/structure/flowers/em and create, edit, delete flower entities. Additionally, you can turn on configuration translation and translate all your entities into multiple languages. Cool, no?/p h2Conclusion/h2 pIn this tutorial we've looked at how we can create our own simple configuration entity type in Drupal 8. The emalpha13/em version (latest at the time of writing) has been used for this, so make sure that if you are using a newer one you make the necessary code adaptations if needed./p pIn Drupal 7 we do not have configuration entities and we are left with creating custom tables that hold data meant as configuration. And obviously, integration with the modest D7 entity API is practically inexistent. This all changes in Drupal 8 with the development of a robust entity API - fully integrated with the multilingual and configuration systems. Because of this, we now have exportable and translatable configuration entities used to manage more complex data that is not content./p pAnd with all these new developments, we are being introduced to a few new concepts that can scare us a bit (a href=http://www.webomelette.com/drupal-8-dependency-injection-service-container-and-all-jazzservices, dependency injection/a, a href=https://www.drupal.org/node/1637614#comment-7415530plugins/a, a href=http://drupalwatchdog.com/volume-3/issue-1/object-oriented-programming-101OOP/a and so on). However, once we get used to them a bit, they will become a friend rather than foe and open the door to more sane, performant and modern development within the Drupal framework./p /div /div

Drupal core announcements: Drupal core security release window on Wednesday, July 16

Mon, 07/14/2014 - 04:45
div class=field field-type-datestamp field-field-start7 div class=field-items div class=field-item odd div class=field-label-inline-first Start:nbsp;/div span class=date-display-single2014-07-16 (All day) America/New_York/span /div /div /div div class=field field-type-text field-field-event-type div class=field-items div class=field-item odd Sprint /div /div /div div class=field field-type-userreference field-field-organizers div class=field-labelOrganizers:nbsp;/div div class=field-items div class=field-item odd a href=/user/14705 title=View user profile.David_Rothstein/a /div /div /div pThe monthly security release window for Drupal 6 and Drupal 7 core will take place on Wednesday, July 16./p pThis does not mean that a Drupal core security release will necessarily take place on that date for either the Drupal 6 or Drupal 7 branches, only that you should prepare to look out for one (and be ready to update your Drupal sites in the event that the Drupal security team decides to make a release)./p pThere will be no bug fix release on this date; the next window for a Drupal core bug fix release is Wednesday, August 6./p pFor more information on Drupal core release windows, see the documentation on a href=http://drupal.org/documentation/version-info#whenrelease timing/a and a href=http://drupal.org/node/1173280security releases/a, and the a href=http://groups.drupal.org/node/260803discussion/a that led to this policy being implemented./p

Miles Carter: Drupal views templating tutorial: Outputting the respective image fields of multiple associated taxonomy term references

Mon, 07/14/2014 - 01:50
pCourtesy of - a href=http://www.milesjcarter.co.uk/blogMiles J Carter Photos on the Web Blog/abr/ Source URL : a href=http://www.milesjcarter.co.uk/blog/web-design-development/drupal-views-templating-tutorial-outputting-respective-image-fields-multiple-taxonomy-term-references/Drupal views templating tutorial: Outputting the respective image fields of multiple associated taxonomy term references/a br//ph1Using a custom field template to output taxonomy term references as their respective image fields, rather than as text or a link/h1 div class=wp-caption aligncenter style=width: 575pxa href=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/output.pngimg alt=output src=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/output.png width=565 height=433 //ap class=wp-caption-textThe ingredient icons are term reference fields formatted to output as their respective image fields, rather than as a link or text/p/div pThe example situation is where a view displays a list of nodes or fieldable entities, for our example items on a menu, and each of these has one or more taxonomy term references, in this example the main ingredients. While it#8217;s simple to output the term references as plain text or a link, showing an image or other field attached to the term reference instead of this presents problems./p h2Using views relationships/h2 pThe obvious solution is to create a relationship to the taxonomy in the view set up, and add the image field via the relationship. However, this currently presents issues with duplicate rows being output. If an item in the view has more than one term reference, it is displayed once for each term reference. Because of how views works, setting #8220;distinct#8221; and #8220;pure distinct#8221; in the query settings does nothing as they are technically distinct results (each has a different term reference)./p pThe a href=https://www.drupal.org/project/views_distinctviews_distinct/a module should offer a solution to this kind of problem, but a href=https://www.drupal.org/node/2158653currently/a it does not work in a way that can aggregate the required fields while filtering duplicates in this situation./p h2Creating the custom field template/h2 pIn our example view, no relationship is used and the relevant term reference field is included in the field list/p pIf you have never made a views template before, click the link #8220;Information#8221; in the Other section of the view:/p pa href=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/themeinfo.pngimg class=aligncenter size-full wp-image-633 alt=themeinfo src=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/themeinfo.png width=303 height=359 //a/p pnbsp;/p pThis displays a list of possible templates to use in customising your view for each field in the view. The template names shown are ordered from least specific to most specific #8211; the filename of the template determines which situtations it is used. The bolded template is the one currently being used. To make a new custom template, create a file in the theme#8217;s templates directory with the name. Click the link next to it to get the default code which should go into the template. In this case we wish to control output in all situations the field appears, so the first custom template option (highlighted) is that used./p pa href=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/themeinfo2.pngimg class=aligncenter size-medium wp-image-634 alt=themeinfo2 src=http://www.milesjcarter.co.uk/blog/wp-content/uploads/2014/07/themeinfo2-600x513.png width=600 height=513 //a/p pnbsp;/p pFrom the helpful comment at the top of the file, it can be seen that the contents of the view item can be found in the $row object. By debugging this object the location of the ingredients term references and their respective image fields can be found./p pIn this case the term reference field data is at:/p div class=syhi_blockcode$row-gt;field_field_ingredients/code/div pand the image field at:/p div class=syhi_blockcode$row-gt;field_field_ingredients[INDEX]['raw']['taxonomy_term']['field_image']/code/div pWhere INDEX is the array index for multiple items./p pThe a href=https://api.drupal.org/api/drupal/modules!field!field.module/function/field_view_field/7field_view_field()/a function is useful here to display the image field without needing to worry about URLs and allows control of formatting, e.g. image style presets. We also need to use an isset() condition to prevent warnings being thrown where rows don#8217;t have any term references./p pPutting this all together gives the example code:/p div class=syhi_blockcodespan style=color: #b1b100;if/spanspan style=color: #009900;#40;/spana href=http://www.php.net/issetspan style=color: #990000;isset/span/aspan style=color: #009900;#40;/spanspan style=color: #000088;$row/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;field_field_ingredients/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/spanbr / nbsp; nbsp; nbsp; nbsp; span style=color: #000088;$term/span span style=color: #339933;=/span span style=color: #000088;$row/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;field_field_ingredients/spanspan style=color: #339933;;/spanbr / br / nbsp; nbsp; nbsp; nbsp; span style=color: #b1b100;foreach/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$term/span span style=color: #b1b100;as/span span style=color: #000088;$ingredient/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#123;/spanbr / nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; span style=color: #b1b100;print/span renderspan style=color: #009900;#40;/spanfield_view_fieldspan style=color: #009900;#40;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #339933;,/span span style=color: #000088;$ingredient/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'raw'/spanspan style=color: #009900;#93;/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #009900;#93;/spanspan style=color: #339933;,/span span style=color: #0000ff;'field_image'/spanspan style=color: #339933;,/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/spanbr / nbsp; nbsp; nbsp; nbsp; span style=color: #009900;#125;/spanbr / span style=color: #009900;#125;/span/code/div pThis outputs the image, but at it#8217;s original size and with an ugly label that says #8220;Image:#8221;. To fix this, we need to use the optional fourth parameter of the field_view_field() function to control display and formatting of the field. The line inside the foreach() loop becomes:/p div class=syhi_blockcodespan style=color: #b1b100;print/span renderspan style=color: #009900;#40;/spanfield_view_fieldspan style=color: #009900;#40;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #339933;,/span span style=color: #000088;$ingredient/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'raw'/spanspan style=color: #009900;#93;/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #009900;#93;/spanspan style=color: #339933;,/span span style=color: #0000ff;'field_image'/spanspan style=color: #339933;,/span br / a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'label'/spanspan style=color: #339933;=gt;/spanspan style=color: #0000ff;'hidden'/spanspan style=color: #339933;,/span span style=color: #0000ff;'settings'/span span style=color: #339933;=gt;/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'image_style'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'thumbnail'/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/span/code/div pThis hides the label and sets the image style preset for the output to #8216;thumbnail#8217;./p pFinal code:/p div class=syhi_blockcodespan style=color: #b1b100;if/spanspan style=color: #009900;#40;/spana href=http://www.php.net/issetspan style=color: #990000;isset/span/aspan style=color: #009900;#40;/spanspan style=color: #000088;$row/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;field_field_ingredients/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/span span style=color: #009900;#123;/spanbr / nbsp; nbsp; nbsp; nbsp; span style=color: #000088;$term/span span style=color: #339933;=/span span style=color: #000088;$row/spanspan style=color: #339933;-gt;/spanspan style=color: #004000;field_field_ingredients/spanspan style=color: #339933;;/spanbr / br / nbsp; nbsp; nbsp; nbsp; span style=color: #b1b100;foreach/spanspan style=color: #009900;#40;/spanspan style=color: #000088;$term/span span style=color: #b1b100;as/span span style=color: #000088;$ingredient/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#123;/spanbr / nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; span style=color: #b1b100;print/span renderspan style=color: #009900;#40;/spanfield_view_fieldspan style=color: #009900;#40;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #339933;,/span span style=color: #000088;$ingredient/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'raw'/spanspan style=color: #009900;#93;/spanspan style=color: #009900;#91;/spanspan style=color: #0000ff;'taxonomy_term'/spanspan style=color: #009900;#93;/spanspan style=color: #339933;,/span span style=color: #0000ff;'field_image'/spanspan style=color: #339933;,/span br / nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'label'/spanspan style=color: #339933;=gt;/spanspan style=color: #0000ff;'hidden'/spanspan style=color: #339933;,/span span style=color: #0000ff;'settings'/span span style=color: #339933;=gt;/span a href=http://www.php.net/arrayspan style=color: #990000;array/span/aspan style=color: #009900;#40;/spanspan style=color: #0000ff;'image_style'/span span style=color: #339933;=gt;/span span style=color: #0000ff;'thumbnail'/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #009900;#41;/spanspan style=color: #339933;;/spanbr / nbsp; nbsp; nbsp; nbsp; span style=color: #009900;#125;/spanbr / span style=color: #009900;#125;/span/code/div pSource - a href=http://www.milesjcarter.co.uk/blogMiles J Carter Photos on the Web Blog/abr/ Read the Original Article : a href=http://www.milesjcarter.co.uk/blog/web-design-development/drupal-views-templating-tutorial-outputting-respective-image-fields-multiple-taxonomy-term-references/Drupal views templating tutorial: Outputting the respective image fields of multiple associated taxonomy term references/a br//p

PreviousNext: Writing a custom Drupal Search API processor

Mon, 07/14/2014 - 01:07
div class=field field-name-field-summary field-type-text-long field-label-hiddendiv class=field-itemsdiv class=field-item even pWhen working with the Search API Drupal module, sometimes we need to programmatically add information that is not available for indexing as a field. Lucky we can write our own custom pre-processor to provide this information to the index./p /div/div/divspan property=dc:title content=Writing a custom Drupal Search API processor class=rdf-meta/span

Gizra.com: Headless Drupal - Inline edit

Sun, 07/13/2014 - 23:00
pIn our a href=http://www.gizra.com/content/restful-angular-forms/last example/a we showed how to create node using an angular form served from Drupal itself. This time we are taking one big step further and create the node from a completely decoupled a href=https://github.com/Gizra/angular-drupal-forms-exampleweb app/a.br And if that#39;s not enough for the readers excited by the idea of a decoupled Drupal, we#39;ve also added inline editing to the example!/p pEnjoy the a href=http://gizra.github.io/angular-drupal-forms-example/#/live demo/a/p div class=thumbnail img src=http://www.gizra.com/assets/images/posts/headless-drupal-inline-edit/image1.gif / div class=captionIf you know Form API's pains, you should be excited now/div /div pa href=http://www.gizra.com/content/headless-drupal-inline-edit/Continue reading…/a/p

Freelock : I've got a theory: The Scientific Method applied to web site performance

Sun, 07/13/2014 - 18:10
div class=g-plusone-wrapper style=margin: 0 1em 1em 1em;float:right g:plusone href=http://www.freelock.com/blog/john-locke/2014-07/ive-got-theory-scientific-method-applied-web-site-performance size=medium annotation=bubble width=250 /g:plusone/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpWhat can you do about this page being so slow? That's a question we've been asked by half a dozen customers in the past 6 months, and as it turns out, we can do quite a lot./p pOne of my long-standing complaints about Drupal is a href=/blog/john-locke/2011-10/top-6-reasons-drupal-really-sucks-developer-editionthat it's a resource hog/a. That's an issue we can generally help by throwing lots of hardware and caching systems at the problem -- but that's not the kind of performance issue these clients were having./p/div/div/divdiv class=field field-name-taxonomy-vocabulary-5 field-type-taxonomy-term-reference field-label-hiddendiv class=field-itemsdiv class=field-item evena href=/tag/performancePerformance/a/divdiv class=field-item odda href=/tag/scalingScaling/a/divdiv class=field-item evena href=/tag/monitoringMonitoring/a/divdiv class=field-item odda href=/tag/drupalDrupal/a/divdiv class=field-item evena href=/tag/drupal-planetDrupal Planet/a/divdiv class=field-item odda href=/tag/technicalTechnical/a/div/div/div

Mediacurrent: The Power of Giving

Fri, 07/11/2014 - 22:00
img typeof=foaf:Image src=http://www.mediacurrent.com/sites/default/files/styles/thumb_blog_spotlight/public/value-of-giving-v1.1.png?itok=89fY3fOa width=200 height=152 alt=The Power of Giving in the Drupal Community title=The Power of Giving in the Drupal Community / pSeveral years ago, a mentor told me to add computer tech services to my web design company’s services because “everyone’s a web designer.” His point: there’s a lot of competition in the web design and development market. With so much competition, why would web development shops like Mediacurrent place so much value in sharing industry knowledge and even custom code for free with the Drupal community? Why is it worthwhile for a for-profit company to share knowledge to a community that includes competitors?/p

Midwestern Mac, LLC: Multi-value spatial search with Solr 4.x and Drupal 7

Fri, 07/11/2014 - 21:59
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpFor some time, Solr 3.x and Drupal 7 have been able to do geospatial search (using the location module, geofield, or other modules that stored latitude and longitude coordinates in Drupal that could be indexed by Apache Solr). Life was good—as long as you only had one location per node!/p pSometimes, you may have a node (say a product, or a personality) affiliated with multiple locations. Perhaps you have a hammer that's available in three of your company's stores, or a speaker who is available to speak in two locations. When solr 3.x and Drupal 7 encountered this situation, you would either use a single location value in the index (so the second, third, etc. fields weren't indexed or searched), or if you put multiple values into solr's search index using the codeLatLonType/code, solr could throw out unexpected results (sometimes combining the closest latitude and closest longitude to a given point, meaning you get strange search results)./p/div/div/div

Joachim's blog: The ripple effect

Fri, 07/11/2014 - 21:21
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpHello! I'm back. I've not made any blog posts in over a year and a half due to the site where my blog was before, drupaler.co.uk, closing down. And while it took me some time to get round to writing a Migrate script to import my posts from the old site's database, it was actually getting round to setting up this new domain that took the longest./p pSo what have I been doing all this time? Especially as I still don't have a single Drupal 7 site out there to my name? Well, these days I work on a humongous web application which has kept me busy for the last 18 months; it's a large Drupal site (we hit a million of one of its several custom entity types recently), but to the general public it's just a login page. I may talk more about the development challenges in future posts. /p pPrior to that, I was building what would have been one of the earliest big Drupal Commerce sites to launch... except that very shortly before launch in October 2012, the whole project got canned./p/div/div/divdiv class=field field-name-field-tags field-type-taxonomy-term-reference field-label-inline clearfixdiv class=field-labelTags:nbsp;/divdiv class=field-itemsdiv class=field-item even rel=dc:subjecta href=/taxonomy/term/52 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=contributing code/a/divdiv class=field-item odd rel=dc:subjecta href=/taxonomy/term/41 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal commerce/a/divdiv class=field-item even rel=dc:subjecta href=/taxonomy/term/3 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=development/a/divdiv class=field-item odd rel=dc:subjecta href=/taxonomy/term/53 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=maintaining projects/a/div/div/div

Lullabot: Front-end Rapport #3

Fri, 07/11/2014 - 20:00
h2a id=toc-currenttrends-in-browser-market-share class=anchor/aa href=http://arstechnica.com/information-technology/2014/07/windows-8-x-internet-explorer-both-flatline-in-june/ title=Current Trends in Browser Market Share on arstechnicaCurrent Trends in Browser Market Share/a/h2 pTopics: Browsers/p pArstechnica does a visual deep-dive into browser market shares through multiple charts and graphs — breaking down worldwide browser trends and adoption rates./p

Aten Design Group: Design4Drupal 2014

Fri, 07/11/2014 - 18:33
img src=http://atendesigngroup.com/sites/default/files/d4d2014.jpg width=1000 height=562 alt= /pa href=http://boston2014.design4drupal.orgDesign4Drupal 2014/a is almost here, and Aten couldn't be more excited. This year, along with being the Design Partner for the event, members of Aten's Design amp; UX team will be presenting four different sessions./p pThis year's Design4Drupal (August 1-3) has been structured to give each day a specific focus. Friday kicks things off with a business summit, Saturday is chock full of sessions and Sunday wraps things up with sprints and trainings. Make sure you catch as many of Aten's sessions on Saturday as you can:/p h2Saturday, August 2, 10:15am/h2 h3a href=http://boston2014.design4drupal.org/session/enhancing-design-adaptive-contentEnhancing Design with Adaptive Content/a/h3 pAten’s a href=http://atendesigngroup.com/about/joel-steidlJoel Steidl/a, Lead Architect, and a href=http://atendesigngroup.com/about/chris-coughlanChristine Coughlan/a, Information Architect, will share practical tips for breaking down and organizing content for projects of any size. They’ll share case studies to reinforce the theory and practice behind adaptive content and best practices for implementing it in Drupal and other platforms./p h3a href=http://boston2014.design4drupal.org/session/layout-design-patternsLayout Design Patterns/a/h3 pa href=http://atendesigngroup.com/about/john-ferrisJohn Ferris/a, Aten's Lead Front-end Developer, presents reusable solutions to common layout problems. He'll begin with foundation CSS layout concepts and then build up to specific techniques for implementing complex layouts in Drupal./p h2Saturday, August 2, 2:15pm/h2 h3a href=http://boston2014.design4drupal.org/session/anti-handoff-better-design-front-end-relationshipAnti-Handoff: A better design amp; front-end relationship/a/h3 pFront-end Developers delivering on what's promised by Designers can make or break a project. a href=http://atendesigngroup.com/about/erin-hollowayErin Holloway/a, Aten's Senior Designer, will walk through approaching this problem with clear communication, the right tools and mutual respect. If you're struggling with collaboration between your team members, this session can help./p h2Saturday, August 2, 3:30pm/h2 h3a href=http://boston2014.design4drupal.org/session/giving-and-getting-great-feedbackGiving and Getting Great Feedback/a/h3 pGreat feedback can be the lifeblood of a successful project. However, setting aside personal preference and giving objective feedback can be challenging. Responding to that feedback can be even harder. Aten’s Designer, a href=http://atendesigngroup.com/about/roxy-korandaRoxy Koranda/a, will give you the tools to both give and get great feedback./p pWith just 3 weeks until the event, there isn't a ton of time left to a href=https://www.eventbrite.com/e/design-4-drupal-boston-2014-dc-2716-tickets-8093037493register/a. If you use Drupal and want to learn more about how best to approach Design, UX and Front-end Development, Design4Drupal is the place to be. We hope to see you there!/p

Acquia: Brant Wynn: Demo Framework – How we pitch Drupal to potential clients

Fri, 07/11/2014 - 15:52
div class=field field-name-body field-type-text-with-summary field-label-hidden div class=field-items div property=content:encoded class=field-item evenpa href=/about-us/team/brant-wynnBrant Wynn/a, Acquia Solutions Architect, and I covered some interesting ground in our conversation preceding his a href=/jams-drupal-campjam's Drupal Camp/a session on selling Drupal to potential clients via beautiful, out-of-the-box demos. Listen to hear about working as a professional open source software developer, the potential wins from having migration tools built into Drupal 8, how Drupal 8 is bringing so many open source technologies and communities together, and more./p /div /div /div span property=dc:title content=Brant Wynn: Demo Framework – How we pitch Drupal to potential clients class=rdf-meta/span

Code Karate: Drupal 7 Mobile Friendly Navigation Toolbar module

Fri, 07/11/2014 - 13:12
div class=field field-name-field-ddod-video field-type-file field-label-hiddendiv class=field-itemsdiv class=field-item evenimg src=http://codekarate.com/sites/default/files/styles/large/public/media-youtube/0kjWmef2Rpg.jpg?itok=xEfx582L alt=Drupal 7 Mobile Friendly Navigation Toolbar - Daily Dose of Drupal Episode 157 //div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpThe a href=https://www.drupal.org/project/navbar rel=nofollowMobile Friendly Navigation Toolbar/a is a replacement for the standard administration toolbar that comes with Drupal 7./p/div/div/div

DrupalCon Amsterdam: Inside Drupalcon Amsterdam Frontend Session Selection

Fri, 07/11/2014 - 08:21
div class=field field--name-body field--type-text-with-summary field--label-hiddendiv class=field__itemsdiv class=field__item evenpAfter attending and helping to organize several Drupal events in Europe I have met a lot people and also had the chance to listen to many good speakers. I am also an usual speaker in DrupalCamps. That brought me enough experience to know when a session was interesting for the audience and feedback from attendees and organizers helps improve my sessions in the future./p pIt’s important for the speaker to know how to engage and entertain attendees. People will learn more and will be more satisfied if the session is dynamic and, why not, funny./p pA few weeks ago I had the opportunity to collaborate, together with a href=https://www.drupal.org/u/lewisnyman target=_blankLewis Nyman/a, in the Frontend track session selection for DrupalCon Amsterdam. I have never spoken in a DrupalCon so it was a good chance to learn from the best./p pOur role was to help guide those who proposed a session by better aligning proposals with the a href=//amsterdam2014.drupal.org/tracks#frontend” target=_blanksuggested topics/a. That was a really good experience because I had to contact speakers I met in previous conferences and others I wanted to meet but we didn’t coincide in any event. Also we tried to invite speakers from other communities to spread the word of Drupal in other horizons and also to have opportunity to learn from professionals that are working in different projects and environments than those we use to know./p pThe response was impressive: we had more than 50 proposed sessions only in our track, for a total of a href=https://amsterdam2014.drupal.org/news/amsterdam-session-submissions-overview target=_blankmore than 500 submissions/a overall. That’s a really big number taking into account that the topics were related to theming and design and because we have other tracks that cover development and site-building topics. Sometimes we had to move sessions from one track to another because it was difficult to decide which track the session fit best in./p pSession topics were diverse but fit well with our needs, what made it really hard to decide between them. We had a limited amount of sessions to accept so Lewis and I tried to estimate different factors in the valuation process. We took into account previous speaking experience, using speaker profiles and videos or slides from previous sessions in other events./p pA session's description was one of the most important factors to evaluate. Tip for prospective speakers: you should be really careful with your session description if you decide someday to speak in any conference. We contacted a few speakers prior to and during session selection to suggest slight variations on their session content so they can fit better with track topics or differ from other proposed sessions./p pWe tried to have a diverse Frontend track with interesting sessions, not only for front-end developers but also for UX designers, site builders, graphic designers… and not only Drupal people will be interested in them. I think anyone dedicated to web will enjoy and learn new techniques and tools used by well-known professionals in high-end projects./p pYou can imagine all the amount of time invested to prepare and coach speakers and also to plan and organize. We meet weekly as a team to comment, discuss and make decisions (also have a good time with Drupal fellows). It was a really enjoyable opportunity for me to gain more experience organizing Drupal events./p p--br / Ruben Teijeiro (a href=https://www.drupal.org/user/780508 target=_blankrteijeiro/a)br / DrupalCon Amsterdam Frontend Co-Chair/p /div/div/div

godel.com.au: Ideas to help keep your Drupal project secure against the OWASP Top 10

Fri, 07/11/2014 - 07:24
div class=field-blog-header-image-display div class=blog-header-image-inner data-image-url=https://www.godel.com.au/sites/default/files/styles/darken_and_desaturated/public/8329988064_46b2eba8e8_z.jpg?itok=1_Jv9Za6/div /div div class=field-post-date Fri July 11, 2014 /div div class=field-title h2Ideas to help keep your Drupal project secure against the OWASP Top 10/h2 /div div class=field-body pI'm sure you've heard the phrase Security is a process, not a product before, or something along those lines. Drupal has a pretty good track record as far as Web-based CMS security goes, and there's a dedicated team of experts looking after Core and Contrib, but it's no secret that the most common vulnerabilities are those we accidentally introduce ourselves during our day-to-day tweaking (Drupal.org a href=https://www.drupal.org/documentation/is-drupal-secureclaims over 90%/a). The a href=http://drupalsecurityreport.org/sites/g/files/g598426/f/201403/drupal-security-whitepaper-1-3.pdfDrupal Security White Paper/a shows pretty clearly that the further we get away from the heavily peer-reviewed Core codebase, the more likely we are to unwittingly introduce something that's dangerous to our data./p pIn the case of what processes we can implement as individuals, self education and reflection is always important, so I figured that the present is as good a time as any to run through the a href=https://www.owasp.org/index.php/Top_10_2013-Top_10OWASP Top 10/a and present a few practical ideas and Drupal Best Practices to help mitigate the risks we inevitably expose ourselves to. I've added some quotes from the white paper to each section to put things into perspective./p h2#1 - Injection/h2 blockquotepDrupal contains a robust object-oriented database a title=An Application Programming Interface (API) specifies how software components should interact with each other. An API usually specifies a set of functions or routines that accomplish a specific task or allow an interaction. A good API makes it easier to develop a program by providing all the building blocks. A programmer then puts the blocks together.APIs are provided by existing programs to facilitate interactions between programs. For example, programmers can use the Twitter API to pull in a feed of tweets based on hashtag to a site. class=glossify-link href=/content/apiAPIimg src=/sites/all/themes/custom/gt/glossify.png class=glossify-img //a that makes it difficult for developers to unknowingly create injection holes by automatically sanitizing query parameters and enforcing an interface. Drupal's file system interaction layer limits where files can be written and alters dangerous file extensions that the server could potentially execute./p /blockquote pIn Drupal, injection attacks are generally going to be enabled by allowing a href=http://en.wikipedia.org/wiki/SQL_injectionunsafe data to sneak into SQL queries/a. In Drupal 7 we have two syntaxes for working with the a href=https://www.drupal.org/developing/api/databasedatabase API/a, the classic Drupal 6 style codedb_query(SELECT * FROM foo f WHERE bar = 'baz');/code and the dynamic DBTNG style codedb_select('foo', 'f')-gt;condition('bar', 'baz' , '=');/code./p pFor both syntaxes, there are two things I think are worth mentioning:/p h3Make use of PHP's PDO and Prepared Statements/h3 pDrupal's database API wraps PHP's own a href=http://php.net/manual/en/book.pdo.phpPDO/a, which supports something called a href=http://php.net/manual/en/pdo.prepared-statements.phpPrepared Statements/a that magically guarantee you won't suffer from an injection attack emprovided you actually use the API correctly/em./p pSo, if you're wondering how to use the API correctly, let's split all SQL queries we might want to use into two categories, those that could be considered hardcoded strings, and those that have one or more variable components. The examples above would be hard coded, an example of something with variable components might look like this:/p pcode// Get the type of the node with the ID of the second URL component.br / // WARNING: Don't actually do this! it is NOT secure.br / $id = arg(1);br / $query = db_query(SELECT type FROM node n WHERE n.nid = . $id);/code/p pThe issue here is that, unlike our hardcoded query, the value of code$id/code can be set to anything at all by the end-user, most notably including strings that resemble fragments of SQL queries. We really don't want the end-user to discover one day that they can start executing their own queries against our database by carefully crafting URL components to exploit our PHP logic./p pHere the fix is to either use PDO placeholders using Drupal's classic syntax, or leverage Drupal's internal query builder with the dynamic syntax. The following two examples (one for each syntax) are secure versions of the previous insecure example:/p pDrupal 6 syntax:/p precode// Get the type of the node with the ID of the second URL component. // The important part here is that the second argument passed to db_query() // is an array of substitutions that will be sanitized internally. $id = arg(1); $query = db_query(SELECT type FROM node n WHERE n.nid = :nid, array(':nid' =gt; $id)); /code/prepDrupal 7 syntax:/p precode// Get the type of the node with the ID of the second URL component. // The important part here is that we use the dynamic query builder to handle // the unsafe $id variable. $id = arg(1); $select = db_select('node', 'n') -gt;condition('n.nid', $id, '=') -gt;fields('n', array('type')); /code/prepThe question now is, how do we know when a variable is unsafe?/p pThe answer should really be, treat all variables as though they are unsafe by default and stop guessing. Be in the habit of using the more secure syntax by default, even when it is not strictly neccessary. This both reduces the risk of some edge-case creeping up on you that you hadn't considered, and makes your code more portable/standardised at the same time./p h3Make use of whitelists for tables/fields/operators/h3 pI think maybe this one is less obvious to many people than making use of PDO, but it is also important to consider./p pAs mentioned in a a href=https://www.drupal.org/node/1776016bunch/a a href=https://www.drupal.org/node/829464of/a a href=https://www.drupal.org/node/2186291core/a a href=https://www.drupal.org/node/1426084issues/a, and a href=http://www.pixelite.co.nz/article/sql-injection-and-drupal-7-top-1-10-owasp-security-riskselsewhere/a (read the comments) Drupal emdoesn't/em actually escape/sanitize emeverything/em that you pass the database API. The reason that those issues are still open and not flagged as critical fix me NOW ZOMG (In part), is because certain parts of our SQL queries are fundamentally unsafe to use user data for, even if they were being escaped by the system./p pImagine a query (presumably hooked up to a radio button or select element) like the following:/p precode// Return the current user's username or email address to be displayed. // WARNING: Don't actually do this! it is NOT secure. global $user; $field_name = $form_state['values']['field']; $select = db_select('users', 'u') -gt;condition('u.uid', $user-gt;uid, '=') -gt;fields('u', array($field_name)); /code/prepIn this case, the end-user can hack up the form you presented them however they like and submit something for the codefield/code form value like password to get a dump of what is stored in the password field for the current user account. It's not hard to imagine other, even more damaging scenarios./p pSince Drupal knows that it is fundamentally insecure to be directly using user data for some things (e.g. table names, fields, operators in codecondition()/code and codeorderBy()/code) and emassumes/em that you'll emdefinitely/em be using whitelisted values emonly/em in these cases. There may well be a de-prioritised, outstanding Core bug that means your emvariables are not being sanitised/escaped at all/em, despite the fact that you're using the query builder. This means that, as well as the end-user getting at your user's passwords when you thought they could only see email addresses, they may also have a way to directly attempt an injection attack on your database./p pThe fix here is, make use of whitelists wherever you're dealing with variables for finite, pre-determined lists of valid options (like field names). For example, the above could be rewritten to be more secure like this:/p precode// Return the current user's username or email address to be displayed. global $user; // Return the username by default. $field_name = 'username'; // Ony allow field names in our whitelist. $allowed_fields = array('username', 'mail'); if (in_array($allowed_fields, $form_state['values']['field'])) { $field_name = $form_state['values']['field']; } $select = db_select('users', 'u') -gt;condition('u.uid', $user-gt;uid, '=') -gt;fields('u', array($field_name)); /code/preh2#2 - Broken authentication and session management/h2 blockquotepUser accounts and authentication are managed by Drupal core. Authentication cookies and a user's name, ID, and password are managed on the server to prevent a user from easily escalating authorization. User passwords are salted and hashed using an algorithm based on the Portable PHP Password Hashing Framework and existing sessions are destroyed upon login and logout./p /blockquote pDrupal handles this well out of the box and most developers will be rarely doing anything that would break it. According to the white paper, there are very few Security Advisories being issued in this category, so I won't dwell on this./p h2#3 - Cross site scripting (XSS)/h2 blockquotepDrupal has a strong system for filtering user-generated content on display. Untrusted user's content is filtered to remove dangerous elements by default. For developers, Drupal has at least eight API functions for filtering output to prevent XSS attacks. When identified, common developer errors that lead to XSS vulnerabilities are mitigated by building safer defaults. For example, a page title function in Drupal 6 is the source of many XSS holes due to a lack of proper escaping. In Drupal 7 this function escapes output by default./p /blockquote pHmmm, I think the words by default mean something different to the authors of the white paper than they do to me. If you do emanything/em in the Drupal theme layer, and you don't explicitly, manually sanitise every single one of your variables as you render them, you have XSS holes in your theme./p pIn Drupal 8, there's a href=https://www.drupal.org/node/1825952a critical issue/a to try and get automatic escaping of markup into core by using the a href=http://twig.sensiolabs.org/Twig/a rendering system which should dramatically increase security (in line with my intuitive definition of by default) and improve performance as a nice bonus. That issue attempts to summarise the situation:/p blockquotepNo-one can write XSS safe code. Nor core contributors, nor contrib developers, no-one./p /blockquote pand from a a href=https://www.drupal.org/node/1712444duplicate issue/a:/p blockquotep100% of all custom themes are insecure (the rest is rounding error). The reason is often that developers forget to escape their data in the templates./p /blockquote pBy the white paper's own reported statistics, over 50% of reported security vulnerabilities in Drupal core and contributed community code are XSS issues./p pIn light of all this, between now and when Drupal 8 auto-escaping is released, even if you learn nothing else about Drupal security, you'll want to become familiar with a few of the API functions provided for a href=https://api.drupal.org/api/drupal/includes!common.inc/group/sanitization/7string sanitisation/a./p pFor reference, the full list on api.drupal.org is:/p ullia href=https://api.drupal.org/api/drupal/modules%21filter%21filter.module/function/check_markup/7check_markup()/a/li lia href=https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/check_plain/7check_plain()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/check_url/7check_url()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_attributes/7drupal_attributes()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_strip_dangerous_protocols/7drupal_strip_dangerous_protocols()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/filter_xss/7filter_xss()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/filter_xss_admin/7filter_xss_admin()/a/li lia href=https://api.drupal.org/api/drupal/includes%21common.inc/function/filter_xss_bad_protocol/7filter_xss_bad_protocol()/a/li lia href=https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/format_string/7format_string()/a/li lia href=https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/get_t/7get_t()/a/li lia href=https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/get_t/7st()/a/li lia href=https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/t/7t()/a/li /ulpRead up on all of the sanitisation functions, but the most commonly used (for general theming) are probably:/p h3check_plain()/h3 pUse this when you have a string that is NOT supposed to be HTML, but you want to display it in an HTML context. It's really just a wrapper around codehtmlspecialchars()/code. Any characters in your non-HTML string that might be interpreted as HTML by the browser are converted into HTML entities so that they render as you would expect them to in a non-HTML context./p pThis means that your string that looks like codeX lt; Y amp; Y gt; Z/code becomes codeX amp;lt; Y amp;amp; Y amp;gt; Z/code./p pA couple of things to keep in mind with this function:/p olliIt's possible to accidentally double encode characters so that codeamp;amp;/code becomes codeamp;amp;amp;/code, which looks really bad when rendered. It is NOT a good idea to run codecheck_plain()/code over everything without thinking, in case you run it on a string that has already had codecheck_plain()/code run on it earlier./li liWhile codecheck_plain()/code is an important function for security, defusing characters that could be interpreted as HTML, it's primary usage is for encoding/decoding characters, NOT guaranteeing that strings are HTML safe by stripping dangerous markup. For example, it's possible that a substring of a string that was previously run through codecheck_plain()/code will have its encoding corrupted if an HTML entity is truncated before the closing code;/code./li /olh3check_markup()/h3 pUse this to apply input filters to a string that is intended to be used emas/em HTML. In this case, we DO want HTML to be interpreted by the browser, but we also want to be careful not to open ourselves up to codelt;scriptgt;/code elements or similar being executed maliciously. In the simplest usage, this function takes two arguments - the string and the machine name of the filter format to apply./p pFilter formats themselves are an important part of core and too detailed a subject for me to go into here. Suffice to say that the out of the box formats set the tone for most custom filters created by developers:/p ollicodeplain_text/code - Behaves as codecheck_plain()/code does./li licodefiltered_html/code - Will strip any (customisable) HTML tags considered dangerous and leave the rest intact/li licodefull_html/code - Will render any and all HTML tags in the string, even if they might be dangerous. (ab)Using this causes developers to grumble./li /olpAvoid using the PHP input filter completely if you care at all about mitigating security risks./p h3t() and/or format_string()/h3 pUse this in situations where you want to perform simple string substitutions with variables (that might come from end-users data) and, in the case of codet()/code also allow for the string to be translatable into other languages./p pSince codet()/code wraps codeformat_string()/code, I encourage you to use the former as they behave the same way and you get the translatability for free./p pThe advantage of using placeholders in strings, rather than concatenating variables, is twofold, codeformat_string()/code will automatically apply codecheck_plain()/code to substitutions that do NOT begin with code!/code and it makes the strings easier to contextualise for translaters./p precode// Here the translators can see a whole sentence and use the placeholders as clues. // We don't have to call check_plain() repeatedly because we're using @placeholder syntax. t('Yesterday I went to @place and brought home a @thing', array( '@place` =gt; 'the park', '@thing' =gt; 'frisbee', )); // Here translators only see two disjointed strings separately: // 'Yesterday I went to' and 'and brought home a'. t('Yesterday I went to ' . check_plain($place) . 'and brought home a ' . check_plain($thing)); /code/preh2#4 - Insecure direct object references/h2 blockquotepDrupal often provides direct object reference, such as unique numeric identifiers of user accounts or content available in the URL or form fields. While these identifiers disclose direct system information, Drupal's rich permissions and access control system prevent unauthorized requests. Methods for obfuscation are available through configuration and community-contributed code. Further, validation and protection against semantic forgery attacks is implemented in Drupal core via the Form API./p /blockquote pFor Drupal, this largely comes down to making sure you have your server environment and Drupal site configured in a way that makes sense for your project, in the context of Drupal, I'm going to tie this into.../p h2#5 - Security misconfiguration/h2 blockquotepMany critical risks, such as access to administrative site controls, text formats, and private information are restricted to a single admin account by default. Identified design inefficiencies that lead to misconfiguration are corrected often through usability testing and fixes are recommended for inclusion to core. Documentation of best practices for secure configuration and site building are provided for free on drupal.org and there are several contributed projects that conduct automated security review or implement further secure configurations./p /blockquote pIn my experience, the two fastest ways to end up with hundreds of spambot accounts (or worse) on your account are:/p olliServers configured in a way that is not Drupal friendly, lazily or by someone who isn't an experienced sysadmin./li liDevelopers building functionality as Drupal user 1 and never logging out or logging in as a user with a different role to test it./li /olpFor the first point. If you are not a sysadmin, you don't directly employ a sysadmin, or you don't have a friend who is a sysadmin who owes you a series of large favours, it is going to be much, much cheaper and less headache inducing to sign up with a href=https://www.acquia.com/Acquia/a or a href=https://www.getpantheon.com/Pantheon/a than to mess around with a shared hosting provider or to try and configure and maintain your own VM./p pFor the second point, the Drupal permissions grid is huge and tedious to manage as it involves a lot of user switching but there are a few things you can do for yourself to make maintaining complex permission sets easier./p h3Implement a simple, repeatable testing plan/h3 pIn the Drupal community, a href=https://www.drupal.org/simpletestSimpleTest/a and a href=http://behat.org/Behat/a are very popular testing tools. Both support simple assertions for the HTTP response code and the existence/absences of HTML elements on a rendered page. In fact, automated tests to check that a given user has permission to do something or visit certain pages are some of the easiest to write and can help you avoid those awkward conversations where we have to explain to someone that there was a regression in the site's fundamental security configuration./p pEven if you don't have the time or resources to set up automated tests for a project, make step-by-step notes of critical functionality and user roles that can be tested as part of QA each release./p pIf you're using drush, you can generate a one time login for any user in the system with codeuli/code and their username:/p pcode$ drush @mysite.alias uli 'John Smith'/code/p h3Have a deployment plan/h3 pPeople who don't know how to use the Drupal permissions grid just love to make changes to it, then immediately forget what changes they made, or tell anyone that they made the changes. That is, if you let them./p pAt the very minimum, you should be exporting your permissions into a href=https://www.drupal.org/project/featuresFeatures/a so that, should anything go wrong, you have some kind of oh shit button to get things back to working order, fast (without rolling back your database)./p pThe Features approach is a little limiting for Permissions management though:/p ulliThe permissions aren't actually locked. It's relatively easy for a permission to be changed on production and it won't be restored to the correct value until the Feature is next reverted./li liIt's not easy to toggle permissions on/off for different development environments. For most permissions you aren't going to want to do this anyway, but for those that you do, you really don't want the wrong permissions in the wrong environment./li liThere are a very large number of Permissions, and exporting them all to a Feature quickly bloats the Feature code and UI./li liAdding a permission to a Feature artificially introduces a dependency of the Feature on that a title=Drupal is a Content Management System that is built on modules - different packages of code that provide different functionalities. Because not all websites are the same, different modules are created and installed to allow websites to perform different tasks. Each Drupal-based website is made up of a series of different modules.Modules increase Drupal's functionality and provide services such as:image galleriescustom content types and content listingsWYSIWYG editorsprivate messagingthird-party integration toolsupdating functionalitye-commerce solutionsand much, much more: as of August 2011 the Drupal website lists over 11,000 free modules. You can explore and search a list of Drupal modules here.Drupal uses modules because they allow the many volunteer developers who create Drupal to work in groups on small projects simultaneously.Each module is designed by a volunteer developer and is developed by a team of other volunteer developers who find bugs and suggest features by using and testing development versions of the modules.Modules help solve problems for website creators by providing specific functionalities while still being open source. To an extent, modules can be altered by developers if their exact use is not perfect for the website.Contrib modules amp; legalitiesAs Drupal is open-source, the licensing and legal considerations are a bit different to proprietary software. You can read them in full here.1: What is the license for Drupal?Drupal and all contributed files hosted on Drupal.org are licensed under the GNU General Public License, version 2 or later. That means you are free to download, reuse, modify, and distribute any files hosted in Drupal.org's Git repositories under the terms of either the GPL version 2 or version 3, and to run Drupal in combination with any code with any license that is compatible with either versions 2 or 3, such as the Affero General Public License (AGPL) version 3.All modules or themes written for Drupal have to licensed under the GPL. The GPL applies to code, but not data - thus your website itself and the data on it is still yours, while any modules used to create your website aren't yours.Any modules or themes written for Drupal must be distributed with their source code so that the user can modify it if they need or want to.Viewing the website is not considered 'distributing' so the source code for your website does not have to be available to anyone who visits it.Because Drupal is licensed free of charge, there is no warranty for it. Importantly, from the GPL itself, Drupal and its distributors (developers) are not liable for damages based on the program itself:12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.Custom modulesFor specific functionality, Godel may need to create a custom module which may be more expensive than using contributed modules, but can be very rewarding.If you are looking to implement some kind of specific functionality in to your website, feel free to browse the relevant modules and see how that functionality has been achieved by others in order to better understand the process behind realising your idea online before you decide to commission Godel to create a custom module for you.Custom modules and patches for existing modules may be uploaded to the Drupal community if they may be useful to other users. This will not affect the way the module functions on your site.Sometimes you can access the functionality you require in a different Release version of the module in question. Sometimes this requires using a beta release or even a previous release of the module. class=glossify-link href=/content/modulemoduleimg src=/sites/all/themes/custom/gt/glossify.png class=glossify-img //a./li liExporting permissions to Features is a tedious and error-prone manual process./li liPermissions exported in Features are not very portable between projects./li liThe generated code in Features is difficult to read over quickly./li liIt's relatively difficult to manage permissions across multiple domains if you have a multisite setup./li /ulpThere are various contrib modules that aim to make permissions management more secure and development friendly, to name a few:/p ullia href=https://www.drupal.org/project/saferpermissionsSafer Permissions/a - Acquia Sponsored./li lia href=https://www.drupal.org/project/permissions_variablePermissions Variable/a - Disclaimer: I wrote this one./li lia href=https://www.drupal.org/project/secure_permissionsSecure Permissions/a/li /ulpAdditionally, you might want to consider making permissions management part of your deploy/build scripts if you use such things to manage your environments./p h2#6 - Sensitive data exposure/h2 blockquotepAccount passwords are salted and repeatedly hashed based on the Portable PHP Password Hashing Framework. Available Drupal community-contributed code offer solutions to encrypt sensitive data at rest or in transit./p /blockquote pThis depends a lot on what your employer/client/government considers sensitive data. Where I live, in Australia, the government has published a convenient set of guidelides around sensitive and private data that can be used to gauge the level of risk if data were to be exposed. If you don't have any in your site, well that's great - although I still recommend implementing codehook_menu()/code to unset the default codenode/code menu path if you haven't already, as it shows every node in the site by default, which can be awkward./p pIf you're working with Ubercart or Commerce, please, please triple check whether your payment gateway integration module sends user's credit card data through the Drupal Form API, to your server, before sending it to the payment gateway provider. This goes double (so sextuple check) for anything that claims to store credit card data for later use, even if it is tokenized. If sensitive credit card (or similar) data touches your server even for a moment, you might be exposing yourself to fines if you haven't taken appropriate steps (a href=http://drupalpcicompliance.org/PCI-DSS/a) to ensure encryption and security./p pIf you work with Drush, and multiple environments, you might want to consider implementing codehook_drush_sql_sync_sanitize()/code for your project. This allows you to scrub out sensitive data from your production database as you pull it down, so that you don't accidently lose it to someone shady along with your laptop or not-so-trustworthy contractor. You don't need to use drush for this, there are lots of ways, including a simple shell script with SQL queries, to setup a decent database scrubbing script. Acquia have some a href=https://docs.acquia.com/articles/scrubbing-drupal-database-environmentdocumented examples/a of how to achieve this too, if you're interested./p h2#7 - Missing function level access control/h2 blockquotepFunction level access in Drupal is protected by a powerful permissions-based system which checks for proper authorization before the action is taken. For the case of URL access, access checking is tightly integrated into the entire menu-rendering and routing system which means that visibility of navigation links and pages are protected by the same system that handles incoming requests./p /blockquote pYes, menu-rendering uses access checking to ensure that navigation links are protected, but links generated by codel()/code or code#type =gt; 'link'/code render arrays do not automatically run access checks. Function (and URL) level access control is very easy to implement in Drupal using codehook_permission()/code, codehook_menu()/code and codeuser_access()/code. Creating new, custom permissions is very straightforward but it's also very easy to get wrong in subtle ways (especially if you're writing some new function that wraps another function with existing access checks) - as I mentioned above, make sure you have a solid testing plan in place for your new permissions scheme before you deploy it!/p h2#8 - Cross-Site request forgery/h2 blockquotepDrupal validates user intention in actions using industry standard techniques. Typical actions with side- effects (such as actions that delete database objects) are generally conducted with the HTTP POST method. Drupal's Form API implements unique form tokens to protect against CSRF in POST requests. Less important actions can leverage the one-time token generation and validation functions of the Form API while still using an HTTP GET request./p /blockquote pReviewing the security white paper, we can see that there's a relatively large incidence of contributed, non-core code that is not correctly implementing the a href=https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7Drupal Form API/a, leading to CSRF exploits./p pAvoiding CSRF exploits in Drupal is relatively easy if you follow three simple rules:/p olliWhenever you expose an action to an end-user that modifies data in your site, implement it using a form (codePOST/code) rather than a link + menu callback (codeGET/code)./li liNever try to build an HTML form manually, always use renderable form arrays and the Form API./li liAlways use form validate/submit handlers and code$form_state/code to access user submitted values rather than trying to extract information from code$_POST/code directly./li /olpIf you need to quickly convert some GET based code you suspect might be at-risk to POST requests, the a href=https://www.drupal.org/node/178896Drupal documentation/a suggests converting the page callback to a simple confirmation form using the codeconfirm_form()/code core function as a base./p pAnother option, is to put a token in the URL that is unique for each page load and can't be easily forged, much like the a href=https://www.drupal.org/project/flagFlag module/a does. Keep in mind though that this approach might not behave well in conjunction with cached markup containing links to URLs that rely on tokens like this./p h2#9 - Using components with known vulnerabilities/h2 blockquotepIncluded libraries and frameworks (of which there are few) in Drupal core are system-level, unsophisticated, and of low risk to full server or application compromise./p /blockquote pUnfortunately, this happens very, very frequently in Drupal as soon as you start counting contributed modules as components. Ironically, the frequency of known security vulnerabilities showing up in installed modules is due in a large part to the security team doing a good job of reviewing and flagging community code. The difficult part here is being proactive about regularly deploying new module versions as security fixes are released./p pIt's a shame that the a href=http://droptor.com/Droptor/a service was discontinued, as it provided a central dashboard for reviewing available security updates across multiple sites. Acquia and Pantheon both provide similar dashboards for sites hosted on their servers./p pIt's also a shame that the core Update module that dials out to Drupal.org to get the status of installed module versions is somewhat poorly optimised. It's very easy to configure a site (such as when using poor man's cron) so that 20+ second page loads are experienced intermittently when using Update. If performance is important, I recommend enforcing the Update module to be a href=/blog/using-context-keep-your-development-modules-disabled-your-production-sitesenabled in a review environment/a, but not production or local development where slow page load times could become an issue./p pThere's little else to say here. Keeping your modules up-to-date is simply a matter of organisation/process and diligence and has little to do with development skills or further learning./p h2#10 - Unwanted redirects and forwards/h2 blockquotepInternal page redirects cannot be used to circumvent Drupal's integrated menu and access control system. Drupal protects against automatic redirection to off-site URLs which could be used in a phishing attack./p /blockquote pDrupal provides the codedrupal_goto()/code function for handling redirections correctly. This function will ignore absolute URLs in codeGET/code requests, but otherwise will always respect the codedestination/code parameter in the URL. This allows us to safely redirect/forward users by constructing our URLs correctly (with codedrupal_get_destination()/code), without opening ourselves up to phishing attacks./p pThe contrib a href=https://www.drupal.org/project/extlinkExternal Links/a module also provides visual feedback for users, protecting them against unexpected offsite redirections, showing an icon on any link that will take the user to a new domain. The a href=https://www.drupal.org/project/extlink_extraExternal Links Extra/a module takes this one step further and allows for a popup warning box, or even a dedicated intermediate page, to make it as clear as possible to users that they are about to be redirected offsite./p /div div class=field-posted-by div class=ds-2col-stacked user-profile view-mode-blog_post_by clearfix div class=group-header /div div class=group-left div class=field-profile-picture img src=https://www.godel.com.au/sites/default/files/styles/blog_profile_picture/public/img_7582.jpg?itok=4djVeal1 width=80 height=80 alt= / /div /div div class=group-right div class=field-name h3David Meister/h3 /div div class=field-position-title Director amp; Lead developer /div /div div class=group-footer /div /div /div div class=field-blog-social a class=facebook-share icon-facebook href=https://www.facebook.com/sharer/sharer.php?u=http://www.godel.com.au/rss/planet-drupal target=_blankf/aa class=twitter-share icon-twitter href=https://twitter.com/share target=_blankt/a /div div class=field-custom-pager div role=article class=ds-1col node node-blog-entry view-mode-custom_pager clearfix div class=field-title h3a href=/blog/using-style-linking-sane-font-face-declarations-post-ie8-worldUsing style-linking for sane @font-face declarations in a post-IE8 world/a/h3 /div div class=field-post-date Mon June 30, 2014 /div div class=field-body Say no to fake browser bold and fake browser italic, messy @font-face syntax and super-legacy browser bug support with the neat, logical style-linking @font-face syntax. /div /div div class=next no-result node-blog-entry/div /div h3 class=field-label Tags /h3 div class=field-tags a href=/planet-drupalplanet drupal/a /div

Drupal core announcements: Drupal core updates for July 10, 2014

Fri, 07/11/2014 - 00:53
h2 id=newWhat's new with Drupal 8?/h2 pThe past two weeks have seen steady progress on Drupal 8, with the release of a href=https://www.drupal.org/node/2296363drupal 8.0-alpha13/a, a href=https://twitter.com/xjmdrupal/status/486904081676763136the Clearing of the RTBC Queue/a, a href=https://www.drupal.org/node/2297545the expected deployment of Semantic Versioning support on Drupal.org/a, the launch of the a href=https://groups.drupal.org/node/430243#D8CX initiative/a, and a href=http://www.drupalcommerce.org/blog/14871/launching-commerce-drupal-8the announcement about the roadmap for Drupal Commerce for Drupal 8/a!/p h3Updates to api.drupal.org/h3 pIf you go to a href=https://api.drupal.org/api/drupal/8 title=https://api.drupal.org/api/drupal/8https://api.drupal.org/api/drupal/8/a you'll notice a few updates:/p ul liA few months ago, we updated the landing page with a list of topics, which were mostly just stubs. Documentation has now been written for most of the topics that are linked from the landing page./li liThere's a href=https://api.drupal.org/api/drupal/services/8a list of Services/a on the right sidebar, which you can filter by tag and name keywords — and each service has its own page, with appropriate cross-linking (list of code that uses the service on the service page, and if a service name is used in code, it should link to the service page)/li liThe a href=https://api.drupal.org/api/drupal/classes/8Classes page/a now lists Traits as well as classes and interfaces/li liFor hooks like a href=https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_form_FORM_ID_alter/8codehook_form_FORM_ID_alter()/code/a, you can now see a list of functions that implement it (previously this only worked for hooks like a href=https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_form_alter/8codehook_form_alter()/code/a where the function name was codemodulename_hookname()/code, but now it works for ALL_CAPS replacements as well)./li /ul h2 id=releaseWhere's Drupal 8 at in terms of release?/h2 pLast week, we fixed 1 critical issue and 5 major issues, and opened 2 criticals and 10 majors. That puts us overall at a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=4amp;priorities%5B%5D=400amp;categories%5B%5D=1amp;categories%5B%5D=2amp;version%5B%5D=8.xamp;issue_tags_op=%3D97 release-blocking critical issues/a and a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=15amp;status%5B%5D=4amp;priorities%5B%5D=300amp;categories%5B%5D=1amp;categories%5B%5D=2amp;version%5B%5D=8.xamp;issue_tags_op=%3D614 major issues/a./p h2 id=helpWhere can I help?/h2 h3 id=topTop criticals to hit this week/h3 pEach week, we check with core maintainers and contributors for the extra critical criticals that are blocking other work. These issues are often tough problems with a long history. If you're familiar with the problem-space of one of these issues, and have the time to dig in, help drive it forward by reviewing, improving, and testing its patch, and by making sure the issue's summary is up to date and any API changes are documented with a a href=https://groups.drupal.org/node/402688draft change record/a, we could use your help!/p ul liWe need people to review a href=https://www.drupal.org/node/2260457Issue #2260457: Allow config entities to remove dependent configuration keys when dependencies are deleted/a. Uninstalling modules in Drupal 8 will remove any configuration that has a dependency on that module. This will keep your site working but at the moment the delete is a bit greedy! Two other related issues, a href=https://www.drupal.org/node/2212081#2212081/a and a href=https://www.drupal.org/node/1881630#1881630/a could use some work too./li lia href=https://www.drupal.org/node/2293773Issue #2293773: Field allowed values use dots in key names - not allowed in config/a is nearly done, but we need to decide on the best of two paths forward, code review and commit./li lia href=https://www.drupal.org/node/2268939Issue #2268939: Config overrides not updated when config changes/a needs review./li lia href=https://www.drupal.org/node/2256521Issue #2256521: New plan, Phase 2: Implement menu links as plugins, including static admin links and views, and custom links with menu_link_content entity, all managed via menu_ui module/a needs extensive code reviews, API changes documented, a change record drafted, and existing change records that will need updates identified and updated to reference the issue./li liThere are still a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=4amp;version%5B%5D=8.xamp;issue_tags_op=%3Damp;issue_tags=beta+blocker7 beta-blockers/a that need to be done to provide a stable data model and stable critical APIs (including a couple of the issues above), and a href=https://www.drupal.org/project/issues/search/drupal?project_issue_followers=amp;status[]=1amp;status[]=13amp;status[]=8amp;status[]=14amp;status[]=4amp;version[]=8.xamp;issue_tags_op=%3Damp;issue_tags=beta+deadline14 non-critical issues that significantly change the data model or critical APIs, and therefore can only be committed before the first beta is released/a. Please help move them forward!/li /ul h3More ways to help/h3 pa href=https://www.drupal.org/node/1679344Issue #1679344: Race condition in node_save() when not using DB for cache_field/a recently caused a Drupal.org outage. The issue already has a proposed resolution recommended in comment #24 — help out by creating a patch for either D7 or D8./p pAdditionally, there are a bunch of easy documentation issues which need some help moving forward. For each of these, there is a Child Issues sidebar. Look there for issues that are active, needs work, or needs review:/p ul lia href=https://www.drupal.org/node/2269389Issue #2269389: Make sure plugin developer info is discoverable/a/li lia href=https://www.drupal.org/node/2294117Issue #2294117: Some @defgroup topics should be moved/renamed/a/li lia href=https://www.drupal.org/node/1908570Issue #1908570: Update or create hook_help() texts for D8 core modules/a/li /ul pIf you want to get started with the core development process, this is a great way to get your first commit in core!/p pYou can also search the Drupal Core issue queue for issues tagged Novice: a href=https://www.drupal.org/project/issues/search/drupal?status[]=Openamp;version[]=8.xamp;component[]=documentationamp;issue_tags=Novicethe ones in the documentation component/a are especially good for new contributors./p pAs always, if you're new to contributing to core, check out a href=https://drupal.org/core-mentoringCore contribution mentoring hours/a. Twice per week, you can log into IRC and helpful Drupal core mentors will get you set up with answers to any of your questions, plus provide some useful issues to work on./p pYou can also help by a href=https://www.gittip.com/DrupalCoreGittipTeam/sponsoring Drupal core development/a. /p h2 id=commitsNotable Commits/h2 pThe best of codegit log --since quot;2014-06-25quot; --pretty=oneline/code (201 commits in total):/p ul lia href=https://www.drupal.org/node/2144263Issue #2144263 by fago, yched, alexpott, Berdir, plach, andypost, effulgentsia, michaelfavia: Decouple entity field storage from configurable fields/a — this important step in completing the Drupal 8 Entity Field API removed the hardcoded assumption that additional (non-base) fields had to be provided by the Field module (because only that was capable of creating the necessary tables for it), as the entity storage had those specific interfaces in the relevant methods. This change completes work done across DrupalCons Portland, Prague, and Austin! Great job team!/li lia href=https://www.drupal.org/node/2286357Issue #2286357 by tim.plunkett: Introduce Display Variants, use for the block rendering flow/a — ports the concept of Variants from Panels/CTools into Drupal core./li lia href=https://www.drupal.org/node/2016629Issue #2016629 by larowlan, neclimdul, sun, alexpott, jibran, ParisLiakos, donquixote, effulgentsia, msonnabaum: Refactor bootstrap to better utilize the kernel./a: ul liBy loading the kernel a lot earlier, we can take advantage of its features to remove superglobals from the bootstrap process and deprecate drupal_bootstrap()./li liIt also makes the code cleaner and more testable, opening the door to more kernel-based testing./li /ul /li lia href=https://www.drupal.org/node/2231595Issue #2231595 by beejeebus, Steven Merrill, kim.pepper, Wim Leers, msonnabaum: Add a cache backend that checks an inconsistent cache, then falls back to a consistent cache backend./a — this allows a site running on a cluster to cache some things locally (e.g.: APC) and other things remotely (e.g.: MySQL, Memcached or Redis), reducing network traffic and improving performance./li liSome new improvements: ul lia href=https://www.drupal.org/node/1906806Issue #1906806 by Berdir, damiankloip, Sifro, dawehner: You can now add views relationships based on entity references/a/li lia href=https://www.drupal.org/node/1999312Issue #1999312 by baisong, lokapujya, botanic_spark, attiks: The Responsive Image module now has an empty image option so you can hide images on certain devices./a/li lia href=https://www.drupal.org/node/2227601Issue #2227601 by mparker17, cs_shadow, swentel, lanchez, mgifford: You can now choose to hide field labels in an accessible way with a - Visually Hidden - label option./a/li lia href=https://www.drupal.org/node/936704Issue #936704 by Matt V., swentel, tim.plunkett, Jalandhar, jimi-o: Drupal now asks for confirmation before deleting all your log messages./a/li /ul /li liSome bug fixes: ul lia href=https://www.drupal.org/node/1468582Issue #1468582 by mgifford, janusman, edward_or, tstoeckler, alanburke, Schnitzel, dcmouyard, LewisNyman: Added meta tags to tell mobile devices that the site is responsive, so they shouldn't render the desktop version/a/li lia href=https://www.drupal.org/node/2290261Issue #2290261 by tim.plunkett, amool: the full configuration export would crash if the php_fileinfo extension was not installed/a/li lia href=https://www.drupal.org/node/2277281Issue #2277281 by dobe, amitgoyal, michaelfavia | drumm: Removed the 128-character cap on allowed file extensions/a/li lia href=https://www.drupal.org/node/578400Issue #578400 by aaronschachter, melsi, Gábor Hojtsy, valthebald, idflood, sign, Damien Tournoud: Pages that are titled simply 0 are now displayed./a/li lia href=https://www.drupal.org/node/2154775Issue #2154775 by er.pushpinderrana, barnettech, kirkkala, InternetDevels | Wim Leers: You can now see your cursor while editing a title in-place/a/li lia href=https://www.drupal.org/node/2282599Issue #2282599 by LewisNyman, joachim: Drop-down menus now work in Stark/a/li /ul /li liA whole bunch of deprecated functions were deleted, most notably a href=https://www.drupal.org/node/2294093codearg()/code/a./li /ul pYou can also always check the a href=https://drupal.org/list-changesChange records for Drupal core/a for the full list of Drupal 8 API changes from Drupal 7./p h2 id=planetDrupal 8 Around the Interwebs/h2 pExcited to learn more about the changes coming up in Drupal 8, but don't like reading patch files? Here are some of the best articles from the past two weeks:/p ul liAmber Matz of a href=http://drupalize.me/Drupalize.Me/a wrote a great a href=http://drupalize.me/blog/201406/accessibility-features-drupal-8analysis of the accessibility improvements in Drupal 8/a./li liDaniel Sipos of a href=http://www.webomelette.com/Web Omelette/a explains a href=http://www.sitepoint.com/drupal-8-version-entityfieldquery/how the Entity Field Query service works in Drupal 8/a./li liKristof van Tomme of a href=http://pronovix.com/Pronovix/a explains how a href=http://pronovix.com/blog/behat-coverage-all-drupal-how-it-could-be-donewe could get Behat coverage for all of Drupal/a./li liSteve Burge of a href=https://www.ostraining.comOSTraining/a talks about a href=https://www.ostraining.com/blog/drupal/drupal-8-july-2015/?utm_source=feedburneramp;utm_medium=feedamp;utm_campaign=Feed%3A+ostrainingdrupal+%28OSTraining+Drupal%29the State of Drupal 8/a./li /ul h2 id=eventsDrupal 8 in Real Life/h2 pWant to meet up with other Drupal folks excited about moving Drupal 8 forward? Code sprints are an ideal way to meet new friends, contribute to Drupal core and/or contrib, learn, share tips/tricks and discover new talent./p pTwo big events, a href=http://2014.tcdrupal.org/Twin Cities DrupalCamp/a (in strongMinnesota, USA/strong) and a href=http://2014.drupalaton.hu/Drupalaton/a (in strongLake Balaton, Hungary/strong), will be holding massive, 4-day Drupal 8 sprints on strongAug 7-10/strong. Help us make sure there is space for everyone by signing up ahead of time!/p ul lia href=https://docs.google.com/spreadsheet/ccc?key=0AtDYnjV5l0uydGFjekZSM1ROR040eldUeEU4OU1JNFE#gid=0Sign up for TCDrupalCamp sprints here!/a/li lia href=https://docs.google.com/spreadsheet/ccc?key=0Aqxsrc5BVkagdEtJeGpzVEVJaGhhWURGTk1HWWRIeUE#gid=0Sign up for Drupalaton sprints here!/a/li /ul pHere are some other upcoming events:/p ul listrongJuly 10/strong: Forum One is hosting a a href=https://www.eventbrite.com/e/drupal-8-code-sprint-with-forum-one-tickets-11921354091Code Sprint/a at their offices in strongWashington DC/strong./li listrongJuly 12-13/strong: a href=http://jerseyshoredrupal.github.io/Drupal 8 at the Jersey Shore/a in strongNew Jersey, USA/strong, has room for 40 Drupal 8 sprinters. a href=https://twitter.com/drupalcampnj@drupalcampnj/a/li listrongJuly 16/strong: DesignHammer is hosting a a href=http://designhammer.com/blog/drupal-coder-lounge-designhammer-0Drupal Coder Lounge/a event in strongDurham, North Carolina, USA/strong to help work on Drupal 8 core and update documentation and contribtued modules for Drupal 8./li listrongJuly 17-20/strong: a href=http://2014.drupalcorn.org/sprintDrupalCorn/a in strongIowa, USA/strong will have a Drupal 8 contributed module sprint. a href=https://twitter.com/drupalcorn@drupalcorn/a/li /ul h2 id=wrapWhew! That's a wrap!/h2 pDo you follow a href=https://drupal.org/planetDrupal Planet/a with devotion, or keep a close eye on the a href=http://www.drupical.com/Drupal event calendar/a, or codegit pull origin 8.x/code every morning without fail before your coffee? We're looking for more contributors to help compile these posts. You could either take a few hours once every six weeks or so to put together a whole post, or help with one section more regularly. a href=https://drupal.org/user/65776/contactContact xjm/a if you'd like to help communicate all the interesting happenings in Drupal 8!/p

Drupal core announcements: Drupal core updates for July 10, 2014

Thu, 07/10/2014 - 22:13
h2 id=newWhat's new with Drupal 8?/h2 pThe past two weeks have seen steady progress on Drupal 8, with the release of a href=https://www.drupal.org/node/2296363drupal 8.0-alpha13/a, a href=https://twitter.com/xjmdrupal/status/486904081676763136the Clearing of the RTBC Queue/a, a href=https://www.drupal.org/node/2297545the expected deployment of Semanitc Versioning support on Drupal.org/a, the launch of the a href=https://groups.drupal.org/node/430243#D8CX initiative/a, and a href=http://www.drupalcommerce.org/blog/14871/launching-commerce-drupal-8the announcement about the roadmap for Drupal Commerce for Drupal 8/a!/p h3Updates to api.drupal.org/h3 pIf you go to a href=https://api.drupal.org/api/drupal/8 title=https://api.drupal.org/api/drupal/8https://api.drupal.org/api/drupal/8/a you'll notice a few updates:/p ul liA few months ago, we updated the landing page with a list of topics, which were mostly just stubs. Documentation has now been written for most of the topics that are linked from the landing page./li liThere's a href=https://api.drupal.org/api/drupal/services/8a list of Services/a on the right sidebar, which you can filter by tag and name keywords — and each service has its own page, with appropriate cross-linking (list of code that uses the service on the service page, and if a service name is used in code, it should link to the service page)/li liThe a href=https://api.drupal.org/api/drupal/classes/8Classes page/a now lists Traits as well as classes and interfaces/li liFor hooks like a href=https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_form_FORM_ID_alter/8codehook_form_FORM_ID_alter()/code/a, you can now see a list of functions that implement it (previously this only worked for hooks like a href=https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_form_alter/8codehook_form_alter()/code/a where the function name was codemodulename_hookname()/code, but now it works for ALL_CAPS replacements as well)./li /ul h2 id=releaseWhere's Drupal 8 at in terms of release?/h2 pLast week, we fixed 1 critical issue and 5 major issues, and opened 2 criticals and 10 majors. That puts us overall at a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=4amp;priorities%5B%5D=400amp;categories%5B%5D=1amp;categories%5B%5D=2amp;version%5B%5D=8.xamp;issue_tags_op=%3D97 release-blocking critical issues/a and a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=15amp;status%5B%5D=4amp;priorities%5B%5D=300amp;categories%5B%5D=1amp;categories%5B%5D=2amp;version%5B%5D=8.xamp;issue_tags_op=%3D614 major issues/a./p h2 id=helpWhere can I help?/h2 h3 id=topTop criticals to hit this week/h3 pEach week, we check with core maintainers and contributors for the extra critical criticals that are blocking other work. These issues are often tough problems with a long history. If you're familiar with the problem-space of one of these issues, and have the time to dig in, help drive it forward by reviewing, improving, and testing its patch, and by making sure the issue's summary is up to date and any API changes are documented with a a href=https://groups.drupal.org/node/402688draft change record/a, we could use your help!/p ul liWe need people to review a href=https://www.drupal.org/node/2260457Issue #2260457: Allow config entities to remove dependent configuration keys when dependencies are deleted/a. Uninstalling modules in Drupal 8 will remove any configuration that has a dependency on that module. This will keep your site working but at the moment the delete is a bit greedy! Two other related issues, a href=https://www.drupal.org/node/2212081#2212081/a and a href=https://www.drupal.org/node/1881630#1881630/a could use some work too./li lia href=https://www.drupal.org/node/2293773Issue #2293773: Field allowed values use dots in key names - not allowed in config/a is nearly done, but we need to decide on the best of two paths forward, code review and commit./li lia href=https://www.drupal.org/node/2268939Issue #2268939: Config overrides not updated when config changes/a needs review./li lia href=https://www.drupal.org/node/2256521Issue #2256521: New plan, Phase 2: Implement menu links as plugins, including static admin links and views, and custom links with menu_link_content entity, all managed via menu_ui module/a needs extensive code reviews, API changes documented, a change record drafted, and existing change records that will need updates identified and updated to reference the issue./li liThere are still a href=https://drupal.org/project/issues/search/drupal?status%5B%5D=1amp;status%5B%5D=13amp;status%5B%5D=8amp;status%5B%5D=14amp;status%5B%5D=4amp;version%5B%5D=8.xamp;issue_tags_op=%3Damp;issue_tags=beta+blocker7 beta-blockers/a that need to be done to provide a stable data model and stable critical APIs (including a couple of the issues above), and a href=https://www.drupal.org/project/issues/search/drupal?project_issue_followers=amp;status[]=1amp;status[]=13amp;status[]=8amp;status[]=14amp;status[]=4amp;version[]=8.xamp;issue_tags_op=%3Damp;issue_tags=beta+deadline14 non-critical issues that significantly change the data model or critical APIs, and therefore can only be committed before the first beta is released/a. Please help move them forward!/li /ul h3More ways to help/h3 pa href=https://www.drupal.org/node/1679344Issue #1679344: Race condition in node_save() when not using DB for cache_field/a recently caused a Drupal.org outage. The issue already has a proposed resolution recommended in comment #24 — help out by creating a patch for either D7 or D8./p pAdditionally, there are a bunch of easy documentation issues which need some help moving forward. For each of these, there is a Child Issues sidebar. Look there for issues that are active, needs work, or needs review:/p ul lia href=https://www.drupal.org/node/2269389Issue #2269389: Make sure plugin developer info is discoverable/a/li lia href=https://www.drupal.org/node/2294117Issue #2294117: Some @defgroup topics should be moved/renamed/a/li lia href=https://www.drupal.org/node/1908570Issue #1908570: Update or create hook_help() texts for D8 core modules/a/li /ul pIf you want to get started with the core development process, this is a great way to get your first commit in core!/p pYou can also search the Drupal Core issue queue for issues tagged Novice: a href=https://www.drupal.org/project/issues/search/drupal?status[]=Openamp;version[]=8.xamp;component[]=documentationamp;issue_tags=Novicethe ones in the documentation component/a are especially good for new contributors./p pAs always, if you're new to contributing to core, check out a href=https://drupal.org/core-mentoringCore contribution mentoring hours/a. Twice per week, you can log into IRC and helpful Drupal core mentors will get you set up with answers to any of your questions, plus provide some useful issues to work on./p pYou can also help by a href=https://www.gittip.com/DrupalCoreGittipTeam/sponsoring Drupal core development/a. /p h2 id=commitsNotable Commits/h2 pThe best of codegit log --since quot;2014-06-25quot; --pretty=oneline/code (201 commits in total):/p ul lia href=https://www.drupal.org/node/2144263Issue #2144263 by fago, yched, alexpott, Berdir, plach, andypost, effulgentsia, michaelfavia: Decouple entity field storage from configurable fields/a — this important step in completing the Drupal 8 Entity Field API removed the hardcoded assumption that additional (non-base) fields had to be provided by the Field module (because only that was capable of creating the necessary tables for it), as the entity storage had those specific interfaces in the relevant methods. This change completes work done across DrupalCons Portland, Prague, and Austin! Great job team!/li lia href=https://www.drupal.org/node/2286357Issue #2286357 by tim.plunkett: Introduce Display Variants, use for the block rendering flow/a — ports the concept of Variants from Panels/CTools into Drupal core./li lia href=https://www.drupal.org/node/2016629Issue #2016629 by larowlan, neclimdul, sun, alexpott, jibran, ParisLiakos, donquixote, effulgentsia, msonnabaum: Refactor bootstrap to better utilize the kernel./a: ul liBy loading the kernel a lot earlier, we can take advantage of its features to remove superglobals from the bootstrap process and deprecate drupal_bootstrap()./li liIt also makes the code cleaner and more testable, opening the door to more kernel-based testing./li /ul /li lia href=https://www.drupal.org/node/2231595Issue #2231595 by beejeebus, Steven Merrill, kim.pepper, Wim Leers, msonnabaum: Add a cache backend that checks an inconsistent cache, then falls back to a consistent cache backend./a — this allows a site running on a cluster to cache some things locally (e.g.: APC) and other things remotely (e.g.: MySQL, Memcached or Redis), reducing network traffic and improving performance./li liSome new improvements: ul lia href=https://www.drupal.org/node/1906806Issue #1906806 by Berdir, damiankloip, Sifro, dawehner: You can now add views relationships based on entity references/a/li lia href=https://www.drupal.org/node/1999312Issue #1999312 by baisong, lokapujya, botanic_spark, attiks: The Responsive Image module now has an empty image option so you can hide images on certain devices./a/li lia href=https://www.drupal.org/node/2227601Issue #2227601 by mparker17, cs_shadow, swentel, lanchez, mgifford: You can now choose to hide field labels in an accessible way with a - Visually Hidden - label option./a/li lia href=https://www.drupal.org/node/936704Issue #936704 by Matt V., swentel, tim.plunkett, Jalandhar, jimi-o: Drupal now asks for confirmation before deleting all your log messages./a/li /ul /li liSome bug fixes: ul lia href=https://www.drupal.org/node/1468582Issue #1468582 by mgifford, janusman, edward_or, tstoeckler, alanburke, Schnitzel, dcmouyard, LewisNyman: Added meta tags to tell mobile devices that the site is responsive, so they shouldn't render the desktop version/a/li lia href=https://www.drupal.org/node/2290261Issue #2290261 by tim.plunkett, amool: the full configuration export would crash if the php_fileinfo extension was not installed/a/li lia href=https://www.drupal.org/node/2277281Issue #2277281 by dobe, amitgoyal, michaelfavia | drumm: Removed the 128-character cap on allowed file extensions/a/li lia href=https://www.drupal.org/node/578400Issue #578400 by aaronschachter, melsi, Gábor Hojtsy, valthebald, idflood, sign, Damien Tournoud: Pages that are titled simply 0 are now displayed./a/li lia href=https://www.drupal.org/node/2154775Issue #2154775 by er.pushpinderrana, barnettech, kirkkala, InternetDevels | Wim Leers: You can now see your cursor while editing a title in-place/a/li lia href=https://www.drupal.org/node/2282599Issue #2282599 by LewisNyman, joachim: Drop-down menus now work in Stark/a/li /ul /li liA whole bunch of deprecated functions were deleted, most notably a href=https://www.drupal.org/node/2294093codearg()/code/a./li /ul pYou can also always check the a href=https://drupal.org/list-changesChange records for Drupal core/a for the full list of Drupal 8 API changes from Drupal 7./p h2 id=planetDrupal 8 Around the Interwebs/h2 pExcited to learn more about the changes coming up in Drupal 8, but don't like reading patch files? Here are some of the best articles from the past two weeks:/p ul liAmber Matz of a href=http://drupalize.me/Drupalize.Me/a wrote a great a href=http://drupalize.me/blog/201406/accessibility-features-drupal-8analysis of the accessibility improvements in Drupal 8/a./li liDaniel Sipos of a href=http://www.webomelette.com/Web Omelette/a explains a href=http://www.sitepoint.com/drupal-8-version-entityfieldquery/how the Entity Field Query service works in Drupal 8/a./li liKristof van Tomme of a href=http://pronovix.com/Pronovix/a explains how a href=http://pronovix.com/blog/behat-coverage-all-drupal-how-it-could-be-donewe could get Behat coverage for all of Drupal/a./li liSteve Burge of a href=https://www.ostraining.comOSTraining/a talks about a href=https://www.ostraining.com/blog/drupal/drupal-8-july-2015/?utm_source=feedburneramp;utm_medium=feedamp;utm_campaign=Feed%3A+ostrainingdrupal+%28OSTraining+Drupal%29the State of Drupal 8/a./li /ul h2 id=eventsDrupal 8 in Real Life/h2 pWant to meet up with other Drupal folks excited about moving Drupal 8 forward? Code sprints are an ideal way to meet new friends, contribute to Drupal core and/or contrib, learn, share tips/tricks and discover new talent./p pTwo big events, a href=http://2014.tcdrupal.org/Twin Cities DrupalCamp/a (in strongMinnesota, USA/strong) and a href=http://2014.drupalaton.hu/Drupalaton/a (in strongLake Balaton, Hungary/strong), will be holding massive, 4-day Drupal 8 sprints on strongAug 7-10/strong. Help us make sure there is space for everyone by signing up ahead of time!/p ul lia href=https://docs.google.com/spreadsheet/ccc?key=0AtDYnjV5l0uydGFjekZSM1ROR040eldUeEU4OU1JNFE#gid=0Sign up for TCDrupalCamp sprints here!/a/li lia href=https://docs.google.com/spreadsheet/ccc?key=0Aqxsrc5BVkagdEtJeGpzVEVJaGhhWURGTk1HWWRIeUE#gid=0Sign up for Drupalaton sprints here!/a/li /ul pHere are some other upcoming events:/p ul listrongJuly 10/strong: Forum One is hosting a a href=https://www.eventbrite.com/e/drupal-8-code-sprint-with-forum-one-tickets-11921354091Code Sprint/a at their offices in strongWashington DC/strong./li listrongJuly 12-13/strong: a href=http://jerseyshoredrupal.github.io/Drupal 8 at the Jersey Shore/a in strongNew Jersey, USA/strong, has room for 40 Drupal 8 sprinters. a href=https://twitter.com/drupalcampnj@drupalcampnj/a/li listrongJuly 16/strong: DesignHammer is hosting a a href=http://designhammer.com/blog/drupal-coder-lounge-designhammer-0Drupal Coder Lounge/a event in strongDurham, North Carolina, USA/strong to help work on Drupal 8 core and update documentation and contribtued modules for Drupal 8./li listrongJuly 17-20/strong: a href=http://2014.drupalcorn.org/sprintDrupalCorn/a in strongIowa, USA/strong will have a Drupal 8 contributed module sprint. a href=https://twitter.com/drupalcorn@drupalcorn/a/li /ul h2 id=wrapWhew! That's a wrap!/h2 pDo you follow a href=https://drupal.org/planetDrupal Planet/a with devotion, or keep a close eye on the a href=http://www.drupical.com/Drupal event calendar/a, or codegit pull origin 8.x/code every morning without fail before your coffee? We're looking for more contributors to help compile these posts. You could either take a few hours once every six weeks or so to put together a whole post, or help with one section more regularly. a href=https://drupal.org/user/65776/contactContact xjm/a if you'd like to help communicate all the interesting happenings in Drupal 8!/p

LightSky: 14 Modules for Improving the Administrative Usability of your Drupal Site

Thu, 07/10/2014 - 21:57
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpOften times, Drupal gets a bad rap for usability. That’s because out of the box Drupal isn’t very user friendly. As with everything Drupal, it requires a few contributed modules in order to really make it shine. Below are a list of fourteen modules that you can add to your Drupal site to increase its usability. Let’s begin!/p pstrongViews Bulk Operations /strong- a href=https://www.drupal.org/project/views_bulk_operations target=_blankVBO/a is a module that allows you to execute bulk actions on views rows. The actions it comes with are pretty standard, but you can extend it using the Rules module or even roll your own if that’s your thing. This module allows for your site admins to be able to do things like mass delete nodes, mass publish/unpublish nodes, or even mass change the nodes author./p pstrongAdmin Views/strong - a href=https://www.drupal.org/project/admin_views target=_blankAdmin Views/a is a module that replaces the stock administration screens with views. Why is this neat? You can add additional exposed filters to your users administration screens, or change which columns appear in order to help your site admins easily find the information they are looking for./p pstrongDraggable Views/strong - a href=https://www.drupal.org/project/draggableviews target=_blankDraggable Views/a is a module that allows your rows in a view to be reordered using the same javascript implementation that you find scattered about the Drupal admin (blocks, menu, etc)./p pstrongModule Filter/strong - a href=https://www.drupal.org/project/module_filter target=_blankModule Filter/a is a module that seeks to garner control over the unwieldy module listing page. It does this by adding a tab on the left hand side for each package, as well as one for showing the modules alphabetically. It also adds a textbox that you can search to quickly filter the module listing./p pstrongAutocomplete Deluxe/strong - The a href=https://www.drupal.org/project/autocomplete_deluxe target=_blankAutocomplete Deluxe/a module replaces the default autocomplete element with the jQuery UI version making it much more user friendly than the default implementation./p pstrongPathologic/strong - The a href=https://www.drupal.org/project/pathologic target=_blankPathologic/a module is an input filter which fixes image and link paths that would otherwise cause them to break. This is useful in situations where your site admins have content on both staging and live sites. Gone are the days of the live site pointing to the test site by accident or vice versa./p pstrongCustom Contextual Links/strong - a href=https://www.drupal.org/project/ccl target=_blankContextual links/a was one of the features that our D6 -gt; D7 clients really seemed to love. One great usability improvement that you can make is to add a contextual link to a view (for example) that would allow them to quickly add the piece of content that corresponds to that view. Normally you’d add these custom contextual links through a set of hooks, but this module provides a nice UI to make it simple. /p pstrongConditional Fields/strong - The a href=https://www.drupal.org/project/conditional_fields target=_blankConditional Fields/a module allows you to create fields that are dependent upon one another in order to be shown. One example of this would be to show a textarea of an admin (or user) selected “Other”. I added this module because it can be go a long way towards cleaning up administration screens when adding content types with lots of information./p pstrongLinkit/strong - The a href=https://www.drupal.org/project/linkit target=_blankLinkit/a module replaces the default CKEditor link icon with an autocomplete field that allows admins to easily drill down to the content they are looking to link to. We have a great write up on this module that you can find a href=http://www.lightsky.com/blog/using-linkit-link-drupalhere/a./p pstrongEdit /strong- Drupal 8 will ship with inline editing, and if you are too excited to wait, check out the a href=https://www.drupal.org/project/edit target=_blankEdit/a module. Edit module allows you to do just that, edit content in place. Note that you’ll need to use the CKEditor WYSIWYG if you want this to work on WYSIWYG fields./p pstrongSelect2/strong - Like the autocomplete deluxe module above, the a href=https://www.drupal.org/project/select2 target=_blankSelect2/a module replaces the standard select box with one that supports searching, remote data sets and infinite scrolling of results./p pstrongReferences Dialog/strong - The a href=https://www.drupal.org/project/references_dialog target=_blankReferences Dialog/a replaces all the standard reference fields with a dialog that allows them to add, edit and search for references. This can go a long way towards simplifying the administration workflow./p pstrongContent Menu/strong - The a href=https://www.drupal.org/project/content_menu target=_blankContent Menu/a module adds the ability for administrators to be able to create pieces of content straight from the menu administration pages. When creating a piece of content, you have the ability to add a menu item, so it only makes sense that you can add a piece a content when adding a menu item./p pstrongNavbar/strong - The a href=https://www.drupal.org/project/navbar target=_blankNavbar/a module adds a mobile friendly navigation bar to the administration section of your website replacing the default toolbar which is non-responsive./p pThere you go. Fourteen modules to improve the authoring experience of your Drupal site. What do you think of the list? Are there any modules you would like to see added? Feel free to discuss in the comments below./p h3 For more tips like these, a href=http://www.lightsky.com/lightsky-socialfollow us/a on social media or subscribe for free to our a href=http://www.lightsky.com/rssRSS feed/a and a href=http://eepurl.com/dx_ljnewsletter/a. You can also a href=http://www.lightsky.com/simple-contact-formcontact us/a directly or a href=http://www.lightsky.com/request-consultationrequest a consultation/a. /h3 /div/div/div

Drupal.org Featured Case Studies: University of Oxford

Thu, 07/10/2014 - 17:28
div class=field field-name-field-mainimage field-type-image field-label-hiddendiv class=field-itemsdiv class=field-item evenimg src=https://www.drupal.org/files/styles/case588x306/public/iMac_tablet_iphone_Oxford.png?itok=0VLDgxcK width=588 height=306 alt=Oxford University homepage screehshots //div/div/divdiv class=field field-name-field-link field-type-link-field field-label-abovediv class=field-labelCompleted Drupal site or project URL:nbsp;/divdiv class=field-itemsdiv class=field-item evena href=http://www.ox.ac.ukhttp://www.ox.ac.uk/a/div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpThe previous version of the University of Oxford site, also designed by Torchbox, was the top rated University site in a Times Education Supplement survey and was much imitated, but after more than seven years of duty, it was a little dated and, critically, wasn’t responsive./p pThe University of Oxford and Torchbox were excited to have the opportunity to revisit the site, and to revitalise it for a more digitally advanced generation of visitors. At the same time, we took on the challenge of moving this high profile, high traffic site to the Drupal Content Management System./p /div/div/divdiv class=field field-name-field-module field-type-node-reference field-label-abovediv class=field-labelKey modules/theme/distribution used:nbsp;/divdiv class=field-itemsdiv class=field-item evena href=/project/custom_breadcrumbsCustom Breadcrumbs/a/divdiv class=field-item odda href=/project/domainDomain Access/a/divdiv class=field-item evena href=/project/dsDisplay Suite/a/divdiv class=field-item odda href=/project/featuresFeatures/a/divdiv class=field-item evena href=/project/linkitLinkit/a/divdiv class=field-item odda href=/project/leafletLeaflet/a/divdiv class=field-item evena href=/project/mediaMedia/a/divdiv class=field-item odda href=/project/media_youtubeMedia: YouTube/a/divdiv class=field-item evena href=/project/media_vimeoMedia: Vimeo/a/divdiv class=field-item odda href=/project/menu_blockMenu block/a/divdiv class=field-item evena href=/project/menu_trail_by_pathMenu Trail By Path/a/divdiv class=field-item odda href=/project/workbenchWorkbench/a/divdiv class=field-item evena href=/project/workbench_moderationWorkbench Moderation/a/divdiv class=field-item odda href=/project/workbench_mediaWorkbench Media/a/divdiv class=field-item evena href=/project/viewsViews/a/divdiv class=field-item odda href=/project/wysiwygWysiwyg/a/divdiv class=field-item evena href=/project/mothershipmothership/a/div/div/div

Mark Shropshire: Spectacle Digital Signage Publishing System Sprint

Thu, 07/10/2014 - 15:39
div class=field field-name-body field-type-text-with-summary field-label-hidden view-mode-rssdiv class=field-itemsdiv class=field-item even property=content:encodedpa href=https://github.com/shrop/spectacle-frontendSpectacle/a is an open source digital signage publishing system for displaying content on any screen. The content is administered by a href=https://drupal.orgDrupal/a and displayed using a href=https://meteor.comMeteor/a./p pa href=https://knowclassic.comClassic Graphics/a, a href=http://suarit.uncc.eduSUAR IT/a at UNC Charlotte, a href=http://chardug.orgCharDUG/a, and a href=http://www.meetup.com/Meteor-Charlotte/Meteor Charlotte/a are sponsoring a Spectacle sprint on July 25th form 9am-4pm ET at a href=http://goo.gl/Z8kvvsClassic Graphics/a. !--break-- While the project is well underway, there is still a lot to do. We will be updating the a href=https://trello.com/spectacle1Trello/a board with ideas and tasks which need to be completed. We will also spend time demoing the current work completed and discussing Spectacle architecture concepts./p pNo matter what your skill level is with Drupal and Meteor, bring your laptop and we will get you up to speed to contribute in some fashion. We have tasks involving Drupal and Meteor site building, configuration, and development. We also have documentation and design needs. Some come on out and enjoy the fun of working together on a fantastic open source project./p pLunch will be provided by a href=https://knowclassic.comClassic Graphics/a./p pRelated links:/p ul lia href=https://drupal.org/project/spectacleSpectacle Drupal distribution/a/li lia href=https://github.com/shrop/spectacle-frontendSpectacle Meteor player/a/li lia href=https://trello.com/spectacle1Project Trello Boards/a/li /ul pRSVP a href=http://www.meetup.com/Meteor-Charlotte/events/194109872/here/a or a href=http://www.meetup.com/charDUG/events/194111332/here/a. Either way, we want to know if you are coming so we know how much lunch to provide. :)/p pContact a href=http://mark.shropshires.net/contactMark Shropshire/a with any questions/p /div/div/divsection class=field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above view-mode-rssh2 class=field-labelBlog Category:nbsp;/h2ul class=field-itemsli class=field-item evena href=/taxonomy/term/13 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Drupal/a/lili class=field-item odda href=/taxonomy/term/40 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=CharDUG/a/lili class=field-item evena href=/taxonomy/term/47 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Meteor.js/a/li/ul/section