<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Welcome to [enzo]lutions</title>
        <link>http://enzolutions.com</link>
        <description>RSS feed for Welcome to [enzo]lutions</description>
        <atom:link href="http://enzolutions.com/rss_drupal.xml" rel="self" type="application/rss+xml" />
                                    <item>
                    <title>The art of contributing in Software</title>
                    <description><![CDATA[<p>After participating for the first time in <a href="https://www.drupalgovcon.org/drupal-govcon-2016">Drupal GovCon 2016</a>, I had the opportunity to meet in person with <a href="https://www.drupal.org/u/qingkong">Kanshu Wu</a>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/kenshu-meetup-1.jpg"/></p>

<p><em>Kanshu</em> is a Drupal Frontend, who lives in the USA since 2014, but he still runs his company <a href="http://www.vi-sure.com">Vi Sure</a> with clients based in China.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/kenshu-meetup-2.jpg"/></p>

<p>I have been friends with <em>Kanshu</em> for about six months, and the way we connected was when I learned the first lesson of my tour <a href="http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days">Around the Drupal World in 120+ days</a>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/enzotour-banner.jpg"/></p>

<p>Because China was an important part of my tour, I decided to install the IM system <a href="https://es.wikipedia.org/wiki/QQ">QQ</a> to try to get information for my trip and be connected with people.</p>

<p>From time to time, I get friend requests from members of Chinese Drupal community mostly because they want to practice English or ask something about Drupal.</p>

<p>But, one day I got <em>Kanshu's</em> request, he told me he was glad that I wanted to go to China to share with the community, and asked me how he could help me on my trip. Because he lives outside China, I told him "Thank you", but couldn't see a way he could help me, since I had almost everything already set and I couldn't meet with him in China; So we just continued connected and we started chatting once every few days.</p>

<p>A couple of weeks after, <em>Kanshu</em> contacted me again telling me that he had found how he could contribute to my tour.</p>

<p>He said, "I am not a PHP developer, and I don't live in China, but I am a graphic and web designer, so I can create the official banner of your trip to improve the communication, marketing, and exposure of your journey."</p>

<p>I found his proposal very smart because he figured out a way to contribute with his skills, something that I didn't figure out. In the end, he did the banner, which was used in many events I participated and the infographic statistics of my tour when I completed it.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/enzotour16-stats-small.png"/></p>

<p>During our lunch, we had a conversation about how small are the contributions from China and Asia, I told him that situation not only happens in China and explained to him that the same problems happens in Latin America. We talked about that maybe the reason is due the challenges in our societies, people spend too much time trying to survive; So the chances that people have to contribute and help the rest of the world are reduced.</p>

<p>I agree with the previous analysis, but I resist to think that we have to accept and continue doing the same things. Let's go back to  <em>Kanshu</em>, he helps a lot of people, not only me, because he has written the first Drupal 7 book about theming in Chinese <a href="http://www.drupaltheme.guide">http://www.drupaltheme.guide</a></p>

<p>The way I see it, our communities always have the opportunity to contribute something based in their knowledge and reality, also those contributions doesn't have to have a global impact, some local initiatives are equally important, like his book in Chinese.</p>

<p>One common belief in China and Latin America ( I can't include other countries of Asia because I did confirm with locals) is that due the hard competition to survive, sharing your knowledge with your competitors will enable them to do what you do, and you will lose your advantage. But in my experience that thinking it's completely the opposite.</p>

<p>Without contributions I wouldn't be able to fund <a href="http://anexusit.com">Anexus</a> a Drupal Workshop located in Costa Rica with the goal of selling services in North America and Europe.</p>

<p>In <em>Anexus</em> contributing is the core of our business from day one until now, because contributing was and is still our way to show to the world that we know about Drupal and that we are good, so hire us!</p>

<p>Because of this, after contributing for almost three years in the <a href="http://drupalconsole.com">Drupal Console</a> project; I have started a new company named <a href="http://weknowinc.com">weKnow</a>.  weKnow is my second company funded with of <a href="http://jmolivas.com/">Jesus Manuel Olivas</a> and <a href="https://twitter.com/Kabarca">Kenny Abarca</a> now based in the USA, using the same logic, demonstrating that <em>we know</em> what we are talking about and that we are good on that applying our previous contributions to show that.</p>

<p>Don't take me wrong; I'm not saying I have an evil plan to master the world after any contribution, I wasn't expecting to create any business at the beginning, it's just something that naturally emerges in my case.</p>

<p>I firmly believe that contributing and constantly doing it, will eventually have a positive effect in your professional life.</p>

<p>For me. <em>contributing</em> means investing in our community, which is good for everybody and in the long term it will be particularly useful to you.</p>

<p>The art of contributing is to find small things you can do to create an impact and continue doing it means that you have a long-term vision.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/07/25/the-art-of-contributing-in-software</link>
                    <pubDate>Mon, 25 Jul 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/07/25/the-art-of-contributing-in-software</guid>
                </item>
                                                                                                                                                                                                                                                                                                                                        <item>
                    <title>Sydney Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>My last stop in Australia is in Sydney, commonly confuse as the capital of Australi, (I will not say which in the correct capital, Google it).</p>

<p>I flew from Melbourne just on time to participate in the Sydney Drupal Meetup; I am glad the local group opens a space to talk about <a href="http://drupalconsole.com">Drupal Console</a> with them.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sydney-drupal-meetup-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sydney-drupal-meetup-3.jpg"/></p>

<p>The reception was great, and I receive a lot of questions and new ideas to be included in Drupal Console.</p>

<p>The meetup organizer gave a fancy Australian wine, I didn't see that coming, thank you so much, guys.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sydney-drupal-meetup-2.jpg"/></p>

<p>Couple things I found interesting about Sydney.</p>

<p>The subway has wagons of two stories.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sydney-subway-two-stories.jpg"/></p>

<p>It's possible to request an Uber car to pickup inside the aiport.</p>

<h2>Airplane</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Melbourne, Australia &#8594; Sydney , Australia</td>
  <td>714</td>
</tr>
<tr>
  <td>Previously</td>
  <td>45.327</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>46.041</td>
</tr>
</tbody>
</table>

<h2>Bus/Car</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.833</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.833</td>
</tr>
</tbody>
</table>

<h2>Train</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>528</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>528</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Melbourne, Sydney (today)</td>
  <td>10.352</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.365.109</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.375.461</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/06/01/sydney-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Wed, 01 Jun 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/06/01/sydney-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                                                <item>
                    <title>Melbourbe Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday was a contribute day; I continue working on a new generator for <a href="http://drupalconsole">Drupal Console</a> <strong>generate:post:update</strong>, this command will be available in next release.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/console-generate-post-update.png"/></p>

<p>In the evening, I had my first contact with the Australia Drupal community where they gave me a space to share with them the current status of <strong>Drupal Console</strong> project. The audience was small, but the interest big, and a lot of question came up, I just hope I could provide good answers.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/melbourne-meetup-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/melbourne-meetup-2.jpg"/></p>

<p>Before the meetup, I did some a little of sightseeing visiting:</p>

<ul>
<li><a href="https://en.wikipedia.org/wiki/St_Paul%27s_Cathedral,_Melbourne">St Paul's Cathedral, Melbourne</a></li>
<li><a href="https://en.wikipedia.org/wiki/Australian_Centre_for_the_Moving_Image">Australian Centre for the Moving Image</a></li>
</ul>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Tasmania (today)</td>
  <td>10.514</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.312.039</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.322.553</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/27/melbourbe-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Fri, 27 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/27/melbourbe-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                                                                                                            <item>
                    <title>Bali Day 1 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>My last stop in Indonesia was Bali, yeah the famous Bali, the place that everybody was to visit, well I am here.</p>

<p>Bali has almost the same population of Costa Rica in a 10% of his space; But, believe me, or not there more than beaches in Bali and I am here to participate in a Drupal meetup with local web developers.</p>

<p>Suryanto the organizer said was a success with 12 attendees, so I was happy to hear that.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/raminten-1.jpg"/></p>

<p>OK, ok I will share some beach pictures from <a href="https://en.wikipedia.org/wiki/Pantai_Kuta">Pantai Kuta</a> my place is about four blocks from the beach I will return tomorrow to swing a little bit.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/pantai-kuta-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/pantai-kuta-2.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/pantai-kuta-3.jpg"/></p>

<p>Is still have a cold, but I hope tomorrow I will have more</p>

<h2>Airplane</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Yogyakarta, Indonesia &#8594; Bali, Indonesia</td>
  <td>542</td>
</tr>
<tr>
  <td>Previously</td>
  <td>39.141</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>39.683</td>
</tr>
</tbody>
</table>

<h2>Train</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>528</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>528</td>
</tr>
</tbody>
</table>

<h2>Bus/Car</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.046</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.046</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Bali (today)</td>
  <td>5.931</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.235.3641</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.241.295</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/19/bali-day-1-drupal-tour-2016</link>
                    <pubDate>Thu, 19 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/19/bali-day-1-drupal-tour-2016</guid>
                </item>
                                                                    <item>
                    <title>Yogyakarta Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Second Drupal meetup in Indonesia, this time in Yogyakarta a small city according to Indonesian standards, but almost bigger than Costa Rica :P.</p>

<p>This meetup was organized by <a href="http://skyshi.com">Skyshi</a> a local Drupal workshop; The audience was really excited about seeing <a href="http://drupalconsole.com">Drupal Console</a> project running using the Indonesian language, at least partially.</p>

<p>In the meetup were some non-Drupal developers, from Joomla, Javascript, and Wordpress community.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/yogyakarta-meetup-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/yogyakarta-meetup-2.jpg"/></p>

<p>During the day, I expend almost all my morning looking a shoe shop to find a replacement for my sneakers and testing the perfect ones, the ones I bring with me were of poor shape, due all the walking I do every day.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/new-sneakers.jpg"/></p>

<p>In sightseeing area, I visited the <a href="https://en.wikipedia.org/wiki/Kraton_Ngayogyakarta_Hadiningrat">Kraton Ngayogyakarta Hadiningrat</a> part of the Sultan Palace. The Sultan is the Governor and the owner of the land in the region.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sultan-palace-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/sultan-palace-2.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Yogyakarta (today)</td>
  <td>18.869</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.211.642</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.230.311</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/17/yogyakarta-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Tue, 17 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/17/yogyakarta-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                            <item>
                    <title>Jakarta, Indonesia Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>I am in last quarter of my [tour](http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days/) in a month I will be landing in my home.</p>

<p>Thanks to <a href="https://www.linkedin.com/in/ardnet">Pratomo Ardianto</a> and <a href="http://sepulsa.com">Sepula</a> I have the opportunity to talk with Drupal community in Jakarta about <a href="http://drupalconsole.com">Drupal Console</a> project.</p>

<p>The attendees had a lot of questions and were very interested in use Drupal 8, but still have some doubt about Drupal 8 modules availability; I hope my answers motivate them to adopt the Drupal 8 usage more soon than later.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/jakarta-drupal-meetup.jpg"/></p>

<p>Before to attend the meetup I did some sightseeing in Jakarta at</p>

<ul>
<li><a href="https://en.wikipedia.org/wiki/National_Museum_of_Indonesia">National Museum</a></li>
<li><a href="https://en.wikipedia.org/wiki/Istiqlal_Mosque,_Jakarta">Istiqlal Mosque</a></li>
<li><a href="https://en.wikipedia.org/wiki/Jakarta_Cathedral">Jakarta Cathedral</a></li>
</ul>

<p>Couples interested things are the Mosque the 3rd biggest mosque in the worlds and inside the Cathedral was a wedding in action at the moment I visited.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/jakarta-national-museum.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/jakarta-istiqlal-mosque.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/jakarta-cathedral-1.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/jakarta-cathedral-2.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Jakarta (today)</td>
  <td>11.658</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.149.066</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.160.724</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/13/jakarta-indonesia-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Fri, 13 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/13/jakarta-indonesia-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                            <item>
                    <title>Drupal Camp Manila Day 2 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>The second day of DrupalCamp Manila, on this day were some introductory sessions about Github, how to contribute to issues in Drupal and of course Drupal development.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-sprint.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-sprint-sven.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-sprint-joe.jpg"/></p>

<p>After lunch two of the organizers <strong>Paul de Paula</strong> and <strong>Gem Devanedera</strong> invite me to their home.</p>

<p>His place is located at <a href="https://en.wikipedia.org/wiki/Tanay,_Rizal">Tanay, Rizal</a> two and a half hours from Manila in the mountains and close to <a href="https://en.wikipedia.org/wiki/Laguna_de_Bay">Laguna de Bay</a>; the biggest lake in the Philippines I will explore that tomorrow.</p>

<p>With then I could feel a more local Pilipino experience, like <strong>Halo Halo</strong>. Pork and Fish</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/halo-halo.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/tanay-fish.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/tanay-pork.jpg"/></p>

<h2>Bus/Car</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Manila &#8594; Tanay</td>
  <td>62</td>
</tr>
<tr>
  <td>Previously</td>
  <td>628</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>690</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Manila (today)</td>
  <td>4.115</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.112.575</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.116.690</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/09/drupal-camp-manila-day-2-drupal-tour-2016</link>
                    <pubDate>Mon, 09 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/09/drupal-camp-manila-day-2-drupal-tour-2016</guid>
                </item>
                                                <item>
                    <title>Drupal Camp Manila Day 1 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>I was impressed with how international the Drupal Camp Manila was, with speakers from ten countries and sponsors from four countries, by far is one the most international events of Drupal I had attended.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-group.jpg"/></p>

<p>The assistance was about 200, again don't trust in my appreciation. I was honor by leading the Drupal Camp Keynote; in my talk, I present about "Why investing in community is good business".</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-keynote.jpg"/></p>

<p>Also, I did a session about Drupal Console, but this time was more advanced than usual, because some attendees from Singapore, Vietnam and Japon already watch the basic introduction during my <a href="enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days/">enzotour16</a></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalconsole-manila.jpg"/></p>

<p>I attended some interesting sessions like Twig in Drupal 8, BeHat, Scrum among others.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-twig.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-behat.jpg"/></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/manila-scrum.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Manila (today)</td>
  <td>5.060</td>
</tr>
<tr>
  <td>Previously</td>
  <td>1.107.515</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>1.112.575</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/05/08/drupal-camp-manila-day-1-drupal-tour-2016</link>
                    <pubDate>Sun, 08 May 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/05/08/drupal-camp-manila-day-1-drupal-tour-2016</guid>
                </item>
                                                                                                                                                                                                                <item>
                    <title>Taipei, Taiwan Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday, I finished my short visit to Hong Kong; Next time I have to reserve more days in this city.</p>

<p><a href="https://www.linkedin.com/in/amouro">Chris Wu</a>, from <a href="https://fliegen.com.tw/">Fliegen</a> help me to organize a Drupal Meetup to talk about <strong>Drupal 8</strong> and <strong>Drupal Console</strong>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/taipei-drupal-meetup.jpeg"/></p>

<p>The audience was small but very receptive, in few days, I will visit a couple of Drupal offices to continue the conversation.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/taipei-metro.jpg"/></p>

<p>Also, I reach 2/3 of my Drupal Tour, only 40 days to finish my tour and go home.</p>

<h2>Airplane</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Hong Kong &#8594; Taipei, Taiwan</td>
  <td>815</td>
</tr>
<tr>
  <td>Previously</td>
  <td>33.941</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>34.756</td>
</tr>
</tbody>
</table>

<h2>Train</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>528</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>528</td>
</tr>
</tbody>
</table>

<h2>Bus/Car</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>628</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>628</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Bangkok, Taipei (today)</td>
  <td>12.440</td>
</tr>
<tr>
  <td>Previously</td>
  <td>980.746</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>993.186</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/29/taipei-taiwan-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Fri, 29 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/29/taipei-taiwan-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                <item>
                    <title>Hong Kong Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>I had the opportunity to participate in the Hong Kong Drupal meetup. I have to say I liked their format; their schedule starts at 7 pm, But they reserve 1 hour to let people talk each other to enforce the networking and to allow people who to have some issues reaching to the place don't miss the sessions.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/hk-meetup-1.JPG"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/hk-meetup-2.JPG"/></p>

<p>The first session was lead by <strong>Jackie Chan</strong> from <a href="http://bootdev.com">BootDev</a> where he share how DrupalCamp China was 2016](http://drupalcampchina.org/drupal%E4%B8%AD%E5%9B%BD%E8%90%A5-2016/sessions/drupalconsole) held in Shanghai; maybe we will see a Drupal day or DrupalCamp Hong Kong soon.</p>

<p>Later on, I have the opportunity to present my session about <a href="http://drupalconsole">Drupal Console</a> including a live demo; People were keen about the product and the reception was incredible.</p>

<p>During day time as part of my sightseeing in Hong Kong I visited the <a href="https://en.wikipedia.org/wiki/Hong_Kong_Museum_of_History">Hong Kong Museum of History</a> and the <a href="https://en.wikipedia.org/wiki/Wong_Tai_Sin_Temple_(Hong_Kong)">Wong Tai Sin Temple</a></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/hk-museum-history.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/wong-tai-sin-temple.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Bangkok (today)</td>
  <td>11.480</td>
</tr>
<tr>
  <td>Previously</td>
  <td>954.506</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>965.986</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/28/hong-kong-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Thu, 28 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/28/hong-kong-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                                                                    <item>
                    <title>Bangkok Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>I am in the second half of my Enzo Tour 2016, the main reason to be in Bangkok was to participate in their Drupal Meetup.</p>

<p>The Drupal meetup was organized by <a href="http://www.fluxus.io/">Fluxus</a>, I met these guys in Mumbai, India during DrupalCon and after that in Hanoi during their first DrupalCamp, so as you can see they are all about community.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/bkk-drupal-meetup.jpg"/></p>

<p>As you can imagine, I did an introduction to Drupal 8.1 and <a href="http://drupalconsole.com">Drupal Console</a></p>

<p>I have to thank you to <a href="http://x-team.com/profile/sven-ryen/">Sven Berg Ryen</a> from Norway who attend this meeting after having a flight of 12 hours from Oslo and be in an immense jet lag.</p>

<p>Before the Drupal Meetup, I did some sightseeing in Bangkok. I went out to the <a href="https://en.wikipedia.org/wiki/Ananta_Samakhom_Throne_Hall">Ananta Samakhom Throne Hall</a> an exhibition of the Masterpieces of Thailand, sorry no pictures because they aren't allowed, but I could tell you I never saw that amount of gold in my life and the quality of pieces is really astonishing.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/ananta-samakhom-throne-hall.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Bangkok (today)</td>
  <td>8603</td>
</tr>
<tr>
  <td>Previously</td>
  <td>880.571</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>889.174</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/22/bangkok-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Fri, 22 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/22/bangkok-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                                                                            <item>
                    <title>Chengdu Drupal Meetup - Drupal Tour 2016</title>
                    <description><![CDATA[<p>After Drupal Camp Chongqing I departure to Chengdu, this city is famous due they host the biggest Panda reservoir in the world, but also they have a local Drupal Community.</p>

<p>To reach Chengdu I took a High-Speed train, operated by <a href="https://en.wikipedia.org/wiki/China_Railway_High-speed]">China Railway High-speed</a>. The service is comfortable and efficient, even the fact I was in <strong>second class</strong> I have a huge space for me and my huge backpack. The train sometimes reaches 296 km by an hour, but you don't feel the speed, at times we run in parallel with a highway, and you can notice the cars looks slow in compare with the train.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/CRH2C.jpg"/></p>

<p>Maybe in the sad news, I have to report I lost my phone. I lost between last subway station and my walk to train station, nobody stole just felt down from my bad I notice because my extra battery charge impact the floor and I hear the sound but due my phone protector I couldn't hear.</p>

<p>Right after arriving in Chengdu, I move towards to the <a href="http://www.cdut.edu.cn/english">Chengdu University of Technology</a>. During this meetup, I have the opportunity to lead an introduction to Drupal 8 and a Introduction to Drupal Console. Thanks to <a href="http://blog.libruce.cn">Bruce</a> becuase he translate to Chinese my words for almost 3 hours and also organize the meetup with <strong>Skip</strong>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/chengdu-meetup.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/bruce-translation.jpg"/></p>

<p>After having a delicious dinner, the locals help me to buy a new phone, I just realize that Lenovo bought Motorola and now and rebranding a new brand of phones named <strong>Zuk</strong> and I bought a <strong>Zuk 1</strong></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/chengdu-new-phone.jpg"/></p>

<h2>Airplane</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>30.293</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>30.293</td>
</tr>
</tbody>
</table>

<h2>Train</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Chongqing, China &#8594; Chengdu, China</td>
  <td>366</td>
</tr>
<tr>
  <td>Previously</td>
  <td>0</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>366</td>
</tr>
</tbody>
</table>

<h2>Bus/Car</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Today</td>
  <td>0</td>
</tr>
<tr>
  <td>Previously</td>
  <td>628</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>628</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Chongqing/Chengdu (today)</td>
  <td>12.887</td>
</tr>
<tr>
  <td>Previously</td>
  <td>840.561</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>853.448</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/18/chengdu-drupal-meetup-drupal-tour-2016</link>
                    <pubDate>Mon, 18 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/18/chengdu-drupal-meetup-drupal-tour-2016</guid>
                </item>
                                                <item>
                    <title>DrupalCamp Chongqing - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday was a big day for Drupal Community in Chongqing, China, due they celebrate their first <a href="2016.drupalchongqing.org">DrupalCamp</a>.</p>

<p>The Drupal community in China in general in just growing and growing and Chongqing community organize this DrupalCamp in 50 days. Their speakers came from Beijing, Shanghai and other major Chinese cities.</p>

<p>One impressive fact is the support of <a href="http://english.cqmu.edu.cn/">Chongqing medical university</a> and more specifically their <strong>Clinical Medicine</strong> program, this program is using Drupal to improve the information system and doing research to connect with Open Hardware, which is quite interesting.</p>

<p>Regarding numbers, the event had about 120+ attendees; this is not an official statistic, is just my appreciation.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcamp_chongqing.jpg"/></p>

<p>I had the honor of being the Keynote in this event, in my session I talk about why "<strong>Investing in the community is a good business</strong>", you can review the slides <a href="http://bit.ly/enzotour16-chongqing">here</a>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcamp-chongqing-keynote.jpg"/></p>

<p>Also, I have the opportunity of talk about <a href="http://drupalconsole.com">Drupal Console</a> project; I lead this session with <a href="http://ranqiangjun.com">Jungle</a> who by the way is the responsible for the Chinese translation of Drupal Console and the leader and co - organizer of this Drupalcamp.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcamp-chongqing-console.jpg"/></p>

<p>Based on some comments I could say this Drupal Camp set a precedent in Drupal Chinese community. Next events over China will try to imitate their level of organization and try to be more official which means in Chinese culture perhaps more political, but maybe that is what is necessary to increase the participation of China in Drupal international community.</p>

<p>Well done Chongqing.</p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Chongqing (today)</td>
  <td>15,209</td>
</tr>
<tr>
  <td>Previously</td>
  <td>825.352</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>840.561</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/17/drupalcamp-chongqing-drupal-tour-2016</link>
                    <pubDate>Sun, 17 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/17/drupalcamp-chongqing-drupal-tour-2016</guid>
                </item>
                                                                                                                                                                                                                                                                                                                    <item>
                    <title>Beijing Day 1 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Last week I learned a term used in China, <a href="http://www.ibtimes.com/apec-blue-skies-fail-cheer-beijing-residents-government-rushes-clean-air-ahead-summit-1721371">APEC Blue Sky</a> in reference a clear sky that happens in China during an APEC meeting in Beijing two years ago. Before landed in Beijing I was a little worried about the quality of air, but, until now I have been so luck; because after two days I have been a good quality of air and almost an APEC blue sky, I still have 8 more days here so I will see how lucky I am.</p>

<p>Yesterday in the morning I was a little frustrated, due my hotel internet connection sucks, and I can't determine how to reach famous sightseeing places in Beijing, so, I decided to sleep a bit more and just leave my hotel ready to attend the Drupal Meetup in Beijing.</p>

<p>The Drupal community was receptive, taking into account that the event was on a Saturday afternoon, and we are in the middle of <a href="https://en.wikipedia.org/wiki/Qingming_Festival">Qingming Festival</a></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/beijing-meetup.jpg"/></p>

<p>Besides me, a local business owner presents about some Drupal projects he is working.</p>

<p>As you can imagine, we went to take an early dinner or a late lunch in my case, as always delicious food.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/beijing-meetup-dinner.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Beijing (today)</td>
  <td>8.793</td>
</tr>
<tr>
  <td>Previously</td>
  <td>622.078</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>630.871</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/04/03/beijing-day-1-drupal-tour-2016</link>
                    <pubDate>Sun, 03 Apr 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/04/03/beijing-day-1-drupal-tour-2016</guid>
                </item>
                                                                                                                                                                        <item>
                    <title>DrupalCamp China - Drupal Tour 2016</title>
                    <description><![CDATA[<p>The main reason to be in Shanghai is to participate in DrupalCamp China. The DrupalCamp China was organized in conjunction with BarCamp; the organizers split the event into two rooms, one for Chinese speakers and one for English speakers.</p>

<p>The keynote was presented by <a href="https://www.linkedin.com/in/jacobredding">Jacob Reeding</a> and talk about the second wave of Open Source and the engagement with the community as companies and individuals.</p>

<p>After the group photo, I have the opportunity to meet with some online friends from Shanghai. Also, I meet with some people that organizing events in Chengdu and Chongqing where I am going to participate, and we have a delicious lunch Chinese style.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/china-friends.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcamp-china-lunch.jpg"/></p>

<p>In the afternoon, I attend the session of <a href="https://www.adammalone.net/about">Adam Malone</a> about how to do an effective demo; I love this session because he shows us how to sell Drupal by showing possibilities and not teaching about Drupal in low level.</p>

<p>Right after, I have the opportunity to talk about <a href="http://drupalconsole.com">Drupal Console</a> project, I was real that I can show the Drupal Console in action using the Chinese language, the room was totally occupied, and I got good questions at the end.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcampchina-console-session.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Shanghai (today)</td>
  <td>4.931</td>
</tr>
<tr>
  <td>Previously</td>
  <td>548.938</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>553.869</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/03/27/drupalcamp-china-drupal-tour-2016</link>
                    <pubDate>Sun, 27 Mar 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/03/27/drupalcamp-china-drupal-tour-2016</guid>
                </item>
                                                                                                                                                                                            <item>
                    <title>Osaka Day 1 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday I arrived in Osaka by bus without any inconvenience; I will stay in an a room provides by <a href="https://annai.co.jp/">Annai Inc</a> community leaders in Japan.</p>

<p>Instead of going out to do some sightseeing, I prefer to stay to do some laundry, share lunch with Annai Inc team and get prepare for the Drupal Cafe No 44 organized by <strong>Annai Inc</strong>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/annai-lunch.jpg"/></p>

<p>At night, I have a session about <a href="http://console.com">Drupal Console</a>, <a href="https://www.facebook.com/satoshi.kino">Satoshi Kino</a> helps me with translation to Japanese, that was a nice touch; there were almost 20 attendees, all eager for understanding the Drupal Console details. Later <strong>Annai</strong> sponsor some drinks and food for everybody in the activity.</p>

<p>Especial thanks to Kyoko and Satoshi for being awesome organizers in Tokyo and Osaka.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/osaka_meetup.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/annai_enzo.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupal-cafe-osaka.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Osaka (today)</td>
  <td>7.847</td>
</tr>
<tr>
  <td>Previously</td>
  <td>427.114</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>434.961</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/03/19/osaka-day-1-drupal-tour-2016</link>
                    <pubDate>Sat, 19 Mar 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/03/19/osaka-day-1-drupal-tour-2016</guid>
                </item>
                                                                                                            <item>
                    <title>Tokyo Day 1 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday was officially my first day in Tokyo in terms I could try to visit some places. According to the plan I did with my the help of <a href="http://www.visitacity.com/">Visit a City</a> I went to <a href="https://en.wikipedia.org/wiki/Sens%C5%8D-ji">Sensoji Temple</a> and <a href="https://en.wikipedia.org/wiki/Asakusa_Shrine">Asakusa Shrine</a> both ancient buildings with a lot of culture and history Behind.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/tokio-temple-day-1.jpg"/></p>

<p>After that I tried to visit the <a href="https://en.wikipedia.org/wiki/Tokyo_National_Museum">Tokyo National Museum</a>, but, was closed and almost all museum in Japan on Mondays. So, I continue walking in <a href="https://en.wikipedia.org/wiki/Ueno_Park">Uedo Park</a></p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/cherries-flowers.jpg"/></p>

<p>The day was cool and raining all days and sometimes windy, so winter resists to go out in Tokyo.</p>

<p>I did a change of my planes and walked towards <a href="https://en.wikipedia.org/wiki/Akihabara">Akihabara</a> a famous place for Anime and Manga shops.</p>

<p>Before to go to do shopping I took a lunch, and I got the best Ramen I tried in my life.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/ramen-tokio.jpg"/></p>

<p>With my stomach full I bought some animes for my son and daughter.</p>

<p>As second change in my schedule, I decided to go to <a href="https://en.wikipedia.org/wiki/Tokyo_Metropolitan_Government_Building">Tokyo Government Office</a> which have two observation desk with free access. What I  have to say is it was good, but the weather the view wasn't  good, I will try to return tomorrow.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/tokyo-london.jpg"/></p>

<p>To finish my day, I attend the Drupal Cafe #43 in Tokio to talk about Drupal Console project as you can imagine; The assistance was better that I was expending about 20+.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupal-cafe-43.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Tokyo (today)</td>
  <td>21.773</td>
</tr>
<tr>
  <td>Previously</td>
  <td>358.350</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>380.123</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/03/14/tokyo-day-1-drupal-tour-2016</link>
                    <pubDate>Mon, 14 Mar 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/03/14/tokyo-day-1-drupal-tour-2016</guid>
                </item>
                                                                                                                                <item>
                    <title>Seoul Day 3 - Drupal Tour 2016</title>
                    <description><![CDATA[<p>Yesterday, Seoul was cooler than the day before, So, we decided to start our day late and look for a brunch in <a href="https://en.wikipedia.org/wiki/Bukchon_Hanok_Village">Bukchon Hanok Village</a> and ancient neighbourhood in Seoul.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/bukchon-breakfast.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/bukchon.jpg"/></p>

<p>After wall inside this ancient place, we decided to continue with our tour in palaces visiting <a href="https://en.wikipedia.org/wiki/Changdeokgung">Changdeokgung Palace</a> and <a href="https://en.wikipedia.org/wiki/Unhyeongung">Unhyeongung Royal Residence</a>.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/changdeokgung.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/unhyeongung.jpg"/></p>

<p>At the end of the noon, we walk across <a href="https://en.wikipedia.org/wiki/Insa-dong">Insa-dong street</a> and drunk coffee.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/insa-dong.jpg"/></p>

<p>At night, we move to another area of Seoul to participate in a meetup of <a href="https://groups.drupal.org/korean-users">Korean Drupal user group</a> to talk about <strong>Drupal Console</strong> project.</p>

<p>They surprise me because <a href="https://www.drupal.org/user/261577">Yeongtaek Hong</a> share a new translation of <a href="http://drupalconsole.com">Drupal Console</a> project to the Korean Language, and Kim another member of the community print two banner one about the meetup and one about my [tour](http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days/).</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalconsole-korean.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/seoul-meetup.jpg"/>
<br/><br/>
<img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/enzotour-banner.jpg"/></p>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Seoul (today)</td>
  <td>13.537</td>
</tr>
<tr>
  <td>Previously</td>
  <td>301.975</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>315.512</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/03/10/seoul-day-3-drupal-tour-2016</link>
                    <pubDate>Thu, 10 Mar 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/03/10/seoul-day-3-drupal-tour-2016</guid>
                </item>
                                                                                                                                <item>
                    <title>1st DrupalCamp Vietnam</title>
                    <description><![CDATA[<p>Yesterday I had the opportunity of participate in the first Drupal Camp Vietnam in Hanoi.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupalcampvn.jpg"/></p>

<p>The event had a turnout about 170 attenders, with around 20% of women participation, caveats those numbers are my appreciation, not official stats.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupacampvn-program.jpg"/></p>

<p>In addition to my assistance, I had the option to present a session about <a href="http://drupalconsole.com">Drupal Console</a> project, I did this presentation in English with translation to Vietnamese by <a href="http://twitter.com/webtomme">Tom Tran</a>.</p>

<p>A Drupal guy for Philipines, <a href="https://www.drupal.org/u/geraldvillorente">Gerald Villorente</a> also did a session in English with translation toVietnamese by local Docker community member, due, his session was about Docker.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/gerald-docker.jpg"/></p>

<p>The rest of the sessions were in Vietnamese, and with the help of organizers they give me a hand to understand what they were saying in their slides, also after a small talk with members of the Drupal community I learn some interested fact I want to share with you.</p>

<p>There is a local organization named <a href="http://vfossa.vn">FOSSA</a> with the primary objective to promote the usage of free and open source software in  Vietnam, because, contrary to what I thought, even Vietnam is a communist country, the government usage of FOSS is only about 20%.</p>

<p>The Vietnamese CMS ranking</p>

<p><strong>General</strong></p>

<ol>
<li>Wordpress.</li>
<li><a href="https://nukeviet.vn/">Nukeviet</a> </li>
<li>Drupal and joomla </li>
</ol>

<p><strong>Government</strong></p>

<ol>
<li>Sharepoint </li>
<li>Liferay </li>
<li>Nukeviet</li>
</ol>

<p>One session I want to remark is a case study about <a href="http://bayo.vn">Bayo</a>, which is a startup-oriented to create travel community for Vietnamese people who travel around southeast Asia built in Drupal, with more that 30k user started in June 2015.</p>

<p>At night, I had some beers with <strong>Gerald</strong> and told me how he transform his life from a gardener in a resort in the Philippines to a Drupal Developer. All via a mentor and self-training. his is a living proof of with determination you can do an 180 degrees change in your life, all you need is passion and termination.</p>

<p>In conclusion, this camp was a good first DrupalCamp for their community, of course, there a lot of space to increase the Drupal penetration in Vietnam, but the realization of this kind of events is a huge jump towards that objective.</p>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Hanoi (today)</td>
  <td>9.056</td>
</tr>
<tr>
  <td>Previously</td>
  <td>240.807</td>
</tr>
<tr>
  <td><strong>Total</strong></td>
  <td>249.863</td>
</tr>
</tbody>
</table>
]]></description>
                    <link>http://enzolutions.com/articles/2016/03/05/1st-drupalcamp-vietnam</link>
                    <pubDate>Sat, 05 Mar 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/03/05/1st-drupalcamp-vietnam</guid>
                </item>
                                                                                                                                                                                                                                                                                                                                                                                                                        <item>
                    <title>New York - Drupal Tour 2016</title>
                    <description><![CDATA[<p>I am very excited to report the beginning of my tour <a href="http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days">Around the Drupal World in 120 Days</a>.</p>

<p>As I read recently on a random post in Facebook. "A trip have three stages."</p>

<ol>
<li>When you plan the trip</li>
<li>When you live the trip </li>
<li>When you remember the trip </li>
</ol>

<p>So I am living the second part of my trip and I want to share with you what I did in this short time (48 hours) in New York, maybe could help other travelers.</p>

<h2>La Guardia Airport</h2>

<p>This was my first time in this airport I could say a small and friendly airport, I don't have any problem, and they have staff that can provide you some tourist information.</p>

<p>I bought a <a href="http://web.mta.info/metrocard">MetroCard</a>, which is valid for buses and subway; they have to machines to buy that card on opposite sides of the airport terminal B, the machine near to bus stop only operate with credit cards or coin. The metro card has a cost of $1 and you put what you want on top.</p>

<p>There three buses lines operating from the airport and the ride from the airport is free is you have a MetroCard.</p>

<p>I took the M60 bus to try to reach the Astoria Boulevard metro station, but be careful the driver announces the Astoria Boulevard at the beginning of the boulevard, and if you get off the bus, you will notice that you are not in Astoria Boulevard station. I made that mistake, but don't worry if you do that, I took the next bus M19 using the MetroCard I bought before and finally reach the subway station to take the line G to reach Brooklyn my destination, that line connect with Manhattan and many other places.</p>

<p>In Brooklyn, I meet up again with Vanessa and Edwin. They were so kind to share with me their spare room. BTW. Edwin was one of my first clients when I decided to start <a href="http://anexusit.com">Anexus</a> with Kenny my business partner a workshop 100% oriented to Drupal, and he remains as a friend.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/edwin-vanessa-small.jpg"/></p>

<h2>Phase2 and Digital Pulp</h2>

<p>My second day was good, even the -4 Celsius degrees, but I guess I was better to prepare than my last visit in NYC two years ago during NYCamp 2014 because at that time, in theory, was 7 Celsius degrees but for me was crazy freezing.</p>

<p>I did a quick visit to <a href="http://phase2technology.com">Phase2</a> one of the most well known Drupal Companies in USA and <strong>Anexus</strong> partner. I just pass over to say hello and of course, bring some Costa Rican coffee.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/molly.png"/></p>

<p>My lunch was at <a href="https://foursquare.com/v/lys-chinese-restaurant/540ce065498e413c5fa7929d">Ly's</a> Chinese Szechuan Restaurant, and I have a "Beef stew soup noodle" was so good.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/nyc-soup.png"/></p>

<p>After that I visited <a href="digitalpulp.com">Digital Pulp</a> to present about <a href="http://drupalconsole.com">Drupal Console</a> a Drupal project where I am co-maintainer, I was invited by <a href="https://github.com/FatherShawn">Shawn Duncan</a> one of our contributors.</p>

<p>The session was good, and I got some good feedback from backend and frontend developers.</p>

<p><img style="float:left; margin-right: 20px; width: 47%; margin-bottom: 20px;" src="http://enzolutions.com/assets/img/digitalpulp-1.jpg"/></p>

<p><img style="float:left; margin-right: 20px; width: 47%; margin-bottom: 20px;" src="http://enzolutions.com/assets/img/digitalpulp-2.jpg"/></p>

<p>If you want to see the slides of that presentation go to <a href="http://bit.ly/enzotour16-nyc">http://bit.ly/enzotour16-nyc</a>.</p>

<h2>Last Day and my trip to India.</h2>

<p>I am going to Departure from Newark Airport in New Jersey; I already visit this airport twice on my way to Boston. Travel from NJ to Mumbai will be my longest trip in an airplane 11.5 hours non-stop, so I am full of movies and books. I will tell you in another post my experiences.</p>

<p>I have to say the Newark airport is nice but not friendly with travelers, because there is not free wifi available.
At least I can use 30 min free connection from <a href="http://www.boingo.com">Boingo</a>.</p>

<h2>Airplane</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (Kilometers)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Costa Rica &#8594; NYC</td>
  <td>3.575</td>
</tr>
<tr>
  <td>Previously</td>
  <td>0</td>
</tr>
</tbody>
</table>

<h2>Walking</h2>

<table>
<thead>
<tr>
  <th></th>
  <th>Distance (steps)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>NYC</td>
  <td>24.926</td>
</tr>
<tr>
  <td>Previously</td>
  <td>0</td>
</tr>
</tbody>
</table>

<p>Sounds a lot but I have more in front of me to explore.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/02/12/new-york-drupal-tour-2016</link>
                    <pubDate>Fri, 12 Feb 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/02/12/new-york-drupal-tour-2016</guid>
                </item>
                                                <item>
                    <title>Soy candidato a la Drupal Association 2016</title>
                    <description><![CDATA[<p>Por segunda vez me presento al proceso de elecciones para <strong>Director at Large</strong> dentro de la Asociación Drupal, para elegir a un candidato de la comunidad a su junta directiva por un periodo de dos años.</p>

<p>A continuación quiero presentarles mi motiviación.</p>

<p><a href="https://assoc.drupal.org/election/2016-director-large-election/candidate/enzo">English version</a></p>

<h1>Motivacion.</h1>

<p>El año pasado propuse mi nombre en las elecciones para este mismo cargo, desafortunadamente no conseguí el apoyo suficiente pero alcance la <a href="https://assoc.drupal.org/blog/holly.ross.drupal/2015-large-election-data-released">3ra posición</a>.</p>

<p>A pesar de que yo no conseguí ser elegido; Hice todo lo posible para encontrar una manera de cumplir mis promesas de campaña, acerca de buscar formas de promover Drupal en comunidades de países en via desarrollo; animándoles a resolver sus propios problemas, sin perder el vínculo con la comunidad internacional de Drupal.</p>

<p>Finalmente, decidí honrar mis promesas, y organize la gira <a href="http://enzolutions.com/articles/2016/01/25/la-vuelta-al-mundo-drupal-en-120-dias/">La vuelta al mundo Drupal en 120 días</a>. El objetivo principal de este viaje es la promoción de Drupal 8, del proyecto <a href="http://drupalconsole.com">Drupal console</a> y estar en contacto con las comunidades para aprender sobre que necesitan para hacer crecer su comunidad y cómo las personas desde el exterior pueden tratar de ayudarles a crecer como comunidad.</p>

<p>Yo ya empecé el viaje visitando las comunidades en New York, EE.UU., India, Singapur, Vietnam, Corea del Sur y Japón. Todavía me restan siete países y 11 ciudades como parte de la gira. Pero, mi aprendizaje acerca de las comunidades comenzó meses antes de que tomara mi primer vuelo, por supuesto, tenía que hablar y estar en constante comunicación con las comunidades locales, esta parte fue difícil ya que en algunos países las comunidades son muy cerradas y su relación con el resto de las comunidades  Drupal alrededor del mundo es casí nula.</p>

<p>Lo que pude extraer de esas comunicaciones fueron las siguientes ideas:</p>

<ul>
<li><p>Ellos están más que felices y complacidos de recibir a los visitantes que quieran aprender de sus comunidades y traer algo para compartir en términos de conocimiento.</p></li>
<li><p>Lamentablemente ellos se sienten aislados y abandonados de la Asociación de Drupal; básicamente, están viviendo en islas, usando un CMS que se encontraron casi por accidente.</p></li>
</ul>

<p>Entonces, ¿qué ideas o proyectos voy a intentar apoyar dentro de la  Asociación de Drupal?</p>

<ul>
<li><p>Librar los multi idiomas en http://drupal.org, debemos hablar tantos idiomas como sea posible. La falta de contenido multilingüe es la primera queja que he encontrado después de hablar con personas de países que no hablan inglés. Se puede decir que esto es costoso, pero las comunidades están dispuestos a proporcionar ayuda a hacerlo posible.</p></li>
<li><p>Establecer una herramienta que permita a las personas contactarse y estar en sintonía con las comunidades locales, estoy pensando en algo entre, g.d.o y http://drupical.com</p></li>
<li><p>Incluír un cambio al código de conducta de la comunidad Drupal para evitar que los usuarios traten de forzar a otros usuarios a solo usar Inglés. Actualmente, los usuarios que tratan de decir algo sin usar el Inglés, inmediatamente recibir una notificación no oficial de que sólo se permite el Inglés.</p></li>
<li><p>Definir becas que permita a conferencistas capacitar personas en países en via de desarrollo, especialmente si hablan el idioma nativo.</p></li>
</ul>

<p>Si consigo una posición en la Asociación Drupal, voy a apoyar proyectos en esa dirección. Basado en mi experiencia de 8 años trabajando con Drupal como un desarrollador, Líder de la comunidad y  co-propietario de una empresa Drupal en un país en via de desarrollo; quiero traer a Asociación Drupal una perspectiva diferente sobre nuestros retos e ideas sobre cómo mejorar la presencia de Drupal en América Latina , África y Asia.</p>

<h1>Experiencia</h1>

<p>Me encontré con Drupal cuando trabaja en un proyecto muy difícil, simplemente porque los plazos eran muy  cortos (sorpresa, sorpresa) y no tenía idea de cómo empezar a trabajar en esa cosa llamada Drupal. Pero una vez que entendí el CMS, tuve la oportunidad de abrir el camino y enseñar a otros.</p>

<p>El Proceso fue muy frustrante, pero el Proyecto fue Entregado con un ligero retraso; como resultado termine amando la plataforma de CMS.</p>

<p>Mi primer evento de la comunidad fue en 2009 en la 1ª Drupal Camp Centroamericano en Managua, Nicaragua donde pude contribuir presentando dos conferencias y aprendi mucho sobre la comunidad Drupal y el grado de fiabilidad del producto.</p>

<p>Después de dos años haciendo Drupal de forma independiente, tomé la decisión de iniciar un negocio con mi amigo <strong>Kenny Abarca</strong>, la nuestra fue la primera empresa Drupal en Costa Rica en el 2010. <a href="http://anexusit.com">Anexus</a> y creo que de Centroamérica. En *Anexus** lidero el aspecto técnico de la empresa, pero, tengo que usar muchos sombreros, siendo CTO mi título oficial. Uno de mis papeles favoritos es sin embargo, el de desarrollador Drupal, donde tengo a motivar, liderar, supervisar y animar a mis compañeros al mismo tiempo que programo al menos 8 horas cada día.</p>

<p>Justo después del Drupal Camp Centroamericano en Nicaragua, empecé a organizar Drupal Meetup en Costa Rica, así como la construcción de la comunidad Drupal desde la base. Como resultado, se celebró la 1ª Drupal Camp en Costa Rica (3ª Drupalcamp Centroamericano) a finales de 2011. Hemos organizado ya 5 DrupalCamp desde la fecha.</p>

<p>Por último, la comunidad Drupal decidió crear una ONG llamada "Drupal Costa Rica" donde tengo el título Presidente. El uso de la ONG se centrara en facilitar las tareas de organización de las actividades de Drupal en Costa Rica.</p>

<h1>Acerca de mi</h1>

<p>Co-fundador de la empresa Drupalera <a href="http://anexusit.com">Anexus</a>. Tengo 39 años, casado y padre de dos hijos: Axel y Zoe. Me entretengo dando largos paseos por los pasillos de los Drupal Grupos y tengo la pasión para armar eventos para la comunidad.</p>

<p>Soy un colombiano de nacimiento y Costarricense por elección; He pasado los últimos 14 años viviendo en esa estrecha franja de tierra entre la América del Norte y del Sur.</p>

<p>Me metí en Drupal 5 a principios de 2008, después de trabajar durante muchos años la construcción de sitios web desde cero usando PHP y después de contribuir en un par de proyectos de PHP con la intención de automatizar la forma en que se desarrollaron sitios web.</p>

<p>En resumen, soy un tipo que sabe Drupal desde tres puntos de vista diferentes, desde el punto de desarrollador, líder comunitario y propietario de la empresa de Drupal.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/02/09/soy-candidato-a-la-drupal-association-2016</link>
                    <pubDate>Tue, 09 Feb 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/02/09/soy-candidato-a-la-drupal-association-2016</guid>
                </item>
                                                <item>
                    <title>Form altering will not be the same in Drupal 8 after using Webprofiler</title>
                    <description><![CDATA[<p>One of the most common tasks as a Drupal developer is alter a form created by Drupal core of by a contrib module to 
enable us to include our business logic or  just remove something annoying for our clients.</p>

<p>In Drupal 8 we still have to the hook <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21form.api.php/function/hook_form_alter/8">hook_form_alter</a>, I know, I know the whole idea of Drupal 8 is to remove hooks, but we still have some of them around.</p>

<p>But, this article is not about to discuss that hook must exist or not, Is there and we have to use until is replaced by something else.</p>

<p>Doing a form alter require a one significant and vital information the <strong>FORM_ID</strong>. Usually, we can get this information implementing a generic form alter and print all form_ids loaded and choose the desired one, or, check in form source code to verify the id in method <strong>getFormId</strong> as you can see in the following method</p>

<pre><code>  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'search_block_form';
  }

</code></pre>

<p>That doesn't look like an old fashion way? indeed, it's the old fashion way. Drupal 8 allow us to have excellent third party tools, and I want to talk about <a href="https://www.drupal.org/project/devel">Webprofiler</a>, which in combination with the <a href="http://drupalcosole.com">Drupal Console</a> project, provide us a clever way to determine and generate our form alter, fast and efficient.</p>

<p><a href="https://www.drupal.org/u/lussoluca">Lussoluca</a> created the webprofiler module, and is an effective implementation of <a href="http://symfony.com/doc/current/cookbook/profiler/index.html">Symfony profiler</a>, using this component to write and extension to provide the Drupal things that Symfony profiler ignore. Webprofiler start as an independent project at <a href="https://www.drupal.org/project/webprofiler">https://www.drupal.org/project/webprofiler</a>, but the last December was merged as a submodule of Devel module; honestly I don't understand because there is not any technical dependency, IMHO webprofiler must have an independent project.</p>

<h1>Generate a standard form alter.</h1>

<p>Anyhow, let me show you how to generate a form alter using the <strong>Drupal Console</strong> without <strong>Webprofiler</strong>.</p>

<p>Using the command <strong>generate:form:alter</strong> we could generate an implementation of hook hoo_form_alter in any desired module, let show you who to execute this command avoiding interactive mode</p>

<pre><code>$ drupal generate:form:alter  --module="testing" --inputs="name:name type:textfield label:Name options: description: maxlength:64 size:64 default_value: weight:0" --no-interaction
</code></pre>

<p>As result, we will get the following code:</p>

<pre><code>use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_form_alter() on behalf of testing.module.
 */
function testing_form_alter(&amp;$form, FormStateInterface $form_state, $form_id) {
    // Change form id here
    if ($form_id == 'form_test_alter_form') {
        drupal_set_message('form_test_form_alter() executed.');

        $form['name'] = array(
          '#type' =&gt; 'textfield',
          '#title' =&gt; t('Name'),
          '#description' =&gt; t(''),
          '#maxlength' =&gt; 64,
          '#size' =&gt; 64,
          '#weight' =&gt; '0',
        );

    }
}
</code></pre>

<p>Checking out, the code above we can see that is just an example, and you need to change the proper form id, but, at least, we have a starting point and example about how to add new form elements.</p>

<h1>Generate a form alter using webprofiler.</h1>

<h2>Installing and enabling Webprofiler.</h2>

<p>Firstly, you need to get the latest version of devel module, because as I said before, webprofiler is a submodule of devel. Let's do that using <strong>Drupal Console</strong>.</p>

<pre><code>$ drupal module:download devel --latest
</code></pre>

<p>Secondly, just enable the webprofiler module as you can see in the following snippet.</p>

<pre><code>$ drupal module:install webprofiler
</code></pre>

<h2>Generating a form alter using Webprofiler</h2>

<p>After enabling the module we just need to navigate to your website visiting the pages with forms we can to alter, when Webprofiler is installed you will get a toolbar at the bottom as you can see in the following image.</p>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/drupal_webprofiler.png"/></p>

<p>Now, If we want to include an extra field in theme configuration, we just need to visit page http://example.comv/admin/appearance/settings/bartik tp store form information in Webprofiler inventory.</p>

<p>Using the command <strong>generate:form:alter</strong> but now in interactive mode, the command will detect that webprofiler module is installed, and we will provide us a list of form id available and give us the option to remove some fields from form, as you can check out in the following image.</p>

<pre><code>drupal generate:form:alter --module=testing
</code></pre>

<p><img style="margin-right: 20px;" src="http://enzolutions.com/assets/img/console_generate_webprofiler.png"/></p>

<p>The interactive mode provides a list of form ids available; you can use the arrows on your keyboard to navigate through options available.</p>

<p>The code generated now will be more precise and as you can see using the Webprofiler inventory we could decide to remove some form elements and still include new ones. The code generated will be similar to the following snippet.</p>

<pre><code>use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_form_FORM_ID_alter() on behalf of testing.module.
 * @see \Drupal\system\Form\ThemeSettingsForm method buildForm at core/modules/system/src/Form/ThemeSettingsForm.php
 */
function testing_form_system_theme_settings_alter(&amp;$form, FormStateInterface $form_state) {
    drupal_set_message('testing_form_system_theme_settings_alter() executed.');

    $form['color']['#access'] = FALSE;

}
</code></pre>

<p>As you can see the sky is the limit we can create commands to do a lot of magic using Webprofiler inventory.</p>

<p>I hope do you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/02/01/form-altering-will-not-be-the-same-in-drupal-8-after-using-webprofiler</link>
                    <pubDate>Mon, 01 Feb 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/02/01/form-altering-will-not-be-the-same-in-drupal-8-after-using-webprofiler</guid>
                </item>
                                                <item>
                    <title>La vuelta al mundo Drupal en 120 dias</title>
                    <description><![CDATA[<p>Hace casi un año, en el 2015, propuse mi nombre en las <a href="https://assoc.drupal.org/election/8/candidates">elecciones</a> para <strong>Director at  Large</strong> en la <a href="https://assoc.drupal.org">Asociación Drupal</a>. El lema de mi campaña fue <strong>Déjame ser tu voz</strong> con la idea de tratar de representar áreas en el mundo fuera de los países se desarrollados.</p>

<p>Puedes revisar el video de mi propuesta.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/h32uIUtePB0" frameborder="0" allowfullscreen></iframe>

<p>Lamentablemente, no he alcance los votos suficientes para ser elegido. Pero, la idea siguio en mi cabeza; ¿Cómo puedo tratar de llevar el conocimiento a las comunidades emergentes en Open Source y específicamente en Drupal? ¿Cómo pude animar a la gente a crear sus soluciones, utilizando su lengua materna como una herramienta para empoderar a su comunidad local?</p>

<p>Por otra parte, ¿Cómo pude hacer esto sin el aval de ser un <strong>Director at  Large</strong> para la Asociación Drupal?</p>

<p>Bueno, llegué a la conclusión de que si quiero hacer un cambio, no tengo que pedir permiso a nadie, y de la misma manera que aquí en Costa Rica empezamos la comunidad Drupal Costa Rica con nuestra pasión como unico aval para construir esta idea.</p>

<p>Por esa razón, he decidido honrar las promesas hechas en campaña, grabadas para la posteridad en vídeo, incluyendo una meta adicional: promover la herramienta en la que he estado co-trabajando durante casi 18 meses, el proyecto Drupal console](http://drupalconsole.com).</p>

<p><strong>Drupal Console</strong> also includes an important component for local communities empowerment enabling people use the tool in their mother language.</p>

<p>El proyecto <strong>Drupal console</strong> también incluye un componente importante para el empoderamiento de las comunidades locales,  permitiendo que las personas utilizen la herramienta en su lengua madre.</p>

<p>Afortunadamente, tengo el apoyo de mi socio <strong>Kenny Abarca</strong> en <a href="http://anexusit.com">Anexus</a> para tener un período de cuatro meses en una agenda semi-sabático, en terminos al trabajo, apoyare uns 4 a 5 horas por día en tareas de soporte a nuestro equipo acerca de Drupal 8.</p>

<p>Que voy a hacer con el resto de mi tiempo, bueno, acordamos que estaria viajando en varios países edesarrollados y en vía de desarrollo para participar en Drupal Camps y Drupal Meetups, para intercambiar experiencias con las empresas y desarrolladores locales y de esta forma tratar de hacer lo que prometi el año pasado, además de promover el proyecto Drupal console.</p>

<p>Además, intentare alentar a las comunidades locales para construir documentación técnica por sí mismos usando su lengua materna para reducir la brecha digital.</p>

<p>Con la idea definida, creamos esta agenda para visitar dieciocho ciudades en trece países y tres continentes, queriamos incluir África, pero debido a restricciones de presupuesto no fue posible.</p>

<iframe src="http://enzolutions.com/embed/enzo-tour-2016/index.html" height="360px" width="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>

<ol>
<li>New York, Estados Unidos / Feb 10 - Feb 12 &#8594; <a href="https://drupalconsole.com/content/drupal-console-introduction-session">Drupal Console Introducción</a></li>
<li>Bombay India / Feb 13 - Feb 20 &#8594; <a href="https://events.drupal.org/node/8600">DrupalCon BOF</a></li>
<li>Singapure, Singapure / Feb 21 - Feb 26 &#8594; <a href="http://groups.drupal.org/node/504398">Drupal Meetup</a> </li>
<li>Hanoi, Vietnam / Feb 27 - Mar 6 &#8594; <a href="http://drupalcamp.vn">DrupalCamp</a></li>
<li>Seul, Corea del sur / Mar 7 - Mar 13 &#8594; <a href="http://groups.drupal.org/node/507923">Drupal Meetup</a> </li>
<li>Tokyo, Japan / Mar 14 <a href="https://www.facebook.com/events/1680328558921229/">Drupal Cafe</a></li>
<li>Osaka, Japan / Mar 18 - Mar 22 &#8594; <a href="https://www.facebook.com/events/541411579373436/">Drupal Cafe</a> </li>
<li>Shanghai, China / Mar 23 - Mar 31 &#8594; <a href="http://drupalcampchina.org/drupal%E4%B8%AD%E5%9B%BD%E8%90%A5-2016/sessions/drupalconsole">DrupalCamp</a> </li>
<li>Beijing, China / Apr 1 - Apr 10 &#8594; <a href="http://www.thinkindrupal.com/node/5974">Drupal Meetup</a></li>
<li>Chongqing, China / Apr 11 - Apr 16 &#8594; <a href="http://2016.drupalchongqing.org/">DrupalCamp</a></li>
<li>Chengdu, China / Apr 17 - Apr 19 &#8594; <a href="https://groups.drupal.org/node/508536">Drupal Meetup</a></li>
<li>Bangkok, Thailandia / Apr 20 - Apr 26 &#8594; <a href="http://www.meetup.com/Drupal-Meetup-Bangkok/events/230041865">Drupal Meetup</a> </li>
<li>Hong Kong, Hong Kong / Apr 25 - Apr 29 &#8594; <a href="http://www.meetup.com/drupalhk/events/229309147">Drupal Meetup</a></li>
<li>Taipei, Taiwan / Apr 30 - May 3 &#8594; <a href="https://drupaltaiwan.org/forum/20160419/11612">Drupal Meetup</a></li>
<li>Manila, Filipinas  / May 4 - May 10 &#8594; <a href="http://2016.drupalcampmanila.com/">DrupalCamp Manila 20016</a></li>
<li>Jakarta, Indonesia / May 11 - May 14 &#8594; <a href="https://www.facebook.com/events/890804504375940/">Drupal Meetup</a></li>
<li>Yogyakarta, Indonesia / May 15 - May 17 &#8594; <a href="https://www.facebook.com/events/1762670827297587/">Drupal Meetup</a></li>
<li>Bali, Indonesia / May 18 - May 21 &#8594; <a href="https://www.facebook.com/events/244028239283984/">Drupal Meetup</a></li>
<li>Melbourne, Australia / May 22 - May 30 &#8594; <a href="http://www.meetup.com/drupalmelbourne/events/231089192">Drupal Meetup</a></li>
<li>Sydney, Australia / May 31 - Jun 6  &#8594; <a href="http://www.meetup.com/drupalsydney/events/230340301">Drupal Meetup</a> </li>
<li>Mexicali, Mexico / Jun 9 - June 12  &#8594; <a href="https://drupalconsole.com/events/drupalconsole-sprint-mexicali-mexico">DrupalConsole Sprint</a></li>
</ol>

<p>Voy a tomar dos mini vacaciones en Tasmania y en Hawai, para completar un viaje de 124 días.</p>

<p>Después de completar este viaje, espero poder ayudar a aquellas comunidades que planeo visitar a mejorar su participación en la Comunidad Drupal global y para mí, mejorar mi visión del mundo.</p>

<p>Si usted se está preguntando si tengo intención de proponer mi nombre para el próximo <a href="https://assoc.drupal.org/blog/holly.ross.drupal/2016-drupal-association-board-election-details">proceso electoral</a> en Asociación Drupal. Para ser honesto, todavía estoy pensando en la posibilidad.</p>

<p>Si usted está alrededor de esas ciudades, y quiere hablar de Comunidades Drupal, Drupal 8 y Drupal Console, por favor no dude en enviarme un correo electrónico a enzo@anexusit.com</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/01/25/la-vuelta-al-mundo-drupal-en-120-dias</link>
                    <pubDate>Mon, 25 Jan 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/01/25/la-vuelta-al-mundo-drupal-en-120-dias</guid>
                </item>
                                                <item>
                    <title>Getting node comments programmatically in Drupal 8</title>
                    <description><![CDATA[<p>This article belongs to tips and tricks section in Drupal 8 because I will explain to you how to get entity comments from a particular entity node.</p>

<p>Before to start to code, I want to clarify that in Drupal 8 comments could be inside <strong>Content type</strong> definition as a standard field.</p>

<p>I will handle comments here as a separate entity. To get comments I will use <a href="https://api.drupal.org/api/drupal/core!lib!Drupal.php/function/Drupal%3A%3AentityQuery/8">EntityQuery</a> using this approach, we will avoid writing explicit SQL queries, and our code will portable.</p>

<pre><code>$cids = \Drupal::entityQuery('comment')
   -&gt;condition('entity_id', $ticketID)
   -&gt;condition('entity_type', 'node')
   -&gt;sort('cid', 'DESC')
   -&gt;execute();

$comments = [];

foreach($cids as $cid) {
 $comment = Comment::load($cid);

 $comments[] = [
     'cid' =&gt; $cid,
     'uid' =&gt; $comment-&gt;getOwnerId(),
     'subject' =&gt; $comment-&gt;get('subject')-&gt;value,
     'body' =&gt; $comment-&gt;get('field_comment_body')-&gt;value,
     'created' =&gt; $comment-&gt;get('created')-&gt;value
 ];
}
</code></pre>

<p>Let's review the code above in detail; As you can see, is required to specify to what kind of entity we are trying to get comments, that tell us that in Drupal 8 is possible to link comments to any entity.</p>

<p>Additionally, I have specified the Entity ID required to get comments, is possible add more conditions; this is useful taking in count that comments are entities and is possible that comments have customs fields with extra information.</p>

<p>When we create the EntityQuery, we define what kind of entity we want to process, as the result the query execution will return a list primary keys of entities matching the conditions, in this case, the main key is represented by cid.</p>

<p>Using the list of comments ids or cids, we load the comment object. I just traverse the option to create an arbitrary array, only to show how do you have to access to comment entity property, usually is required to use the method get, but there are some exceptions like comment owner ID.</p>

<p>I hope do you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/01/20/getting-node-comments-programmatically-in-drupal-8</link>
                    <pubDate>Wed, 20 Jan 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/01/20/getting-node-comments-programmatically-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>Around the Drupal World in 120 Days</title>
                    <description><![CDATA[<p>Almost a year ago in 2015, I proposed my name in the <a href="https://assoc.drupal.org/election/8/candidates">elections</a> for Director at  Large in <a href="https://assoc.drupal.org">Drupal Association</a>. The slogan of my campaign was <strong>Let me be your voice</strong> with the idea to try to represent areas in the world outside develop countries.</p>

<p>Check the video of my proposal.</p>

<iframe src="https://player.vimeo.com/video/121906640" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>

<p><a target="_blank" href="http://v.youku.com/v_show/id_XMTQ0ODU1MTUwNA==.html">Version for China</a></p>

<p>Sadly, I didn't get enough votes to get elected. But, the idea remains in my head; How I could to try to bring the knowledge to those emerging communities in Open Source and specifically in Drupal? How I could encourage people to create their solutions, using their language as a tool to empower their local community?</p>

<p>Moreover, How I could do this without the endorsement of being a Director at Large for Drupal Association?</p>

<p>Well, I got the conclusion that if I want to do a change and don't need to ask permission to anybody, and in the same way here in Costa Rica we started the Drupal Costa Rica community with our passion as our endorsement to build this idea.</p>

<p>For that reason, I decided to put my money where my mouth is, regarding what I said in my video campaign, including an additional goal: promote the tool I have been co-working for almost 18 months the <a href="http://drupalconsole.com">Drupal Console</a> project.</p>

<p><strong>Drupal Console</strong> also includes an important component for local communities empowerment enabling people use the tool in their mother language.</p>

<p>Fortunately, I got support from my business partner <strong>Kenny Abarca</strong> at <a href="http://anexusit.com">Anexus</a> to have a period of four months with a semi-sabbatical schedule to regarding work. Having 4-5 hours per day in duties to support our team regarding of Drupal 8 adoption and implementation.</p>

<p>What I will do with the rest of my time, well, we agree that I will be traveling in several developed and developing countries participating in DrupalCamps, Drupal meetups to exchange experiences with local companies and developers. To try to do what I propose last year and promote the Drupal Console project.</p>

<p>Also, Encouraging local communities to build technical documentation for themselves using their mother language to reduce their digital gap.</p>

<p>With the idea settle, we create this agenda to visit eighteen cities in thirteen countries and three continents, we want to include Africa, but due budgets restrictions wasn't possible.</p>

<iframe src="http://enzolutions.com/embed/enzo-tour-2016/index.html" height="360px" width="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>

<ol>
<li>NYC, USA / Feb 10th - Feb 12th &#8594; <a href="https://drupalconsole.com/content/drupal-console-introduction-session">Drupal Console Introduction</a></li>
<li>Mumbai India / Feb 13th - Feb 20th &#8594; <a href="https://events.drupal.org/node/8600">DrupalCon BOF</a></li>
<li>Singapore, Singapore / Feb 21st - Feb 26th &#8594; <a href="http://groups.drupal.org/node/504398">Drupal Meetup</a> </li>
<li>Hanoi, Vietnam / Feb 27th - Mar 6th &#8594; <a href="http://drupalcamp.vn">DrupalCamp</a></li>
<li>Seoul, South Korea / Mar 7th - Mar 13th &#8594; <a href="http://groups.drupal.org/node/507923">Drupal Meetup</a> </li>
<li>Tokyo, Japan / Mar 14th <a href="https://www.facebook.com/events/1680328558921229/">Drupal Cafe</a></li>
<li>Osaka, Japan / Mar 18th - Mar 22th &#8594; <a href="https://www.facebook.com/events/541411579373436/">Drupal Cafe</a> </li>
<li>Shanghai, China / Mar 23th - Mar 31st &#8594; <a href="http://drupalcampchina.org/drupal%E4%B8%AD%E5%9B%BD%E8%90%A5-2016/sessions/drupalconsole">DrupalCamp</a> </li>
<li>Beijing, China / Apr 1st - Apr 10th &#8594; <a href="http://www.thinkindrupal.com/node/5974">Drupal Meetup</a></li>
<li>Chongqing, China / Apr 11th - Apr 16th &#8594; <a href="http://2016.drupalchongqing.org/">DrupalCamp</a></li>
<li>Chengdu, China / Apr 17st - Apr 19th &#8594; <a href="https://groups.drupal.org/node/508536">Drupal Meetup</a></li>
<li>Bangkok, Thailand / Apr 20th - Apr 25th &#8594; <a href="http://www.meetup.com/Drupal-Meetup-Bangkok/events/230041865">Drupal Meetup</a></li>
<li>Hong Kong, Hong Kong / Apr 25th - Apr 29th &#8594; <a href="http://www.meetup.com/drupalhk/events/229309147">Drupal Meetup</a></li>
<li>Taipei, Taiwan / Apr 30th - May 3th &#8594; <a href="https://drupaltaiwan.org/forum/20160419/11612">Drupal Meetup</a></li>
<li>Manila, Philippines  / May 4th - May 10th &#8594; <a href="http://2016.drupalcampmanila.com/">DrupalCamp Manila 20016</a></li>
<li>Jakarta, Indonesia / May 11th - May 14th &#8594; <a href="https://www.facebook.com/events/890804504375940/">Drupal Meetup</a></li>
<li>Yogyakarta, Indonesia / May 15th - May 17th &#8594; <a href="https://www.facebook.com/events/1762670827297587/">Drupal Meetup</a></li>
<li>Bali, Indonesia / May 18th - May 21st &#8594; <a href="https://www.facebook.com/events/244028239283984/">Drupal Meetup</a></li>
<li>Melbourne, Australia / May 22nd - May 30th &#8594; <a href="http://www.meetup.com/drupalmelbourne/events/231089192">Drupal Meetup</a></li>
<li>Sydney, Australia / May 31st - June 6th  &#8594; <a href="http://www.meetup.com/drupalsydney/events/230340301">Drupal Meetup</a></li>
<li>Mexicali, Mexico / Jun 9th - June 12th  &#8594; <a href="https://drupalconsole.com/events/drupalconsole-sprint-mexicali-mexico">DrupalConsole Sprint</a></li>
</ol>

<p>I will take two mini holidays in Tasmania and Hawaii, to complete a trip of 124 days.</p>

<p>After complete this trip, I expect to help those communities I plan to visit to help to improve their participation in global Drupal Community and for me, well, enhance my vision of the world.</p>

<p>If you are wondering if I plan to propose my name for next <a href="https://assoc.drupal.org/blog/holly.ross.drupal/2016-drupal-association-board-election-details">election process</a> in Drupal Association. To be honest, I am still considering the possibility.</p>

<p>If you are around those cities, and you want to talk about Drupal Communities, Drupal 8 and Drupal Console, please don't hesitate to email me to enzo@anexusit.com</p>
]]></description>
                    <link>http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days</link>
                    <pubDate>Tue, 19 Jan 2016 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2016/01/19/around-the-drupal-world-in-120-days</guid>
                </item>
                                                <item>
                    <title>How to get content type fields in Drupal 8</title>
                    <description><![CDATA[<p>The creation of custom logic for our customer sometimes requires a certain level of automatisation in terms that our logic must be flexible to support changes in the data structure.</p>

<p>In Drupal 8 the most common way to represent data is using node entities, and we could create different types of content types or bundles for node entities.</p>

<p>Each content type could increase or decrease the amount and type of fields assigned to each content type, and our code must be prepared to handle that situations.</p>

<p>I will explain to you, how to get content type definition and use that information to flatten a node object into an array.</p>

<h1>Getting content type fields definition</h1>

<p>Firstly I will create a function to get fields definition for a content type machine name provided, of course, you can implement this function as a method in your classes.</p>

<pre><code>function contentTypeFields($contentType) {
    $entityManager = Drupal::service('entity.manager');
    $fields = [];

    if(!empty($contentType) {
        $fields = array_filter(
            $entityManager-&gt;getFieldDefinitions('node', $contentType), function ($field_definition) {
                return $field_definition instanceof FieldConfigInterface;
            }
        );
    }

    return $fields;      
}
</code></pre>

<p>In this case, I am only interested in use field machine name, but you can do a different approach to doing something with field definition itself.</p>

<p>Also, I use node as a hard-coded entity type, but you can use any entity, to get their bundle field definition.</p>

<h1>Flatten node</h1>

<p>Using the field definition array, we can get all node values and assign to an array. I will use an imaginary content type machine name <em>ticket</em></p>

<pre><code>use Drupal\node\Entity\Node;
use Drupal\field\FieldConfigInterface;

// Load node
$node = Node::load($ticketID);

$fields = contentTypeFields('ticket'); // Replace your content type machine name here.

$ticket['title'] = $node-&gt;get('title')-&gt;value;
foreach($fields as $fieldID =&gt; $field){
    $ticket[$fieldID] = $node-&gt;get($fieldID)-&gt;getValue();
}

print_r($ticket);

</code></pre>

<p>The code above will produce an output similar to this</p>

<pre><code>Array
(
    [title] =&gt; This is an unassigned ticket
    [field_description] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [value] =&gt; Create a ticket with no one assigned to make sure the system handles it well
                )

        )
    [field_status] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [target_id] =&gt; 2
                )

        )

    [field_ticket_type] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [target_id] =&gt; 9
                )

        )

)
</code></pre>

<p>After transform node into an innocuous array, you can add or remove any information required.</p>

<p>This kind of transformation is useful in Drupal 8, to skip some validation in the object render to avoid content injection.</p>

<p>Maybe you are thinking why not use function <a href="http://php.net/manual/en/function.get-object-vars.php">get_object_vars</a>, well all properties are protected and are only accessible using get method, get_object_vars only return public properties, so doesn't work for our purpose.</p>

<p>Another idea could be, just use an array casting to transform node object into an array, but if you try to do that and exception is thrown with the following error message.</p>

<p><strong>A fatal error occurred: Could not normalize object of type Drupal\Core\Field\BaseFieldDefinition, no supporting normalizer found.</strong></p>

<p>I hope did you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/12/22/how-to-get-content-type-fields-in-drupal-8</link>
                    <pubDate>Tue, 22 Dec 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/12/22/how-to-get-content-type-fields-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to get a list of content types in Drupal 8</title>
                    <description><![CDATA[<p>Continuing with the series of articles about how to do Drupal development common tasks using Drupal 8 way I will share today how you could get a list of content types available programmatically.</p>

<p>Using the following code you could print the complete list</p>

<pre><code>$contentTypes = \Drupal::service('entity.manager')-&gt;getStorage('node_type')-&gt;loadMultiple();

$contentTypesList = [];
foreach ($contentTypes as $contentType) {
    $contentTypesList[$contentType-&gt;id()] = $contentType-&gt;label();
}

print_r($contentTypesList);
</code></pre>

<p>After executing the code above you will output similar to the following snippet:</p>

<pre><code>Array
(
    [article] =&gt; Article
    [page] =&gt; Basic page
)
</code></pre>

<p>Off course in my example I Just want a list of values machine-name -> human label, but you can manipulate the <a href="https://api.drupal.org/api/drupal/core!modules!node!src!Entity!NodeType.php/class/NodeType/8">Drupal\node\Entity\NodeType</a> entity to do advanced things.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/12/03/how-to-get-a-list-of-content-types-in-drupal-8</link>
                    <pubDate>Thu, 03 Dec 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/12/03/how-to-get-a-list-of-content-types-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to execute an external PHP application inside Symfony/Drupal in a Sandbox</title>
                    <description><![CDATA[<p>I know this could be a weird situation, but, believe or not sometimes is required execute an external application, maybe because that application doesn't have and API or just because you just need to execute that and get the results.</p>

<p>An easy thought could be just include the main file of that application, but maybe that is not possible because both applications could use similar namespaces or try to reload same libraries, for solve that is required to try to execute that application using a kind of <strong>Sandbox</strong>.</p>

<p>To accomplish that task, we can use the Symfony <a href="http://symfony.com/doc/current/components/process.html">Process</a> Component.</p>

<p>Let me show you a small piece of code that could be included in your Symfony or Drupal 8 application.</p>

<pre><code>use Symfony\Component\Process\PhpProcess;

$php_script = file_get_contents($php_file);

$phpProcess = new PhpProcess($php_script, $documentroot);
$phpProcess-&gt;run();
$output = $phpProcess-&gt;getOutput();
</code></pre>

<p>Firstly, we must read a PHP file path, defined in variable <em>$php_file</em> then using function <em>PhpProcess</em> execute that script using a specific DocumentRoot for our external application, that will avoid any issue of missing classes.</p>

<p>Secondly, the process is executed and finally we could get the output after our external application is completed, this process is synchronous.</p>

<p>Internally the Symfony component Process try to allocate the php-cli in your system to execute your application.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/11/27/how-to-execute-an-external-php-application-inside-symfonydrupal-in-a-sandbox</link>
                    <pubDate>Fri, 27 Nov 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/11/27/how-to-execute-an-external-php-application-inside-symfonydrupal-in-a-sandbox</guid>
                </item>
                                                <item>
                    <title>How to manipulate an Entity:Block programmatically in Drupal 8</title>
                    <description><![CDATA[<p>This is my first post after Drupal 8 got his first official release, now it's time to start to do some basic stuff using the Drupal 8 way.</p>

<p>Even I have been working a lot with Drupal 8 core, there are some typical things that I found still a little bit strange. But being honest if more my fault that Drupal 8 fault; All we have just to adjust own mental mindsets.</p>

<p>Today I want to show you how to deal with Block in Drupal 8 because yesterday I spent several hours trying to understand how to manipulate a block to extend a functionality for <a href="http://drupalconsole.com">Drupal Console</a> project.</p>

<h1>Get a list of blocks</h1>

<p>This looks an easy task, but there are some considerations you must take into account.</p>

<p>First, Do you need a list of all <em>Blocks</em> available or all <em>Blocks</em> enabled?</p>

<p>Why this separation is important, well as you maybe know or hear in Drupal 8 blocks are plugins and use <a href="https://www.drupal.org/node/1882526">annotations</a> to expose to Drupal 8 their existence. Therefore, we could get a list of blocks but they will not be <a href="https://api.drupal.org/api/drupal/core!modules!block!src!Entity!Block.php/8">Entity:Block</a> objects, we could get just their definition, this is important because you can't manipulate them, so you just can use as extra information in your logic.</p>

<p>Only blocks that are enabled and assigned to a theme and in a region are Entity:Block instances.</p>

<h2>Get available blocks</h2>

<p>Using the service <strong><a href="https://api.drupal.org/api/drupal/core!core.services.yml/service/plugin.manager.block/8">plugin.manager.block</a></strong> we will get all blocks available definition.</p>

<pre><code>$blockManager = \Drupal::service('plugin.manager.block');
$contextRepository = \Drupal::service('context.repository');

// Get blocks definition
$definitions = $blockManager-&gt;getDefinitionsForContexts($contextRepository-&gt;getAvailableContexts());

print_r($definitions['help_block']);
</code></pre>

<p>Executing the code above we will an output for <em>help_block</em> similar to the following snippet.</p>

<pre><code>Array
(
    [admin_label] =&gt; Drupal\Core\StringTranslation\TranslatableMarkup Object
        (
            [string:protected] =&gt; Help
            [translatedMarkup:protected] =&gt;
            [options:protected] =&gt; Array
                (
                )

            [stringTranslation:protected] =&gt;
            [arguments:protected] =&gt; Array
                (
                )

        )

    [category] =&gt; Help
    [derivative] =&gt;
    [id] =&gt; help_block
    [class] =&gt; Drupal\help\Plugin\Block\HelpBlock
    [provider] =&gt; help
)
</code></pre>

<p>As you can see is valuable information about the block but it's not a real Entity:Block instances.</p>

<h2>Get a list of all Entity:Block available</h2>

<p>Using <a href="https://api.drupal.org/api/drupal/core!lib!Drupal.php/function/Drupal%3A%3AentityQuery/8">Drupal:entityQuery</a> class, we can build a kind of SQL query for a specific entity in this case for Block entities. The following piece of code gets the full list of blocks available.</p>

<pre><code>$ids = \Drupal::entityQuery('block')-&gt;execute();
</code></pre>

<p>Off course we can filter the results, for instance, we could use the condition plugin to fetch all block related with help module, as you can see in the following snippet of code.</p>

<pre><code>$ids = \Drupal::entityQuery('block')
    -&gt;condition('plugin', 'help_block')
    -&gt;execute();

print_r($ids);
</code></pre>

<p>After executing the code above we could get an output similar this:</p>

<pre><code>Array
(
    [bartik_help] =&gt; bartik_help
    [himalaya_help] =&gt; himalaya_help
    [seven_help] =&gt; seven_help
)
</code></pre>

<p>I got three Entity:Block ids, related to the three themes I have enabled in my system Bartik, Seven and <a href="https://www.drupal.org/project/himalaya">Himalaya</a>.</p>

<h1>Loading an Entity:Block</h1>

<p>Until now we get definition of blocks and Entity:Block ids, but not a real Entity:Block, let me show you how do that using the Drupal 8 class use <a href="https://api.drupal.org/api/drupal/core%21modules%21block%21src%21Entity%21Block.php/class/Block/8">Drupal\block\Entity\Block</a> as you can see below.</p>

<pre><code>use Drupal\block\Entity\Block;
$block = Block::load('bartik_help');
print_r($block);
</code></pre>

<p>The code above load the Entity:Block for <strong>bartik_help</strong>, if you execute this code in your custom module you will get an output like this.</p>

<pre><code>Drupal\block\Entity\Block Object
(
    [id:protected] =&gt; bartik_help
    [settings:protected] =&gt; Array
        (
            [id] =&gt; help_block
            [label] =&gt; Help
            [provider] =&gt; help
            [label_display] =&gt; 0
        )

    [region:protected] =&gt; content
    [weight:protected] =&gt; -30
    [plugin:protected] =&gt; help_block
    [visibility:protected] =&gt; Array
        (
        )
......
......
    [dependencies:protected] =&gt; Array
        (
            [module] =&gt; Array
                (
                    [0] =&gt; help
                )

            [theme] =&gt; Array
                (
                    [0] =&gt; bartik
                )

        )

    [provider] =&gt;
)
</code></pre>

<h1>Create an Entity:Block</h1>

<p>Last but not least, I will show you how to create an Entity:Block from code definition.</p>

<p>Imagine did you created a block plugin using <strong>Drupal Console</strong> with id default_block. Using the following command.</p>

<pre><code>$ drupal generate:plugin:block
</code></pre>

<p>If you want to enable that generated block programmatically, you can use the following snippet of code.</p>

<pre><code>$blockEntityManager = \Drupal::service('entity.manager')-&gt;getStorage('block');
$block = $blockEntityManager-&gt;create(
  array(
      'id'=&gt; $plugin_id,
      'plugin' =&gt; $plugin_id,
      'theme' =&gt; $theme
  )
);
$block-&gt;setRegion('content');
$block-&gt;save();
</code></pre>

<p>Besides, I decided to assign the default_block inside Content region for theme Bartik, after creating the Entity:Block.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/11/21/how-to-manipulate-an-entityblock-programmatically-in-drupal-8</link>
                    <pubDate>Sat, 21 Nov 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/11/21/how-to-manipulate-an-entityblock-programmatically-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>Understanding migrations in Drupal 8</title>
                    <description><![CDATA[<p>As you know Drupal 8 was released at Nov 19 / 2015 (finally).</p>

<p>One of the most recurrent questions is <strong>"It's time to create new projects in Drupal 8"</strong>, but there is another difficult question. <strong>"How I can migrate my current Drupal 7/6/* to Drupal 8"</strong></p>

<p>To try to answer that question let me explain a little bit how Migration works in Drupal 8.</p>

<h1>Modules required</h1>

<p>Drupal 8 provide in their core modules the <strong>Migrate</strong> module, this module provide a mini framework to be user to migrate from <em>Any source</em> to Drupal 8. I said ANY because this module itself doesn't have any logic related to Drupal stuff.</p>

<p>The idea is if you plan to migrate from a specific source like Drupal, Wordpress, CQ5 etc you must write an integration to handle the transformation of content into Drupal 8 structure.</p>

<p>Fortunately for us at least we have a Drupal 8 core module related to Drupal named <strong>Migrate Drupal</strong>, this module contains some Migrate plugin to run the migration process between older Drupal versions to Drupal 8, but this module doesn't contain migration definitions since Drupal 8 beta 13</p>

<p>Therefore, the first step you need to do is install these modules, I will use the project <a href="http://drupalconsole.com">Drupal Console</a> for this tasks and I will continue using some commands available related with migration.</p>

<pre><code>$ drupal module:install migrate migrate_drupal
</code></pre>

<h1>Where I can find migrations</h1>

<p>After install modules Migration and Migrate Drupal, I guess you are waiting for something in UI to start to handle your migrations. Sadly there is nothing inside Drupal Core to provide a UI for migration, this responsibility relies on two contributed modules <a href="https://www.drupal.org/project/migrate_plus">Migrate Plus</a> and <a href="https://www.drupal.org/project/migrate_upgrade">Migrate Upgrade</a>.</p>

<p>Each module apply a different point of view about migrations, both IMHO looks like <em>Migrate Upgrade</em> it's in a more mature state. But, there is always a but, I don't like the idea that you are only available to see all migrations available when you are running the migration itself.</p>

<p>With Drupal just released it's probably that you will be in a stage where you don't really know what are you doing, so I decided to implement some migration command inside <strong>Drupal Console</strong> project with my own point of view.</p>

<h1>Loading migrations</h1>

<p>As I said before I prefer load migrations but without running a migration yet. For that purpose, I did a command <strong>migrate:setup</strong> as you can see in following CLI execution sample.</p>

<pre><code>$ drupal migrate:setup --db-type=mysql --db-host=127.0.0.1 --db-name=plato_tipico --db-user=root --db-pass=root --db-port=3306 --no-interaction
</code></pre>

<p>In the sample above I pass all parameters using inline mode, but if you omit an option, the command will start the interactive mode. Remember to remove the option *--no-interaction** to enable the interactive mode.</p>

<p>The command above will inspect your legacy DB and import all migrations available in Drupal 8 to be used with your legacy DB.</p>

<p>All migration entities created will remain in your system, even after complete a migration process.</p>

<h1>Get list of migrations</h1>

<p>In order to get a list of migrations available in your system, you must execute the following command</p>

<pre><code>$ drupal migrate:debug
</code></pre>

<p>As you can appreciate in the following image some migrations work in more that one Drupal legacy version</p>

<p><img src="http://enzolutions.com/assets/img/console_migrate_debug.png"/></p>

<h1>Execute a migration</h1>

<p>After reviewing your system in term of migrations available, we could execute all migrations available for your legacy system you can execute the following command to start a full migration process.</p>

<pre><code>$ drupal migrate:execute all --db-type=mysql --db-host=127.0.0.1 --db-name=plato_tipico --db-user=root --db-pass=root --db-port=3306 --no-interaction
</code></pre>

<p>Below you can see how looks the migration process.</p>

<p><img src="http://enzolutions.com/assets/img/console_migrate_execute.png"/></p>

<p>The image above shows how the command report what migrations fail and what migration works. As you can see each migration is independent and the migration process is not interrupted if some of them fail.</p>

<p>But if you want to avoid to execute one of more migration to avoid any exception you can use the parameter <strong>--exclude</strong> providing the migration id(s) do you want to exclude, you can get those ids from <em>migrate:debug</em> command.</p>

<p>Moreover, if you only want to execute one or a couple of migrations, just change the parameter <strong>all</strong> for any migration id(s) do you want, this is useful to execute a partial migration after resolve any issues found after executing a full migration process</p>

<h1>Where are located migrations.</h1>

<p>Now you are wondering <strong>"Where are located migration"</strong> if they aren't in Migrate or Migrate Drupal. Well, migrations are allocated in each specific module, for instance if you review in your Drupal Core modules in path <strong>/core/modules/book/migration_templates</strong> you will find some YAML files with the information necessary to create a Migration entity in your system. When you executed the command <strong>migrate:setup</strong> all migration_templates folder were parsed to create Migration Entities.</p>

<h1>Caveats</h1>

<p>Right now there are mostly migrations available for Drupal 6, I guess the bet is related Drupal 6 are more critical to be migrated to Drupal 8.</p>

<p>You can find more Drupal 7 migration proposed as issues in <a href="http://groups.drupal.org/imp">http://groups.drupal.org/imp</a> sandbox, in <a href="http://anexusit.com">Anexus</a> we propose around 70 migration entities for Drupal 7 and 10 of them were already accepted in Drupal 8 core. I promise to provide a list of all our Drupal 7 Migration in few weeks.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/11/02/understanding-migrations-in-drupal-8</link>
                    <pubDate>Mon, 02 Nov 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/11/02/understanding-migrations-in-drupal-8</guid>
                </item>
                                                                    <item>
                    <title>Why languages are so important in technology?</title>
                    <description><![CDATA[<p>For a long time everybody related technology with the US and more specifically with Silicon Valley, and is normal to have iconic concepts. Now, how that concept affect the penetration of technology around the world? Well, one of the most common commandment for non English speakers is "<strong>You</strong> must learn english if you want to work in this industry".</p>

<p>Personally I partially disagree with that conception, I recognize English is important in IT industry because as a web developer if I could at least read English I got access to the latest news and could be in sync with the trendy topics. But also is true that is possible to work in technology industry without any knowledge of English, if you don't believe me, think about China, India, Japan or Russia they use IT every day and most of them only speak their mother language.</p>

<p>It's probably true that they could receive the latest news in technology a little late, but think about this, humankind is sending astronauts to space using <a href="https://en.wikipedia.org/wiki/Soyuz">Soyuz</a> a URSS technology from the 70's, so I guess we can survive with a little delay.</p>

<p>Moreover, what I thought is really bad with the concept of only use English as the medium to communicate your products, of course that only applies to products that plans to conquer the world (insert <a href="https://en.wikipedia.org/wiki/Dr._Evil">Dr. Evil</a> laugh here).</p>

<p>Let's talk about in terms of <a href="http://drupal.org">Drupal</a> which one of the most important Open Source project around the world. I know you will say, well Drupal right now is translated in some level to <a href="https://localize.drupal.org">110+</a> languages which is again a remarkable achievement, but there is always a but, this is only from end user point of view, what about the documentation necessary for people who pretend to support those multilingual site and without knowledge of English.</p>

<p>Again you can quote again the  commandment for non English speakers is "<strong>You</strong> must learn english if you want to work in this industry" in the sense that if you are or pretending to be a web developer you are suppose to be able to handle some level of English. The problem is using that logic we are automatically excluding the <a href="https://en.wikipedia.org/wiki/List_of_languages_by_total_number_of_speakers">85%</a> of population around the world.</p>

<p>Although, these numbers could be justified in terms that 15% is good enough to attend IT needs of other populations, but remember not all of them are IT guys, that would be so sad.</p>

<p>So, why is it so important to try to attend the needs of non English speakers in Drupal community for web development? Well if you check the numbers of penetration of Drupal in Africa and Asia and in some level in Latin America are almost nothing nothing compared to the numbers in the US/Canada and Europe.</p>

<p>If you are wondering why? The answer is easy, if the locals can't understand the logic behind a product, companies or organisations only have two options A) Hire a really expensive developer overseas B) Find an alternative solution with documentation in their language or at least enough resources in their local market trained to maintain that product.</p>

<p>Then, who is guilty for this situation? Maybe the top notch developers in the US, Canada or Europe, because they don't think in that 85% I mention before, <strong>NO</strong> is not their fault, surprise surprise is our fault, correct you don't misread is our fault, you may not know but I am a Colombian living in Costa Rica, so basically a Latin American by definition and I didn't speak a word of English until 9 years ago, so if you speak &amp; understand English and you have access to that information and you don't produce content in your mother language too, then is your fault.</p>

<p>Basically that top notch developers living in the US/Canada and Europe use the language they know, so is our responsibility to translate or produce IT documentation in our languages Spanish, French, Portuguese, Mandarin, Russian, Hindi etc. By doing this kind of contributions we can introduce a huge and positive impact in our societies because that means that 85% of the population will now have access to the edge of technology and that clever guy that we ignore before will join us to produce a change in our developing societies.</p>

<p>Before you ask yourself, well what are you doing in this direction. I maintain my blog in Spanish too, you can check at <a href="http://7sabores.com/blogs/enzo">7sabores.com</a> and in any project I'm involved I try to include the multilingual component, for instance let me show you how you can translate the project <a href="http://drupalconsole.org">Drupal Console</a>, project I have been investing all my "free time", into your mother language.</p>

<h1>Clone Drupal Console Project</h1>

<p>Go to github repository project <a href="https://github.com/hechoendrupal/DrupalConsole">https://github.com/hechoendrupal/DrupalConsole</a> and hit the button <em>fork</em> on the top of page</p>

<h1>Clone your forked repo</h1>

<pre><code>$ git clione git@github.com:YOURUSERHERE/DrupalConsole.git
</code></pre>

<h1>Add your language translation</h1>

<p>Imagine you want translate Drupal Console to <a href="https://en.wikipedia.org/wiki/Hindi">Hindi</a> which is spoken by 250 millions human beings. just follow the following instructions</p>

<pre><code>$ cd DrupalConsoleFolder
$ cp config/translations/console.en.yml config/translations/console.hi.yml
</code></pre>

<p>Now you have a YAML file and you can start to translating string to your mother language.</p>

<h1>Enable DrupalConsole in your language</h1>

<pre><code>$ cd DrupalConsoleFolder
$ ./bin/console init
</code></pre>

<p>The command above generate a config file for Drupal Console located in <strong>~/.console/config.yml</strong>, to enable the new Hindi language, event that language is not part of Drupal Console yet, just change the file and must be locks similar to this snippet.</p>

<pre><code>application:
  environment: 'prod'
  language: hi
  editor: vim
  temp: /tmp
</code></pre>

<h1>Contribute your new language</h1>

<p>You just need to add your language to git and commit to your forked repository github will help you to create a Pull Request, but if you need support for that you can contact us (the maintainers) in our support chat at <a href="https://gitter.im/hechoendrupal/DrupalConsole">https://gitter.im/hechoendrupal/DrupalConsole</a>.</p>

<h1>Sync your changes</h1>

<p>If you are worry because new functionality was added and you are behind, don't worry we added to Drupal Console a command to sync YAML translation files.</p>

<pre><code>$ cd DrupalConsoleFolder
$ ./bin/console yaml:merge console.hi.yml console.en.yml console.hi.yml
</code></pre>

<p>The command above will retain your translation and bring additions to your translation file.</p>

<p>"If you talk to a man in a language he understands, that goes to his head. If you talk to him in his language, that goes to his heart" Nelson Mandela</p>

<p>Muchas gracias for reading this article.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/09/12/why-languages-are-so-important-in-technology</link>
                    <pubDate>Sat, 12 Sep 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/09/12/why-languages-are-so-important-in-technology</guid>
                </item>
                                                <item>
                    <title>How to download remote files with Silex/Symfony and Drupal 8</title>
                    <description><![CDATA[<p>As a new developer of Silex/Symfony, I found really excited some components available to use with <a href="http://silex.sensiolabs.org/">Silex</a> and <a href="symfony.com">Symfony</a>. Today
I want to talk about <a href="https://github.com/guzzle/guzzle">Guzzle</a> and <a href="https://github.com/alchemy-fr/Zippy">Zippy</a>, I am going to show you how to use both 
to download and handle remote zip/gz files in your application.</p>

<h1>Installing with composer.</h1>

<p>Firstly, we need to add the dependency in our <strong>composer.json</strong> file as you can see in the following snippet.</p>

<pre><code>{
    "require": {
        "guzzlehttp/guzzle": "~6.1.1",
        "alchemy/zippy": "0.2.*@dev"
    }
}
</code></pre>

<p>After include these new dependencies you must to run the composer update as you can see in the following bash sentence.</p>

<pre><code>$ composer update
</code></pre>

<h1>Usage</h1>

<p>With those new vendors, you only need to use the, as you can see in the following code.</p>

<pre><code>&lt;?php

use Alchemy\Zippy\Zippy;
use GuzzleHttp\Client;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
</code></pre>

<p>Now inside any method of your class is possible to request to create a client of Guzzle, in general terms Guzzle is like a 
headless browser.</p>

<pre><code>$client =  new Client();

// Destination file to download the release
$destination = tempnam(sys_get_temp_dir(), 'file.') . "tar.gz";

// Get and save file
$client-&gt;get($remote_zip_file_path, ['save_to' =&gt; $destination]);

// Handle Zip file to extract in your system
$zippy = Zippy::load();
$archive = $zippy-&gt;open($destination);
$archive-&gt;extract('./');

try {
  $fs = new Filesystem();
  $fs-&gt;rename($remote_zip_file_name, './' . $new_folder_name);
} catch (IOExceptionInterface $e) {
  print 'Error renaming folder';
}
</code></pre>

<p>In the code above we are assuming we have the path to file and name and we want to rename the folder after extract, the code 
also could be improved include a try catch section for extract process.</p>

<p>As you can see is complex task like that normally is handle by CURL but as you can see Guzzle is more powerful and his implementation is easier to understand.</p>

<h1>Drupal usage.</h1>

<p>Because now <a href="http://drupal.org">Drupal</a> 8 include several Symfony components and other useful components, the code above could be rewrite 
using Drupal 8 wrapper, let me show you the implementation.</p>

<pre><code>use Drupal\Core\Archiver\ArchiveTar;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;

</code></pre>

<pre><code>$client =  new Drupal::httpClient();

// Destination file to download the release
$destination = tempnam(sys_get_temp_dir(), 'file.') . "tar.gz";

// Get and save file
$client-&gt;get($remote_zip_file_path, ['save_to' =&gt; $destination]);

// Handle Zip file to extract in your system
$archiver = new ArchiveTar($destination, 'gz');
$archiver-&gt;extract('./');
fclose($destination . '.tar.gz');

try {
  $fs = new Filesystem();
  $fs-&gt;rename($remote_zip_file_name, './' . $new_folder_name);
} catch (IOExceptionInterface $e) {
  print 'Error renaming folder';
}
</code></pre>

<p>As you can see is similar and we don't have to modify the Drupal 8 composer.json file, to include components because they are
already included in Drupal 8 core.</p>

<p>If you want to check a complete implementation of this logic, you can check the source code of <a href="http://drupalconsole.com">Drupal Console</a> project commands 
<a href="https://github.com/hechoendrupal/DrupalConsole/blob/master/src/Command/Module/DownloadCommand.php">module:download</a> and <a href="https://github.com/hechoendrupal/DrupalConsole/blob/master/src/Command/Site/NewCommand.php">site:new</a></p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/07/09/how-to-download-remote-files-with-silexsymfony-and-drupal-8</link>
                    <pubDate>Thu, 09 Jul 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/07/09/how-to-download-remote-files-with-silexsymfony-and-drupal-8</guid>
                </item>
                                                                    <item>
                    <title>How to remove file documents from SOLR index after been replaced in nodes in Drupal 7</title>
                    <description><![CDATA[<p>If you have revisions enabled in your content types, it keeps all your old files on the server (associated with old revisions), 
so replacing a file definitely is harder.</p>

<p>Even though if you don't have revisions enabled, if you try to remove it and add it again to the node, the name/link is 
updated, but since a file with that name is kept on the server and there is a name duplication, Drupal adds those "_0", 
"_1" etc suffixes to future uploaded versions of that file's name.</p>

<p>In term of node render is not a problem, but in terms of SOLR indexing all those files will be indexed, so instead of get 
one record for a match is possible get N records where N is the number of time do you overwrite the same file.</p>

<p>Then, to resolve this annoying behavior I will show you a solution to remove a file document from SOLR index if a file is 
removed from a node. this solution use <a href="https://www.drupal.org/project/entity">Entity API</a> module so it should be added 
as a dependency in your module .info file.</p>

<pre><code>/**
 * Implements hook_node_update().
 */
function MYMODULE_node_update($node) {

  // Array of content types to act on.
  if (in_array($node-&gt;type, array('article', 'blog_post'))) {
    $wrapper = entity_metadata_wrapper('node', $node);
    $original_wrapper = entity_metadata_wrapper('node', $node-&gt;original);

    // Array of file fields to act on.
    foreach (array('field_public_files', 'field_private_files') as $field) {
      if (!isset($original_wrapper-&gt;{$field})) {
        continue;
      }
      $current_files = array();
      $original_files = array();

      // Get files that were attached to the original node (before update).
      foreach ($original_wrapper-&gt;{$field}-&gt;value() as $file) {
        $original_files[] = $file['fid'];
      }
      // Stop if there were no files previously attached.
      if (empty($original_files)) {
        continue;
      }

      // Get files currently attached to the node (after update).
      foreach ($wrapper-&gt;{$field}-&gt;value() as $file) {
        $current_files[] = $file['fid'];
      }

      // Delete files that were in the original node but were removed during this update
      $deleted_files = array_diff($original_files, $current_files);
      if(!empty($deleted_files)) {
       $env_id = apachesolr_default_environment();
       $solr = apachesolr_get_solr($env_id);
       foreach ($deleted_files as $fid) {
         $file_id = apachesolr_document_id($fid, 'file') . '-' . $node-&gt;nid;

         // Remove file document from SOLR index, re-index is not required,
         $solr-&gt;deleteByQuery("id:$file_id");
       }
      }
    }
      $deleted_files = array_diff($original_files, $current_files);
      if(!empty($deleted_files)) {

    }
  }
}
</code></pre>

<p>The code above react when a node is updated for specific content types and specific fields, using function <a href="http://www.drupalcontrib.org/api/drupal/contributions!entity!entity.module/function/entity_metadata_wrapper/7">entity_metadata_wrapper</a> 
we can determine the information of our node before update and after update.</p>

<p>After calculate if some files were deleted the logic to delete the file document from SOLR is applied, let me see that code 
in detail</p>

<pre><code>$env_id = apachesolr_default_environment();
$solr = apachesolr_get_solr($env_id);
foreach ($deleted_files as $fid) {
 $file_id = apachesolr_document_id($fid, 'file') . '-' . $node-&gt;nid;

 // Remove file document from SOLR index, re-index is not required,
 $solr-&gt;deleteByQuery("id:$file_id");
}
</code></pre>

<p>Firstly, a SOLR object instance is declared. In my example I use the default SOLR instance, if you have more than one instance 
of SOLR is necessary to change the logic to use the proper instance.</p>

<p>Using <a href="http://www.drupalcontrib.org/api/drupal/contributions!apachesolr!apachesolr.module/function/apachesolr_document_id/6">apachesolr_document_id</a> function 
the SOLR ID is calculated using the <strong>fid</strong>, <strong>file</strong> type and providing the specific relation to the specific node subject of 
update, because in some Drupal installs a file could be associated to several nodes.</p>

<p>Finally, using <a href="http://www.drupalcontrib.org/api/drupal/contributions!search_api_solr!includes!solr_connection.interface.inc/function/SearchApiSolrConnectionInterface%3A%3AdeleteByQuery/7">deleteByQuery</a> method the delete from SOLR index is requested, 
this delete is applied immediately, SOLR re-index is not required.</p>

<p>I expect you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/06/17/how-to-remove-file-documents-from-solr-index-after-been-replaced-in-nodes-in-drupal-7</link>
                    <pubDate>Wed, 17 Jun 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/06/17/how-to-remove-file-documents-from-solr-index-after-been-replaced-in-nodes-in-drupal-7</guid>
                </item>
                                                <item>
                    <title>How to customize a Search API filters in Drupal 7</title>
                    <description><![CDATA[<p>Last week I show you <a href="http://enzolutions.com/articles/2015/06/02/how-to-add-customs-fields-to-solr-index-using-entity-api-amp-search-api/">How to add customs fields to SOLR index using Entity API &amp; Search API</a>, 
continues with that line of concept I will to show you how to manipulate a Search API query to include a custom logic in 
your queries.</p>

<p>Firstly, let imagine an hypothetical scenario when we need to run a different query for anonymous and registered users.</p>

<p>Using the custom fields created in previous referenced above we will show today's list of events, in the other hand for 
registered users we will show events in progress (including multi day events) and events coming soon.</p>

<h1>Alter Search API query.</h1>

<p>To modify our queries we will use hook <a href="http://www.drupalcontrib.org/api/drupal/contributions!search_api!search_api.api.php/function/hook_search_api_query_alter/7">hook_search_api_query_alter()</a> 
as you can see in the following example</p>

<pre><code>function MYMODULE_search_api_query_alter(SearchApiQueryInterface $query) {
  global $user;
  // Filter from where the Search API query will be trigger 
  if(arg(0) == 'events' &amp;&amp; arg(1) == 'list') {

    $start_day = strtotime(date('Y-m-d'));

    if($user-&gt;uid == 0 ) {
      $query-&gt;condition('event_start_day', $start_day, '&lt;=');
      $query-&gt;condition('event_end_day', $start_day, '&gt;=');
    }
    else {
      // Select events in progress
      $left_filter = $query-&gt;createFilter('AND');
      $left_filter-&gt;condition('event_start_day', $start_day, '&lt;=');
      $left_filter-&gt;condition('event_end_day', $start_day, '&gt;=');

      // Select events with a start date in the future
      $right_filter = $query-&gt;createFilter('AND');
      $right_filter-&gt;condition('event_start_day', time(), '&gt;=');

      $main_filter = $query-&gt;createFilter('OR');
      $main_filter-&gt;filter($left_filter);
      $main_filter-&gt;filter($right_filter);

      $query-&gt;filter($main_filter);
     }
}     
</code></pre>

<p>Let dissect the previous piece of code. If user is anonymous we will <a href="http://www.drupalcontrib.org/api/drupal/contributions%21search_api%21includes%21query.inc/function/SearchApiQueryInterface%3A%3Acondition/7">SearchApiQueryInterface::condition</a> method 
to include new filters to determine events who are happening today, even though if those events are multi day events.</p>

<p>In the case of registered users, the same method is used but with a subtle variation. By default all conditions are added 
using an <strong>AND</strong> operator which is fine most of the times. However, in our case is required include to groups of validation 
in same query for that reason an <strong>OR</strong> operator is required.</p>

<p>Using the <a href="http://www.drupalcontrib.org/api/drupal/contributions%21search_api%21includes%21query.inc/function/SearchApiQueryInterface%3A%3AcreateFilter/7">SearchApiQueryInterface::createFilter</a> is 
possible create groups of filters using AND or OR operator.</p>

<p>In addition, using <a href="http://www.drupalcontrib.org/api/drupal/contributions%21search_api%21includes%21query.inc/function/SearchApiQueryInterface%3A%3Afilter/7">SearchApiQueryInterface::filter</a> is possible 
include those group of filters inside a <strong>SearchApiQueryInterface</strong> object.</p>

<p>In summary the snippet of code above create a filter similar to</p>

<pre><code>(event_start_day &lt;= time() AND event_end_day &gt;= time()) OR (event_start_day &gt;= time())
</code></pre>

<p>You can create any combination of filters required in your logic.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/06/10/how-to-customize-a-search-api-filters-in-drupal-7</link>
                    <pubDate>Wed, 10 Jun 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/06/10/how-to-customize-a-search-api-filters-in-drupal-7</guid>
                </item>
                                                                    <item>
                    <title>How to add customs fields to SOLR index using Entity API &amp; Search API</title>
                    <description><![CDATA[<p>Nowadays the ability to search in website almost compulsory and most of the times is took for granted.</p>

<p>Using Drupal we have two main options <a href="http://lucene.apache.org/solr/">SOLR</a> and <a href="https://www.elastic.co/">Elastic Search</a>. 
Today I will explore how to work SOLR server.</p>

<p>In Drupal there are two popular modules to connect it with <strong>SOLR</strong> <a href="https://www.drupal.org/project/apachesolr">apachesolr</a> and 
 <a href="https://www.drupal.org/project/search_api">search_api</a> and I decided to use <strong>search_api</strong> to interact with SOLR in 
this article.</p>

<h1>The problem</h1>

<p>Lets imagine this problem: We have an Event content type with a Date field to determine the start date and end date (optional).</p>

<p>Using Search API that field could be indexed without mayor problems, but if we try to do a view to list all event in a date range
 is difficult because Views modules doesn't provide the Between operator for SOLR views, this operator is only available
 for views using <strong>Entity Fields</strong></p>

<h1>The Solution</h1>

<p>Because all events have minute granularity we can't use <strong>equal</strong> operator to determine if an event belongs to a specific day, to 
solve that problem we add extra information to SOLR creating two new fields to store the day event in timestamp in order to be 
able to use the equal operator.</p>

<p>To create these new fields in our node entities we will use <a href="http://drupal.org/project/entity">Entity API</a> and more specifically 
hook <a href="http://www.drupalcontrib.org/api/drupal/contributions!entity!entity.api.php/function/hook_entity_property_info_alter/7">hook_entity_property_info_alter</a>.</p>

<p>Let me show you an implementation example.</p>

<pre><code>/**
 * Implements hook_entity_property_info_alter().
 */
function MYMODULE_entity_property_info_alter(&amp;$info) {
  $info['node']['properties']['event_start_day'] = array(
    'type' =&gt; 'integer',
    'label' =&gt; t('Event Start Day'),
    'sanitized' =&gt; TRUE,
    'getter callback' =&gt; 'MYMODULE_search_api_property_event_start_day_getter_callback',
  );
  $info['node']['properties']['event_end_day'] = array(
    'type' =&gt; 'integer',
    'label' =&gt; t('Event End Day'),
    'sanitized' =&gt; TRUE,
    'getter callback' =&gt; 'MYMODULE_search_search_api_property_event_end_day_getter_callback',
  );
}
</code></pre>

<p>As you can see we are modifying entity definition to include two new properties <strong>event_start_day</strong> and <strong>event_end_day</strong>,
probably the most information is the <strong>getter callback</strong> which is a function used to calculate the proper values for each 
property.</p>

<p>The functions defined in getter callback is used by Search API in the process of indexing to store the value in SOLR index.</p>

<p>Let me show an example of implementation of those getter functions.</p>

<pre><code>/**
 * Getter callback for event start day.
 */
function MYMODULE_search_api_property_event_start_day_getter_callback($item) {
  return strtotime(substr($item-&gt;field_event_date[LANGUAGE_NONE][0]['value'], 0, 10)); 
}

/**
 * Getter callback for event end day.
 */
function MYMODULE_search_search_api_property_event_end_day_getter_callback($item) {
  // Set time at midnight of end day of event
  if($item-&gt;field_event_date[LANGUAGE_NONE][0]['value2'] != '') {
    return strtotime(substr($item-&gt;field_event_date[LANGUAGE_NONE][0]['value2'], 0, 10)) + 86399;
  }
  else {
    return strtotime(substr($item-&gt;field_event_date[LANGUAGE_NONE][0]['value'], 0, 10)) + 86399;
  }
}
</code></pre>

<p>Off course you can implement any logic required here, the variable $item is an object representing a Drupal node.</p>

<p>After clear your cache the new fields will be able to select to be indexed by SOLR, you can do this accessing the URL 
<strong>http://example.com/admin/config/search/search_api/index/YOUR_INDEX/fields</strong> as you can see in the following 
image.</p>

<p><img style="float:left; margin-right: 20px;" src="http://enzolutions.com/assets/img/entity_fields_solr_index_search_api.png"/></p>

<p>When the process of re-index run again the new fields will be stored in SOLR and will be able to be selected in a View.</p>

<p>I hope you found this post useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/06/02/how-to-add-customs-fields-to-solr-index-using-entity-api-amp-search-api</link>
                    <pubDate>Tue, 02 Jun 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/06/02/how-to-add-customs-fields-to-solr-index-using-entity-api-amp-search-api</guid>
                </item>
                                                <item>
                    <title>How to enable CORS in Drupal 8 in non Apache webservers</title>
                    <description><![CDATA[<p>As you maybe know <a href="https://www.drupal.org/drupal-8.0">Drupal 8</a> is almost ready to be released, could be in next
<a href="https://events.drupal.org/barcelona2015">DrupalCon Europe</a> held in Barcelona.</p>

<p>However if you are interested in CORS applications you must to wait until Drupal 8.1 to get native support to CORS in Drupal
more information at <a href="https://www.drupal.org/node/1869548#comment-9365043">issue</a>.</p>

<p>Long time ago I wrote the article <a href="http://enzolutions.com/articles/2014/09/08/how-to-enable-cors-requests-against-drupal-8/">How to enable CORS requests against Drupal 8</a>
but that approach only works in environments using Apache Web Server, but in servers using a non Apache web server like
 <a href="http://nginx.org/">Ngix</a> that solution is useless. Today I face that problem in <a href="https://pantheon.io">Pantheon</a>.</p>

<p>Therefore, I implemented a solution hacking the file index.php to enable CORS. Let me split the change in two stages.</p>

<p>Firstly we have to guarantee the REST method OPTIONS return the proper value, because Drupal 8 can't handle that request right now, check the code to implement that</p>

<pre><code>  if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    $response = new Response(200);
    $response-&gt;headers-&gt;set('Access-Control-Allow-Origin', '*');
    $response-&gt;headers-&gt;set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PATCH, DELETE');
    $response-&gt;headers-&gt;set('Access-Control-Allow-Headers', 'Authorization');
    $response-&gt;send();
    exit;
  }
</code></pre>

<p>Secondly, we have to modify normal requests to enable remote requests from any source desired, as you can see in the following snippet of code</p>

<pre><code>  $response = $kernel
      -&gt;handle($request)
      // Handle the response object.
      -&gt;prepare($request);

  // Enable CORS requests, Change '*' for any specific domain or ip address
  $response-&gt;headers-&gt;set('Access-Control-Allow-Origin', '*');
  $response-&gt;headers-&gt;set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PATCH, DELETE');
  $response-&gt;headers-&gt;set('Access-Control-Allow-Headers', 'Authorization');
</code></pre>

<p>You can apply this <a href="http://enzolutions.com/assets/attaches/d8-cors-index.patch.txt">patch</a> against Drupal 8 beta 10.</p>

<p>I know there are initiatives to enable this feature using contributed modules, but meanwhile we get a definite solution, 
this is temporary solution flexible enough using Drupal 8 style to start using Drupal as backend in a Decoupled solution.</p>

<p>I hope you found this post useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/05/26/how-to-enable-cors-in-drupal-8-in-non-apache-webservers</link>
                    <pubDate>Tue, 26 May 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/05/26/how-to-enable-cors-in-drupal-8-in-non-apache-webservers</guid>
                </item>
                                                <item>
                    <title>Soy candidato por una posición en la Drupal Association como Large director</title>
                    <description><![CDATA[<p>Hoy he decidido nominar a mí mismo como un candidato para un puesto en la <a href="https://assoc.drupal.org/" target="_blank">Drupal Association</a> como <strong>Large Director</strong>.</p>

<p>Puedes leer más sobre el proceso electoral en <a href="https://assoc.drupal.org/blog/holly.ross.drupal/nominations-open-drupal-association-large-director" target="_blank">Nominations Open for Drupal Association At Large Director</a>.</p>

<h1>Fechas importantes</h1>

<ul>
<li>Auto nominaciones: 1 Feb,2015 a 20 Feb, 2015</li>
<li>Elecciones: 9 Mar, 2015 a 20 Mar, 2015</li>
</ul>

<p>Así que permítanme decirles algo acerca de mi y mis motivaciones para proponer mi nombre.</p>

<h1>Acerca de mi</h1>

<p>Colombian de nacimiento, Costarricense por elección, he pasado los últimos 13 años viviendo en esa estrecha franja de tierra entre Norte y Sur América. Co-fundador de AnexusIT.</p>

<p>Tengo 38 años, casado y padre de dos niños: Axel y Zoe. Disfruto de largos paseos por los pasillos de los Drupal Groups y cierta habilidad para la organizar eventos de la comunidad.</p>

<p>Conocí Drupal 6 a principios de 2008 después de trabajar durante muchos años construyendo sitios web desde cero usando PHP y después de muchos meses de contribuir a un par de proyectos de PHP con la intención de automatizar la forma en sitios web son construidos.</p>

<h1>Experiencia</h1>

<p>Mi primer proyecto Drupal fue un verdadero reto, simplemente porque los plazos eran muy apretados (sorpresa, sorpresa) y no tenía ni idea de cómo empezar a trabajar en en Drupal. Aun así oo era el encargado de liderar el camino y enseñar a otros. Rl proceso fue muy frustrante, pero sin embargo el proyecto fue entregado con un retraso de solo unos días, acabé odiando el proyecto, y amando a la plataforma de CMS.</p>

<p>Mi primer contacto con la comunidad fue en 2009 en la primera Drupal Camp Centroamericano en Nicaragua donde hice dos conferencias y donde aprendí mucho sobre la comunidad y qué tan fuerte es el producto podría ser.</p>

<p>Después de dos años trabajando para empresas haciendo Drupal, tomé la decisión de iniciar la primera totalmente orientada a Drupal Costa Rica alrededor de 2010. AnexusIT fue la primera empresa de su tipo en Centroamérica.</p>

<p>En AnexusIT Dirijo las áreas tecnológicas y técnicas de la empresa. Llego a usar muchos sombreros, aunque el director de tecnología es mi título oficial. Mi papel favorito es el de desarrollador Drupal, donde trato de motivar, liderar, supervisar y animar a mis compañeros de trabajo al mismo tiempo que programar al menos 8 horas cada día.</p>

<p>Después de la Drupal Camp Centroamericano en Nicaragua empecé a organizar Drupal Meetups en Costa Rica y en la edificación de la comunidad Drupal en Costa Rica. Como resultado de ello, organizamos el primera Drupal Camp Costa Rica (y tercera Drupal Camp Centroamericano) a finales de 2011. Hemos sido anfitriones de este evento en Costa Rica cada año donde la última edición se celebro en agosto 2014.</p>

<p>Durante todo este tiempo yo diriji a la comunidad en Costa Rica sin un título oficial, porque nos faltaba una estructura formal. Para remediar esto, en enero de 2015, nosotros (la comunidad) fundamos una ONG llamada "Drupal Costa Rica", donde yo soy el co-fundador y primer presidente. Planeamos usar la ONG para facilitar las tareas de la coordinación de las actividades de Drupal en Costa Rica.</p>

<h1>Motivación.</h1>

<p>En los últimos años la Drupal Association ha empezado a orientarse mas al mundo con la inclusión de los miembros de Europa y Australia, pero aunque la visión ahora es más global es aún la visión de personas de países con un alto nivel de desarrollo.</p>

<p>Después de algunas conversaciones con un amigo de Vietnam <a href="http://de.linkedin.com/in/webtomme/" target="_blank">Tom Soqyu</a> acerca de las experiencias en actividades destinadas a la construcción de una comunidad de Drupal y tareas orientadas a crear el primer Drupal en Vietnam detectamos que a pesar de la distancia nos enfrentamos a problemas similares debido a que vivimos en países no desarrollados o de mercados emergentes si desea utilizar otro término.</p>

<p>Entonces, ¿qué ideas que apoyaré en asociación Drupal, Bueno me encantan iniciativas para patrocinar conferencistas que permitan la formación de personas en los países emergentes, especialmente si hablan el idioma del país emergente como por ejemplo francés y Inglés en muchos países de África. Si obtengo una posición en la Drupal Association voy a apoyar proyectos en esa indole.</p>

<p>Así que basado en mi experiencia de 5 años trabajando con Drupal developer, Líder de una Comunidad y propietario de empresa en un país emergente, quiero llevar a la Drupal Association una perspectiva diferente acerca de nuestros retos e ideas sobre cómo mejorar la presencia de Drupal en América Latina, África y Asia.</p>

<h1>Contácteme</h1>

<p>No dude en hacerme cualquier pregunta a través de Facebook, Twitter, correo electrónico o utilizando los comentarios en está entrada de blog.</p>

<p>Como se puede imaginar le estoy pidiendo que voten por mí. Pero también los invito a comprobar todos los candidatos y determinar cual coincide mejor con su forma de pensar y sentir. También no se olvide de invitar a sus amigos a votar.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/02/03/soy-candidato-por-una-posicion-en-la-drupal-association-como-large-director</link>
                    <pubDate>Tue, 03 Feb 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/02/03/soy-candidato-por-una-posicion-en-la-drupal-association-como-large-director</guid>
                </item>
                                                <item>
                    <title>Running for a position on Drupal Association At Large Director</title>
                    <description><![CDATA[<p>Today I decided to nominate myself as a candidate for a position on <a href="https://assoc.drupal.org/" target="_blank">Drupal Association</a> At <strong>Large Director</strong>.</p>

<p>You can read more about the election process at <a href="https://assoc.drupal.org/blog/holly.ross.drupal/nominations-open-drupal-association-large-director" target="_blank">Nominations Open for Drupal Association At Large Director</a>.</p>

<h1>Important dates</h1>

<ul>
<li>Self Nominations: 1 February,2015 through 20 February, 2015</li>
<li>Elections process: 9 March, 2015 through 20 March, 2015</li>
</ul>

<p>So let me tell you something about my and my motivations to propose my name.</p>

<h1>About Me</h1>

<p>Colombian by birth, Costa Rican by choice, I have spent the last 13 years living in that narrow piece of land between North and South America. I co-founded and have been running a successful Drupal workshop called AnexusIT. I am 38, married and father of two brilliant kids: Axel and Zoe. I enjoy long walks through the hallways of Drupal Groups and have a knack for putting together community events.</p>

<p>I got into Drupal 6 in early 2008 after working for many years building websites from scratch using PHP and after many months contributing to a couple of PHP projects with the intention to automate the way websites were built.</p>

<h1>Experience</h1>

<p>My first Drupal project was a real challenge simply because the deadlines were very tight (surprise surprise) and I had no idea how to start working on that thing. I was even the one who had to lead the way and teach others. Anyway, the process was very frustrating but even that the project was delivered with a delay of a few days I ended up hating the project but loving the CMS platform.</p>

<p>My first contact with the community was in 2009 at the 1st Drupal Camp Centroamericano in Nicaragua were I did two lectures and learn a lot about the community and how strong the product could be.</p>

<p>After two years working for other’s companies doing Drupal, I took the decision to start the first Drupal oriented workshop in Costa Rica around 2010. AnexusIT was the first company of it’s kind in Central America. I lead the technological and technical areas of the company. I get to wear many hats but Chief Technology Officer is my official title. My favorite role though, is Drupal developer, where I get to motivate, lead, supervise and encourage my peers while still coding for at least 8 hours every single day.</p>

<p>After the Drupal Camp Centroamericano in Nicaragua I started to organising Drupal Meetups in Costa Rica and building up the Drupal community in Costa Rica. As result, we organised   the 1st Drupal Camp Costa Rica (and 3rd Drupal Camp Centroamericano) in late 2011. We have been hosting this event in Costa Rica yearly with the latest edition being held on August 2014.</p>

<p>During all this time I was leading the community in Costa Rica without an official title, because we were lacking a formal structure. To remediate that, in January 2015, we (the community) founded a NGO called “Drupal Costa Rica” where I am the co-founder and first President. We are planning on using the NGO to facilitate the chores of putting together Drupal activities in Costa Rica.</p>

<h1>Motivation</h1>

<p>In recent years the DA has started looking more world-oriented with the inclusion of members from Europe and Australia, but even that the vision is still through the eyes of people from high develop countries.</p>

<p>After some conversations with a friend from Vietnam <a href="http://de.linkedin.com/in/webtomme/" target="_blank">Tom Soqyu</a> about experiences of activities aimed at building a Drupal community and tasks oriented to create the First Drupal in Vietnam we detect we face similar problems because we live in non developer countries or emerging markets if you want to use other term.</p>

<p>So what ideas I will support in Drupal association, well I love initiatives to sponsor speakers to training people in emergent countries specially if they speak the language of emerging country and french and english in many countries in africa. If I get a position in Drupal Association I will support project in that direction.</p>

<p>So based in my experience of 5 years working with Drupal as Developer, Community Lead and Company Owner in an emergent country I want to bring to DA a different perspective about our challenges and ideas about how to improve the presence of Drupal in Latin America, Africa and Asia.</p>

<h1>Contact me</h1>

<p>Feel free to ask me any question via facebook, twitter, email or using the comments in this post.</p>

<p>So as you can imagine I'm asking you to vote for me. But also I invite you to check all candidates and determine who match better with your mindset and your feeling. Also don't forget to invite your friends to vote.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/02/03/running-for-a-position-on-drupal-association-at-large-director</link>
                    <pubDate>Tue, 03 Feb 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/02/03/running-for-a-position-on-drupal-association-at-large-director</guid>
                </item>
                                                <item>
                    <title>What is Drupal Console for me</title>
                    <description><![CDATA[<p><img style="float:left; margin-right: 20px;;" src="http://enzolutions.com/assets/img/drupal_console_logo.png"/> Maybe you hear about the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> or maybe not because is an independent project related with <a href="https://www.drupal.org/drupal-8.0">Drupal 8</a>.</p>

<p>If you are a older Drupal user/developer you could find some similarities with <a href="https://github.com/drush-ops/drush" target="_blank">Drush</a> Project, and to be honest there are some similarities.</p>

<p>But if you are a <a href="http://symfony.com">Symfony</a> developer you will find some similarities with <a href="http://symfony.com/doc/current/components/console/introduction.html" target="_blank">Console Component</a> and actually it's what it is, Drupal Console is an implementation of Symfony Component to meet the Drupal 8 Way.</p>

<p>The Drupal Console, embrace the principles of Drupal 8 about using Symfony 2 components and other libraries to solve the commons problems instead to reinvent the wheel for everything, that concept is called <a href="http://fuseinteractive.ca/blog/im-lazy-here-have-pie" target="_blank">PIE</a> ( Proudly Invented Elsewhere).</p>

<p>Using the Symfony <a href="http://symfony.com/doc/current/components/console/introduction.html" target="_blank">Console Component</a> <a href="http://dmouse.net/">David Flores</a> and <a href="http://jmolivas.com/" target="_blank">Jesus Olivas</a> start a project to implement the same concept from Symfony to Drupal 8.</p>

<p>One of the incentives to create the project Drupal Console was have a pet project to force them to learn the Drupal 8 way.</p>

<p>But now the project is not a pet project anymore, you can see the full list of contributors at <a href="https://github.com/hechoendrupal/DrupalAppConsole/graphs/contributors" target="_blank">https://github.com/hechoendrupal/DrupalAppConsole/graphs/contributors</a> and if you want be part of this project just drop a message using the <a href="https://gitter.im" target="_blank">Gitter</a> room <a href="https://gitter.im/hechoendrupal/DrupalAppConsole">https://gitter.im/hechoendrupal/DrupalAppConsole
</a>.</p>

<p>The majority of commands in Drupal Console require a Drupal 8 instance, because the bootstrap of Drupal 8 is loaded to have access to all classes and libraries used in Drupal 8, to avoid re invent the wheel. But of course you can contribute commands without a dependency of Drupal 8.</p>

<p>Right now the Drupal Console has 28 commands listed below</p>

<pre><code>$ drupal list
Drupal Console version 0.6.5

Available commands:
 cr                              Rebuild and clear all site caches.
 drush                           Run drush from console.
 help                            Displays help for a command
 list                            Lists commands
 self-update                     Update the console to latest version.
cache
 cache:rebuild                   Rebuild and clear all site caches.
config
 config:debug                    Show the current configuration.
container
 container:debug                 Displays current services for an application.
generate
 generate:command                Generate commands for the console.
 generate:controller             Generate &amp; Register a controller
 generate:entity:config          Generate a new "EntityConfig"
 generate:entity:content         Generate a new "EntityContent"
 generate:form:config            Generate a new "ConfigFormBase"
 generate:module                 Generate a module.
 generate:plugin:block           Generate a plugin block
 generate:plugin:imageeffect     Generate image effect plugin.
 generate:plugin:rest:resource   Generate plugin rest resource
 generate:service                Generate service
migrate
 migrate:debug                   Display current migration available for the application
 migrate:execute                 Execute a migration available for application
module
 module:debug                    Display current modules available for application
 module:download                 Install module or modules in the application
 module:install                  Install module or modules in the application
 module:uninstall                Install module or modules in the application
router
 router:debug                    Displays current routes for the application
 router:rebuild                  Rebuild routes for the application
</code></pre>

<p>Most of them are oriented to generate code to speed up the process of development for Drupal 8, but in the same way of Symfony Console has commands to interact with Cache, Migrate and Database you can contribute modules for any purpose, so your imagination is the limit.</p>

<p>In my personal case I'm the contributor of commands related with Drupal 8 Migrate and Modules integration. My inspiration to create these commands wasn't to replace Drush, my ideas was to really understand how the Migration process works and be aware the module activation process.</p>

<p>After complete these commands now I can say I understand how Drupal 8 Migrate process works and how a module is installed and uninstalled.</p>

<p>But the learning process doesn't end in Drupal 8 components, when I try to create the command <a href="https://github.com/enzolutions/DrupalAppConsole/blob/module-command/src/Command/ModuleDownloadCommand.php" target="_blank">module:download</a> I have to declare libraries <a href="https://github.com/alchemy-fr/Zippy" target="_blank">Zippy</a> and
<a href="https://github.com/ARTACK/DOMQuery" target="_blank">DOMQuery</a> as dependencies using <a href="https://getcomposer.org" target="_blank">Composer</a>. Why code that libraries myself if I can use code create for non Drupal Developers :P.</p>

<p>So right now we are looking for testers and coders for new commands to improve the Drupal Console, if you think you can contribute with Drupal Console core you are more than welcome.</p>

<p>Also we expect in the future contribute to Symfony Console Component some code based in our needs, again why create <a href="https://www.acquia.com/blog/building-bridges-linking-islands">island of code</a>, instead of that push back code to the core and help other Open Source projects.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/01/25/what-is-drupal-console-for-me</link>
                    <pubDate>Sun, 25 Jan 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/01/25/what-is-drupal-console-for-me</guid>
                </item>
                                                <item>
                    <title>How to create a Multi Step Form in Drupal 8</title>
                    <description><![CDATA[<p>Last weekend I organize and participate in the initiative of <a href="http://drupal.org" target="_blank">Drupal</a> Community <a href="http://www.anexusit.com/blog/drupal-sprint-weekend-costa-rica" target="_blank">Global Sprint Weekend</a> with a location in Costa Rica.</p>

<p>Among talks and contributions I found a interesting request in Drupal 8 and I want to share with my the implementation.</p>

<p>I want to create a Multi Step Form, because Drupal 8 doesn't have an official release yet there are many stuff we easily do in Drupal 7 but now in some way to need to learn again how to solve our problems in a different way or Drupal/Symfony Style.</p>

<p>I will create a Multi Step Form to enable users to find a car providing Year, Body Style and Gas Mileage.</p>

<h1>Create a Module</h1>

<p>I will skip the explanation about how to create the Module <strong>multi_step_form</strong> in Drupal 8 because could be generated using the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> executing the following command.</p>

<pre><code>$ drupal generate:module
</code></pre>

<p>After generate the module we will use another command to add a Form with properties required as you can see below</p>

<pre><code>$ drupal generate:form:config
</code></pre>

<p>As result we will get a form with a method <strong>buildForm</strong> like this</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state) {

  $config = $this-&gt;config('multi_step.multi_step_form_config');

  $form['model'] = [
    '#type' =&gt; 'select',
    '#title' =&gt; $this-&gt;t('Model'),
    '#description' =&gt; $this-&gt;t(''),
          '#options' =&gt; array('1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015'),
          '#default_value' =&gt; $config-&gt;get('model'),
  ];

  $form['body_style'] = [
    '#type' =&gt; 'checkboxes',
    '#title' =&gt; $this-&gt;t('Body Style'),
    '#description' =&gt; $this-&gt;t(''),
          '#options' =&gt; array('Coupe', 'Sedan', 'Convertible', 'Hatchbac', 'Station wagon', 'SUV', 'Minivan', 'Full-size van', 'Pick-up'),
          '#default_value' =&gt; $config-&gt;get('body_style'),
  ];

  $form['gas_mileage'] = [
    '#type' =&gt; 'radios',
    '#title' =&gt; $this-&gt;t('Gas Mileage'),
    '#description' =&gt; $this-&gt;t(''),
          '#options' =&gt; array('20 mpg or less', '21 mpg or more', '26 mpg or more', '31 mpg or more', '36 mpg or more', '41 mpg or more'),
          '#default_value' =&gt; $config-&gt;get('gas_mileage'),
  ];

  return parent::buildForm($form, $form_state);

}
</code></pre>

<h2>Define step property</h2>

<p>Inside the Form class we need to a protected property to store the current step of Multi Step,check the following snippet.</p>

<pre><code>class MultiStepForm extends ConfigFormBase
 {

  protected $step = 1;
</code></pre>

<h2>Get parent form</h2>

<p>Instead of call parent functon <strong>buildForm</strong> at the end I will call at the beginning to modify the form before the form is render.</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state) {
  $form = parent::buildForm($form, $form_state);
</code></pre>

<h2>Filter form elements by step</h2>

<p>Now we need filter what elements of form will be rendered based in step value, as you can see in following snippet.</p>

<pre><code>if($this-&gt;step == 1) {
  $form['model'] = [
    '#type' =&gt; 'select',
    '#title' =&gt; $this-&gt;t('Model'),
    '#description' =&gt; $this-&gt;t(''),
          '#options' =&gt; array('1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015'),
          '#default_value' =&gt; $config-&gt;get('model'),
  ];
}
</code></pre>

<h2>Change submit label</h2>

<p>Now we need alter the label of submit button to inform end user that there is a next step or if we reach the end of multi step.</p>

<p>In our case we only have 3 steps and the code will be like this</p>

<pre><code>if($this-&gt;step &lt; 3) {
  $button_label = $this-&gt;t('Next');
}
else {
  $button_label = $this-&gt;t('Find a Car');
}

$form['actions']['submit']['#value'] = $button_label;

return $form;
</code></pre>

<h2>Enable Multi Step</h2>

<p>At the end we need enable the Multi Step Form behaviour, to do this is necessary modify the method <strong>submitForm</strong> forcing Form Rebuild if we don't reach yet the last step of Multi Step using the method <a href="https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Form!FormState.php/function/FormState%3A%3AsetRebuild/8" target="_blank">setRebuild()</a> part of <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/class/FormState/8" target="_blank">Form State</a>.</p>

<p>The submitForm method will be similar to following code</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function submitForm(array &amp;$form, FormStateInterface $form_state) {
  if($this-&gt;step &lt; 3) {
    $form_state-&gt;setRebuild();
    $this-&gt;step++;
  }
  else {
    parent::submitForm($form, $form_state);
    /*$this-&gt;config('multi_step.multi_step_form_config')
          -&gt;set('model', $form_state-&gt;getValue('model'))
          -&gt;set('body_style', $form_state-&gt;getValue('body_style'))
          -&gt;set('gas_mileage', $form_state-&gt;getValue('gas_mileage'))
        -&gt;save();*/
  }
}
</code></pre>

<p>If you want test a full implementation of Multi Step you can download the module <a href="https://github.com/enzolutions/drupal8_multi_step_form" target="_blank">drupal8_multi_step_form</a>.</p>

<p>I hope you found this blog entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/01/21/how-to-create-a-multi-step-form-in-drupal-8</link>
                    <pubDate>Wed, 21 Jan 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/01/21/how-to-create-a-multi-step-form-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to overwrite Backbone Model save function</title>
                    <description><![CDATA[<p><img style="float:left; margin-right: 20px;;" src="http://enzolutions.com/assets/img/backbonejs-logo-small.png"/> <a href="http://backbonejs.org" target="_blank">Backbone JS</a> enables you to create a JS application to connect with your existing API over a RESTful JSON interface.</p>

<p>Backbone define some <a href="http://es.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">REST</a> states to operate over models for instance:</p>

<ul>
<li>Model Fetch: <strong>GET</strong></li>
<li>Model New: <strong>POST</strong></li>
<li>Model Update: <strong>PUT</strong></li>
</ul>

<p>But is possible our API doesn't implement all REST States, for instance <a href="http://www.drupal.org" target="_blank">Drupal</a> 8 (version in development) don't implement the method PUT to save Drupal Entities yet.</p>

<p>In exchange the REST State PATCH is used by Drupal to save models.</p>

<p>So if I try to create a regular Model as you can see in the following snippet.</p>

<pre><code>Node = Backbone.Model.extend({
        initialize: function(){
            alert("Welcome to this world");
        }
    });

var node = new Node({ id: 1, title: 'Node Sample in Backbone'});

node.save(userDetails, {
    success: function (user) {
        alert(user.toJSON());
    }
})
</code></pre>

<p>The code above will execute an Ajax call using PUT method.</p>

<p>If you are a Drupal Developer you will notice the model doesn't match the Drupal Entity structure with language and deltas, but I just want to show a simply logic about Backbone save.</p>

<p>Now let me show you how we can overwrite the save function to change the REST method.</p>

<pre><code>Node = Backbone.Model.extend({
        initialize: function(){
            alert("Welcome to this world");
        },
        save: function(attrs, options) {
          options.patch = true;
          // Proxy the call to the original save function
          Backbone.Model.prototype.save.call(this, attrs, options);
        }
    });

var node = new Node({ id: 1, title: 'Node Sample in Backbone'});

node.save(userDetails, {
    success: function (user) {
        alert(user.toJSON());
    }
})
</code></pre>

<p>Now our model will execute and Ajax request using PATCH method.</p>

<p>I used this technique to enable the library <a href="https://github.com/enzolutions/backbone.drupal" target="_blank">Backbone.Drupal</a> send models to Drupal 8 using REST method PATCH.</p>

<p>I hope you found this blog entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2015/01/20/how-to-overwrite-backbone-model-save-function</link>
                    <pubDate>Tue, 20 Jan 2015 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2015/01/20/how-to-overwrite-backbone-model-save-function</guid>
                </item>
                                                                    <item>
                    <title>How to create an Authentication Provider in Drupal 8</title>
                    <description><![CDATA[<p>Some weeks ago I show you <a href="http://enzolutions.com/articles/2014/12/16/how-to-create-a-rest-resource-in-drupal-8" target="_blank">How to create a Rest Resource in Drupal 8</a> and as I explain in that post we use the Authentication Provider <strong>Basic Auth</strong> as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/restui_bundle_entities_settings.png"/></p>

<p>Right now is the unique Authentication Provider available to use in a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS" target="_blank">CORS</a> scenery. If you want to read more about CORS you can read the blog entry <a href="http://enzolutions.com2014/05/31/what-is-cross-origin-resource-sharing-cors" target="_blank">What is Cross-Origin Resource Sharing (CORS)</a>.</p>

<p>But what about if <strong>Basic Auth</strong> doesn't fit with your needs, well I will show you how to create a custom Authentication Provider.</p>

<h1>The Requirement</h1>

<p>My imaginary request will be create an Authentication Provider without user validation, that means access as <strong>Anonymous</strong> user, but we require to validate the source of request to check against an <strong>IP White List</strong> enabled to access our REST resources.</p>

<h1>Create a Module</h1>

<p>I will skip the explanation about how to create the Module <strong>ip_consumer_auth</strong> in Drupal 8 because could be generated using the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> executing the following command.</p>

<pre><code>$ drupal generate:module
</code></pre>

<p>After create the module with the console, we will use the console again to create a Form Configuration to create our <strong>IP White List</strong> using the following command.</p>

<pre><code>$ drupal generate:form:config
</code></pre>

<p>Now we must add a Textarea field to the form to store allowed IP Address. The implementation of method buildForm will looks similar to following snippet.</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state) {
  $config = $this-&gt;config('ip_consumer_auth.consumers_form_config');
  $form['allowed_ip_consumers'] = [
    '#type' =&gt; 'textarea',
    '#title' =&gt; $this-&gt;t('Allowed IP Consumers'),
    '#description' =&gt; $this-&gt;t('Place IP addresses on separate lines'),
    '#default_value' =&gt; $config-&gt;get('allowed_ip_consumers'),
  ];
  return parent::buildForm($form, $form_state);
}
</code></pre>

<p>The form class will be located at <strong>ip_consumer_auth/src/Form/ConsumersForm.php</strong></p>

<p>The layout to enter allowed IP consumer will looks similar to this image</p>

<p><img src="http://enzolutions.com/assets/img/allowed_ip_resources.png"/></p>

<p>The code to save that values are generated by <strong>Drupal Console</strong>, in the same way the Routing is created. Be sure you change the values to your convenience after generate the form.</p>

<h1>Create Authentication Provider</h1>

<p>Before to start with code for our Authetication Provider we need to inform to <strong>Drupal 8</strong> the existence of our custom Authentication Provider, to do that we add a new file in our module named <strong>ip_consumer_auth.service.yml</strong> because my module name is <strong>ip_consumer_auth</strong>.</p>

<p>Let me show you the content of that file</p>

<pre><code>services:
  authentication.ip_consumer_auth:
    class: Drupal\ip_consumer_auth\Authentication\Provider\IPConsumerAuth
    arguments: ['@config.factory', '@entity.manager']
    tags:
      - { name: authentication_provider, priority: 100 }
</code></pre>

<p>The discover for services will find this file and registering our Authentication Provider Class <strong>Drupal\ip_consumer_auth\Authentication\Provider\IPConsumerAuth</strong> and prepare the elements to send to constructor.</p>

<p>With the sentence above we don't have to implement the method <strong>create</strong> in our class, because the Discover send the parameters using <a href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank">Dependency Injection</a>.</p>

<p>At the end we define the priority, this value will define the execution order if multiple Authentication Provider were enabled.</p>

<h2>Implement Class Authentication Provider IPConsumerAuth</h2>

<p>Our class <strong>IPConsumerAuth</strong> must implement the interface <a href="https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Authentication!AuthenticationProviderInterface.php/interface/AuthenticationProviderInterface/8" target="_blank">AuthenticationProviderInterface</a> as you can see in the following snippet.</p>

<pre><code>/**
 * IP Consumer authentication provider.
 */
class IPConsumerAuth implements AuthenticationProviderInterface {
}
</code></pre>

<h2>Libraries</h2>

<p>The Authentication Provider require some libraries and we must to inform to AutoLoader where are these libraries, let me show the complete list.</p>

<pre><code>namespace Drupal\ip_consumer_auth\Authentication\Provider;

use \Drupal\Component\Utility\String;
use Drupal\Core\Authentication\AuthenticationProviderInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Flood\FloodInterface;
use Drupal\user\UserAuthInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
</code></pre>

<h2>Implement method applies</h2>

<p>Even if the Authentication Provider is enabled for some REST resource is required a validation to confirm the Authentication Provider apply for current Request.</p>

<p>In our case if our Authentication Provider was enabled we will add any extra validation as you can see in the following implementation.</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function applies(Request $request) {
  // If Authentication Provider is enabled always apply
  return TRUE;
}
</code></pre>

<h2>Implement method authenticate</h2>

<p>Now we have to implement the logic to execute to validate the Request, check the following snippet.</p>

<pre><code>/**
 * {@inheritdoc}
 */
public function authenticate(Request $request) {
  $allowed_ip_consumers = $this-&gt;configFactory-&gt;get('ip_consumer_auth.consumers_form_config')-&gt;get('allowed_ip_consumers');
  $ips = array_map('trim', explode( "\n", $allowed_ip_consumers));
  $consumer_ip = $request-&gt;getClientIp(TRUE);
  if (in_array($consumer_ip, $ips)) {
    // Return Anonymous user
    return $this-&gt;entityManager-&gt;getStorage('user')-&gt;load(0);
  }
  else{
    throw new AccessDeniedHttpException();
    return null;
  }
}
</code></pre>

<p>In the implementation above I use the <strong>configFactory</strong> to get the information stored about allowed IP Consumer using the Settings form created before.</p>

<p>The authenticate method receive an <a href="http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html" target="_blank">Request</a> object defined in <a href="http://symfony.com/doc/current/components/http_foundation/introduction.html"></a>The HttpFoundation Component</a> of <a href="http://symfony.com/" target="_blank">Symfony</a>.</p>

<p>Using the Request method <a href="http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html#method_getClientIp" target="_blank">getClientIp</a> we get the IP of Consumer.</p>

<p>I used the PHP functions <a href="http://php.net/manual/es/function.explode.php" target="_blank">explode</a>, <a href="http://php.net/manual/es/function.array-map.php" target="_blank">array_map</a> and <a href="http://php.net/manual/en/function.in-array.php" target="_blank">in_array</a> to determine if IP consumer belong to Allowed IP consumer. I know maybe with a regex will be more efficient but I really sucks in Regex.</p>

<p>If validation pass I return an Account object for Anonymous user, if fail an Access Denied Exception is throw.</p>

<h2>Implement method handleException</h2>

<p>If the IP wasn't in the allowed list of IP Consumer an exception is throw, using the method <strong>handleException</strong> we have the option to intercept and process to produce any output desired.</p>

<p>Let me share with you my implementation</p>

<pre><code>  /**
   * {@inheritdoc}
   */
  public function cleanup(Request $request) {}

  /**
   * {@inheritdoc}
   */
  public function handleException(GetResponseForExceptionEvent $event) {
    $exception = $event-&gt;getException();
    if ($exception instanceof AccessDeniedHttpException) {
      $event-&gt;setException(new UnauthorizedHttpException('Invalid consumer origin.', $exception));
      return TRUE;
    }
    return FALSE;
  }
</code></pre>

<p>As you can see is not to complex, but is just an idea above what you can do with this method.</p>

<h1>Usage</h1>

<p>After create our module with our custom Authentication Provider and enable it, we are ready to start to use.</p>

<p>Lets imagine you install the module <a href="https://github.com/enzolutions/entity_rest_extra" target="_blank">Entity Rest Extra</a> and we will use our Authentication Provider.</p>

<p>Using the <a href="https://www.drupal.org/project/restui/git-instructions" target="_blank">Rest UI</a>(I recommend to use the git version until Drupal 8 get a first release) module we enable the REST Resource and enable our Custom Authentication Provider, as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/custom_authentication_provider.png"/></p>

<h2>Access Denied</h2>

<p>Now if you try to access via CORS the REST end point <strong>http://example.com/bundles/node</strong> you will get an error <strong>403 Forbidden</strong> because the allowed IP consumers weren't defined yet.</p>

<h2>Unauthorized</h2>

<p>After enable your IP consumer and try again <strong>http://example.com/bundles/node</strong> you will get an error <strong>401 Unauthorized</strong></p>

<p>If that error doesn't have any logic for you let me explain, remember in our Authentication Provider we don't have information about any user, so if the request pass the validation of IP Consumer we return an Anonymous user.</p>

<p>When we enable any REST Resource in Drupal 8 a new set of  permissions is created, in our case we have to assign the permission <strong>Access GET on Bundles by entities resource</strong> to Anonymous user as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/rest_anonymous_permission.png"/></p>

<h2>Access Denied AGAIN</h2>

<p>Well maybe at this point you get MAD with me, because now you get again an error
 <strong>403 Forbidden</strong>, but at this time the fault is not caused by Authentication Provider or by Rest permission itself.</p>

<p>The error now is related with REST Resource itself is you check the code of module <strong>Entity Rest Extra</strong> you will found the permission <strong>Administer content types</strong> is required to access this Resource.</p>

<h2>Bonus</h2>

<p>Well you can complain about nobody inform to you that module has own permissions validation or the REST permissions, well that could be true.</p>

<p>If you want to get more information about a specific Drupal 8 router you can use the <strong>Drupal Console</strong>.</p>

<p>First thing you have to do is determine the Router id, we can you the canonical URL of REST resource as you can see in the following command.</p>

<pre>
 $ console router:debug | grep bundles/{entity}
 rest.entity_bundles.GET.json                             /bundles/{entity}
 </pre>

<p>Now we can get more information about router using the following command.</p>

<pre>
 $ console router:debug rest.entity_bundles.GET.json
 Route name                   Options
 rest.entity_bundles.GET.json
  + Pattern                   /bundles/{entity}
  + Defaults
   - _controller              Drupal\rest\RequestHandler::handle
   - _plugin                  entity_bundles
  + Options
   - compiler_class           \Drupal\Core\Routing\RouteCompiler
   - _access_mode             ANY
   - 0                        ip_consumer_auth
   - 0                        access_check.permission
  </pre>

<p>As you can see the last thing executed is access_check.permission generating the error 401. Maybe in the future the internal permissions in resourced will be included.</p>

<p>If you want see a complete implementation of Authentication provider you clone the project <a href="https://github.com/enzolutions/ip_consumer_auth" target="_blank">IP Consumer Auth</a></p>

<p>I hope you found this blog entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/12/28/how-to-create-an-authentication-provider-in-drupal-8</link>
                    <pubDate>Sun, 28 Dec 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/12/28/how-to-create-an-authentication-provider-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to use Drupal 8 state in Cron to resume a process.</title>
                    <description><![CDATA[<p>Usually Cron could be used to execute tasks who require a lot of processing, is normal to execute this tasks over a list of items.</p>

<p>The problem with this requirements is maybe there is not enough with one cron time execution to process the whole elements in our list of items to process. So we have to save the status of our execution to continue the next time the cron is executed.</p>

<p>We can do that with <a href="https://api.drupal.org/api/drupal/core%21modules%21system%21core.api.php/group/queue/8" target="_blank">Queue Operations</a>, but this solution is complex to implement(maybe just for me) so I will propose a simple option to implement the resume feature.</p>

<h1>Working with our list of items to process.</h1>

<p>Lets imagine we store our list of items in and array, and the normal option to process and array is using a <a href="http://php.net/manual/en/control-structures.foreach.php" target="_blank">foreach</a>.</p>

<p>Well we can't use a foreach in our resume because this function starts his execution with a reset of the internal array pointer to the first element of the array and that is not good for our resume process.</p>

<p>So I have to use a different solution to do that, let me show you my first implementation</p>

<pre><code>foreach ( $array as $array_key =&gt; $array_value ) {
}
</code></pre>

<p>Instead of that I decide to use a simple while with some changes to simulate the array key assignation in a variable as you can see in the following snippet.</p>

<pre><code>while (list($array_key, $array_value) = each($array)) {
}
</code></pre>

<h1>Store last state</h1>

<p>With the problem about array pointer resolved we need store the last correct pointer processed by cron, to store that I use a new feature of Drupal 8 <a href="https://api.drupal.org/api/drupal/core!lib!Drupal.php/function/Drupal%3A%3Astate/8" target="_blank">Drupal::state()</a>.</p>

<p>Drupal:state store temporary and not critical information, this information is not be migrated between environments in a eventual migration to production.</p>

<p>Let me show you how to use in combination with while loops</p>

<pre><code>while (list($array_key, $array_value) = each($array)) {

  // --- INSERT LONG OPERATIONS HERE --

  // Set last bank process to continue after this bank
  \Drupal::state()-&gt;set('last_key', $array_key);
}

// Delete last bank if all were processed
\Drupal::state()-&gt;delete('last_key');
</code></pre>

<p>If the hook_cron is interrupted at least we will know in the last index executed without problems, because is stored in state variable <strong>last_key</strong></p>

<p>If we don't get any interruption we must delete the state variable.</p>

<h1>Set array pointer</h1>

<p>First I need to create a custom function named <strong>_array_set_pointer_by_key</strong> to set the array pointer to any arbitrary position, let me show the implementation.</p>

<pre><code>function _array_set_pointer_by_key(&amp;$array, $key)
{
    reset($array);
    while($index=key($array))
    {
        if($index==$key)
            break;

        next($array);
    }
}
</code></pre>

<p>The function above works with any kind of array keys.</p>

<p>Now we need to validate if we have to resume the execution of <strong>hook_cron</strong> in some position of our array of list of items, using again the <strong>Drupal::State</strong> to get the information as you can see in the following piece of code.</p>

<pre><code>$last_key = \Drupal::state()-&gt;get($last_bank_variable, null);

if ($last_key) {
  // Set pointer to last key to process
  _array_set_pointer_by_key($array, $last_key);

  // Set array to next valid bank to process
  next($array);
}
</code></pre>

<p>After reset the array we use the <a href="http://php.net/manual/en/function.next.php" target="_blank">next</a> function to move the pointer to next position where we want to resume.</p>

<p>I hope you find this blog entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/12/26/how-to-use-drupal-8-state-in-cron-to-resume-a-process</link>
                    <pubDate>Fri, 26 Dec 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/12/26/how-to-use-drupal-8-state-in-cron-to-resume-a-process</guid>
                </item>
                                                                    <item>
                    <title>How to create a Rest Resource in Drupal 8</title>
                    <description><![CDATA[<p>One of the biggest changes in <a href="https://www.drupal.org/drupal-8.0" target="_blank">Drupal 8</a> is his integration with <a href="http://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank">RESTful</a>.</p>

<p>Today I want to share with you how to create your own Rest Resources in a custom module to publish your website information using a RESTful API.</p>

<p>I will create a new REST Resource with the objective to get the list of bundle types available for a specific entity.</p>

<h1>Create a Module</h1>

<p>I will skip the explanation about how to create a Module in Drupal 8 because could be generated using the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> executing the following command.</p>

<pre><code>$ php console.phar generate:module
</code></pre>

<h1>Create a new REST Resource</h1>

<p>Assuming we create a new module named <strong>entity_rest_extra</strong> is required to create a class file <strong>EntityBundlesResource.php</strong> inside the module in a folder path <strong>src/Plugin/rest/resource</strong>.</p>

<h2>Namespace</h2>

<p>The namespace for this new Rest Resource will be</p>

<pre><code>namespace Drupal\entity_rest_extra\Plugin\rest\resource;
</code></pre>

<h2>Libraries</h2>

<p>We must to use some dependencies to create the REST Resource, below the full list.</p>

<pre><code>use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Psr\Log\LoggerInterface;
</code></pre>

<h2>Annotations</h2>

<p>To enable the Discover for REST Resources found our new Rest Resource we must to implement the proper information in Annotation. check the following example.</p>

<pre><code>/**
 * Provides a resource to get bundles by entity.
 *
 * @RestResource(
 *   id = "entity_bundles",
 *   label = @Translation("Bundles by entities"),
 *   uri_paths = {
 *     "canonical" = "/bundles/{entity}"
 *   }
 * )
 */
</code></pre>

<p>As you can see we provide a Resource <strong>id</strong> with a <strong>label</strong>, also we define the <strong>canonical</strong> URL for our REST Resource with a parameter named <strong>entity</strong></p>

<p>Using the annotation the Discover for Rest Resources will declare the routing dynamically so we don't need include a <strong>routing.yml</strong> file in our module.</p>

<h2>Implement Class</h2>

<p>Now we have to create a class extending from <a href="https://api.drupal.org/api/drupal/core%21modules%21rest%21src%21Plugin%21ResourceBase.php/class/ResourceBase/8" target="_blank">ResourceBase</a> as you can see in the following snippet</p>

<pre><code>class EntityBundlesResource extends ResourceBase {
  /**
   *  A curent user instance.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;
  /**
   *  A instance of entity manager.
   *
   * @var \Drupal\Core\Entity\EntityManagerInterface
   */
  protected $entityManager;
}
</code></pre>

<p>Our implementation require two properties for <strong>Current User</strong> and <strong>EntityManager</strong>.</p>

<h1>Class Setup</h1>

<p>As you can imagine each class require a constructor and Drupal 8 is not the exception, but Drupal also implement
<a href="http://www.phptherightway.com/pages/Design-Patterns.html" target="_blank">The Factory Pattern</a> to prepare the values to send to constructor.</p>

<p>But is better to explain to you with the following example where we need to send the <a href="https://www.drupal.org/node/2133171" target="_blank">services</a>: <strong>Resource Format</strong>, <strong>Logger</strong>, <strong>Entity manager</strong> and <strong>Current User</strong> to the <strong>constructor</strong></p>

<pre><code>/**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container-&gt;getParameter('serializer.formats'),
      $container-&gt;get('logger.factory')-&gt;get('rest'),
      $container-&gt;get('entity.manager'),
      $container-&gt;get('current_user')
    );
  }
</code></pre>

<p>Now we need to define the constructor where we are receiving the values from the create method, as you can see below.</p>

<pre><code>/**
  * Constructs a Drupal\rest\Plugin\ResourceBase object.
  *
  * @param array $configuration
  *   A configuration array containing information about the plugin instance.
  * @param string $plugin_id
  *   The plugin_id for the plugin instance.
  * @param mixed $plugin_definition
  *   The plugin implementation definition.
  * @param array $serializer_formats
  *   The available serialization formats.
  * @param \Psr\Log\LoggerInterface $logger
  *   A logger instance.
  */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    array $serializer_formats,
    LoggerInterface $logger,
    EntityManagerInterface $entity_manager,
    AccountProxyInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);

    $this-&gt;entityManager = $entity_manager;
    $this-&gt;currentUser = $current_user;
  }
</code></pre>

<h1>Implement REST method</h1>

<p>Last but not least we have to define the RESTful state we want to implement, in my example I want to implement a GET method to response according the parameters.</p>

<p>Inside the class with have to create a method matching the RESTful state name, so for GET we have to implement a method named <strong>get</strong> as you can see in the following snippet.</p>

<pre><code>  /*
   * Responds to GET requests.
   *
   * Returns a list of bundles for specified entity.
   *
   * @return \Drupal\rest\ResourceResponse
   *   The response containing a list of bundle names.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   */
  public function get($entity = NULL) {
    if ($entity) {
      $permission = 'Administer content types';
      if(!$this-&gt;currentUser-&gt;hasPermission($permission)) {
        throw new AccessDeniedHttpException();
      }
      $bundles_entities = \Drupal::entityManager()-&gt;getStorage($entity .'_type')-&gt;loadMultiple();
      $bundles = array();
      foreach ($bundles_entities as $entity) {
        $bundles[$entity-&gt;id()] = $entity-&gt;label();
      }
      if (!empty($bundles)) {
        return new ResourceResponse($bundles);
      }
      throw new NotFoundHttpException(t('Bundles for entity @entity were not found', array('@entity' =&gt; $entity)));
    }

    throw new HttpException(t('Entity wasn\'t provided'));
  }
</code></pre>

<p>As you can see the method receive as parameter the last value pass to URL.</p>

<p>Also using the <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Session%21AccountProxyInterface.php/interface/AccountProxyInterface/8" target="_blank">Account Proxy Interface</a> we can determine if Current User has enough rights to get the bundle list.</p>

<p>The <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityManagerInterface.php/interface/EntityManagerInterface/8" target="_blank">Entity Manager Interface</a> allow us to we get the list of bundles for Entity requested.</p>

<p>After that we prepare an array with the results, these results will be transformed to the proper format requested by the user using the class <a href="https://api.drupal.org/api/drupal/core%21modules%21rest%21src%21ResourceResponse.php/class/ResourceResponse/8" target="_blank">ResourceResponse</a>, in our case we will request a json response.</p>

<p>If you want to implement RESTful state POST just add a method <strong>post</strong></p>

<p>You can see a full and functional custom REST Resources at <a href="https://github.com/enzolutions/entity_rest_extra" target="_blank">https://github.com/enzolutions/entity_rest_extra</a></p>

<h1>Using our new Resource</h1>

<p>Using the contrib module <a href="https://www.drupal.org/project/restui/git-instructions" target="_blank">Rest UI</a> (I recommend to use the git version until Drupal 8 get a first release) you can enable your custom Rest Resource.</p>

<p>This module enable a UI to set the Authentication and format for each RESTful method implemented as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/restui_bundle_entities_settings.png"/></p>

<p>Using this setting the access to Resource will be granted or denied.</p>

<p>Using the Chrome Application <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm">Postman - REST Client</a> you can execute an authenticated request to URL <strong>http://example.com/bundles/node</strong> as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/postman_rest_request.png"/></p>

<p>If all is working as expected you will get a similar result to next json output.</p>

<pre><code>{
  "article": "Article",
  "page": "Basic page"
}
</code></pre>

<p>I hope you find this blog entry usefull.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/12/16/how-to-create-a-rest-resource-in-drupal-8</link>
                    <pubDate>Tue, 16 Dec 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/12/16/how-to-create-a-rest-resource-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to create a Field Formatter in Drupal 8</title>
                    <description><![CDATA[<p>One of the biggest changes in <a href="https://www.drupal.org/drupal-8.0" target="_blank">Drupal 8</a> is his integration with <a href="http://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank">RESTful</a>.</p>

<p>Because now Views lives in Core you can create a view with JSON response in few minutes, you just need enable modules <strong>Views</strong>, <strong>Views UI</strong> and <strong>RESTful Web Services</strong></p>

<p>The problem I found with image is the formatter for image is not compatible with RESTful responses due the output of Image formatter is HTML.</p>

<h1>Create a View</h1>

<p>Let me explain the situation if you create a view with a <strong>Rest Export</strong> display you can select what fields of your entity you want to render.</p>

<p>Now if you choose an image field the default format is Image as you can see in the following snapshot.</p>

<p><img src="http://enzolutions.com/assets/img/image_field_formatter.png"/></p>

<p>Even if you don't set the option to link to original image you will get the image in HTML format as you see in the following sample of JSON response.</p>

<pre><code>[
  {
    title: "Image sample # 3",
    field_image: " &lt;img src="http://example.com/sites/default/files/styles/thumbnail/public/field/image/globe.jpg?itok=wmu3VCr6" width="100" height="75" alt="" typeof="foaf:Image" class="image-style-thumbnail" /&gt; "
  },
  {
    title: "Image sample # 2",
    field_image: " &lt;img src="http://example.com/sites/default/files/styles/thumbnail/public/field/image/sample_08.jpg?itok=X9N005N1" width="100" height="75" alt="" typeof="foaf:Image" class="image-style-thumbnail" /&gt; "
  },
  {
    title: "Image sample # 1",
    field_image: " &lt;img src="http://d$/sites/default/files/styles/thumbnail/public/field/image/sample_01.jpg?itok=UD1-QXTj" width="100" height="75" alt="" typeof="foaf:Image" class="image-style-thumbnail" /&gt; "
  }
]
</code></pre>

<p>The previous output was generated by a view selecting articles with images, if you want import this view in your system just download the file <a href="http://enzolutions.com/assets/attaches/view_image_list.yml" target="_blank">views_list.yml</a> and import using the Configuration Management of Drupal accessing the URL <strong>http://example.com/admin/config/development/configuration/single/import</strong> in your Drupal install as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/configuration_management_view_import.png"/></p>

<p>If you want read more about Configuration Management in Drupal 8 you can read the post entry <a href="http://enzolutions.com/articles/2014/08/27/understanding-configuration-management-in-drupal-8/">Understanding Configuration Management in Drupal 8</a></p>

<p>To resolve this problem I will show you how to create your own Field Formatter to meet your needs.</p>

<h1>Create a Module</h1>

<p>I will skip the explanation about how to create a Module in Drupal 8 because could be generated using the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> executing the following command.</p>

<pre><code>$ php console.phar generate:module
</code></pre>

<h1>Create a new Field Formatter</h1>

<p>If you want to create a new custom Field Formatter is require to add a new class file located inside your module in the following path</p>

<pre><code>YOUR_MODULE/src/Plugin/Field/FieldFormatter/
</code></pre>

<p>Inside this folder you must create a class file per each Field Formatter do you want to create.</p>

<p>I will create a new file named <strong>ImageRawFormatter.php</strong>, I will explain each part of this file</p>

<h2>Field Formatter Metadata</h2>

<p>Before to start to code we must to define some stuff required for a proper function.</p>

<h3>Namespace</h3>

<p>We have to define what will be Namespace for your Field Formatter</p>

<pre><code>namespace Drupal\image_raw_formatter\Plugin\Field\FieldFormatter;
</code></pre>

<p>Drupal 8 implement <a href="http://www.php-fig.org/psr/psr-4/" target="_blank">PSR-4</a> from  <a href="http://www.php-fig.org/" target="_blank">PHP Framework Interop Group</a></p>

<p>This specification follow the following pattern</p>

<pre><code>\&lt;NamespaceName&gt;(\&lt;SubNamespaceNames&gt;)*\&lt;ClassName&gt;
</code></pre>

<p>In our case the division will be</p>

<ul>
<li><strong>NamespaceName</strong>: Drupal</li>
<li><strong>SubNamespaceNames</strong>: image_raw_formatter\Plugin\Field\FieldFormatter</li>
<li><strong>ClassName</strong>: ImageRawFormatter</li>
</ul>

<h2>Libraries required</h2>

<p>In this specific case we have to define where are classes we require to create our Field Formatter.</p>

<p>Drupal 8 use Autoloader class but we need to inform where they are using the intruction <strong>use</strong>.</p>

<pre><code>use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;
use Drupal\image\Entity\ImageStyle;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\FieldItemListInterface;
use \InvalidArgumentException;
</code></pre>

<h3>Annotations</h3>

<p>Drupal 8 have several discovers to detect specific implementation, for instance we have a Discover to detect all Field Formatter declared in our application and the way to declare a new Field Formatter is using <a href="https://wiki.php.net/rfc/annotations" target="_blank">Annotations</a>.</p>

<p>Below you can find an annotation example for Field Formatter</p>

<pre><code>/**
 * Plugin implementation of the 'image_raw_formatter' formatter.
 *
 * @FieldFormatter(
 *   id = "image_raw_formatter",
 *   label = @Translation("Image Raw"),
 *   field_types = {
 *     "image"
 *   }
 * )
 */
</code></pre>

<p>As you can see we must define an unique <strong>id</strong> with a <strong>label</strong> with translation and we must define for which field types this Field Formatter will be available.</p>

<h2>Implement Class</h2>

<p>Now we have to create a class extending from <a href="https://api.drupal.org/api/drupal/core%21modules%21image%21src%21Plugin%21Field%21FieldFormatter%21ImageFormatterBase.php/class/ImageFormatterBase/8">ImageFormatterBase</a> as you can see in the following snippet</p>

<pre><code>class ImageRawFormatter extends ImageFormatterBase
{
}
</code></pre>

<h3>Settings Form</h3>

<p>Now we have to add a method <strong>settingsForm</strong> to define the Setting options for our Formatter. check the following implementation.</p>

<pre><code>/**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $image_styles = image_style_options(FALSE);
    $element['image_style'] = array(
      '#title' =&gt; t('Image style'),
      '#type' =&gt; 'select',
      '#default_value' =&gt; $this-&gt;getSetting('image_style'),
      '#empty_option' =&gt; t('None (original image)'),
      '#options' =&gt; $image_styles,
    );
    return $element;
  }
</code></pre>

<p>The implementation above allow user select a specific image style to be returned or just return the original image.</p>

<h3>Summary Report</h3>

<p>Is important to inform to end users current setting of formatter, to enable that we have to implement the method <strong>settingsSummary</strong></p>

<pre><code>/**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = array();
    $image_styles = image_style_options(FALSE);
    // Unset possible 'No defined styles' option.
    unset($image_styles['']);
    // Styles could be lost because of enabled/disabled modules that defines
    // their styles in code.
    $image_style_setting = $this-&gt;getSetting('image_style');
    if (isset($image_styles[$image_style_setting])) {
      $summary[] = t('Image style: @style', array('@style' =&gt; $image_styles[$image_style_setting]));
    }
    else {
      $summary[] = t('Original image');
    }
    return $summary;
  }
</code></pre>

<p>As you can see the method above just read the current settings and render an output.</p>

<h3>Render Field Formatter</h3>

<p>At the end we need to define the how we want to render the field based in current Field Formatter settings, we have to implement the method <strong>viewElements</strong> as you can see in the following snippet.</p>

<pre><code>/**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items) {
    $elements = array();
    $image_style_setting = $this-&gt;getSetting('image_style');

    // Determine if Image style is required.
    $image_style = NULL;
    if (!empty($image_style_setting)) {
      $image_style = entity_load('image_style', $image_style_setting);
    }
    foreach ($items as $delta =&gt; $item) {
      if ($item-&gt;entity) {
        $image_uri = $item-&gt;entity-&gt;getFileUri();
        // Get image style URL
        if ($image_style) {
          $image_uri = ImageStyle::load($image_style-&gt;getName())-&gt;buildUrl($image_uri);
        } else {
          // Get absolute path for original image
          $image_uri = $item-&gt;entity-&gt;url();
        }
        $elements[$delta] = array(
          '#markup' =&gt; $image_uri,
        );
      }
    }
    return $elements;
  }
</code></pre>

<p>If you read the logic only determine if the configuration require use any image style or if is only required the original image, in both sceneries the proper path url is return.</p>

<p>We don't need any transformation to JSON because that is handled by view Display selected.</p>

<h1>Module usage</h1>

<p>After enable our custom module we just need edit our view and edit the field to use new Raw Formatter as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/image_field_raw_formatter.png"/></p>

<p>After save the view and run again the output will be totally different and perfect to use in RESTful services to avoid HTML parsing to extract the image path. check the output example below.</p>

<pre><code>[
  {
    title: "Image sample # 3",
    field_image: "http://drupal8b3.dev/sites/default/files/styles/thumbnail/public/field/image/globe.jpg?itok=wmu3VCr6"
  },
  {
    title: "Image sample # 2",
    field_image: "http://drupal8b3.dev/sites/default/files/styles/thumbnail/public/field/image/sample_08.jpg?itok=X9N005N1"
  },
  {
    title: "Image sample # 1",
    field_image: "http://drupal8b3.dev/sites/default/files/styles/thumbnail/public/field/image/sample_01.jpg?itok=UD1-QXTj"
  }
]
</code></pre>

<p>You can download a full implementation of this custom Image Raw Field Formatter at <a href="https://github.com/enzolutions/image_raw_formatter" target="_blank">https://github.com/enzolutions/image_raw_formatter</a>.</p>

<p>I expect you found this blog entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/12/09/how-to-create-a-field-formatter-in-drupal-8</link>
                    <pubDate>Tue, 09 Dec 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/12/09/how-to-create-a-field-formatter-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>Resetting the administrator password with sql-query in Drupal 8</title>
                    <description><![CDATA[<h1>The Problem</h1>

<p>When in Drupal 8, the password for user #1 (the administrator) is lost and the email notification don't work, it is possible to set the password via a database query.</p>

<p>Right now we are in the middle of the development of Drupal 8 and the usual command <a href="http://www.drushcommands.com/drush-6x/user/user-login" target="_blank"><strong>drush uli</strong></a> provided by <a href="http://www.drush.org/" target="_blank"></a>Drush doesn't work.</p>

<p>Right now when I try to execute that command I got the following error.</p>

<pre><code>Fatal error: Call to undefined function url() in /Users/enzo/.composer/vendor/drush/drush/commands/user/user.drush.inc on line 466
Drush command terminated abnormally due to an unrecoverable error.
</code></pre>

<h1>The Solution</h1>

<h2>Generate a new password</h2>

<p>First, you have to generate a password hash that is valid for your site.</p>

<p>Execute the following commands from the command line, in the Drupal 8 root directory:</p>

<pre><code>$ php core/scripts/password-hash.sh 'your-new-pass-here'

password: your-new-pass-here    hash: $S$EV4QAYSIc9XNZD9GMNDwMpMJXPJzz1J2dkSH6KIGiAVXvREBy.9E
</code></pre>

<p>Be careful not to include more or less characters as the hash. These hashes look somewhat like <strong>$S$EV4QAYSIc9XNZD9GMNDwMpMJXPJzz1J2dkSH6KIGiAVXvREBy.9E</strong>.</p>

<p>We will use the generated password later.</p>

<h2>Update the user password.</h2>

<p>Now you need to update the user password, in our case we need update the Administrator password, fortunately the UID for Administrator is 1 equal to previous versions of Drupal.</p>

<p>With the new password we need run the following SQL statement.</p>

<pre><code>UPDATE users_field_data SET pass='$S$E5j59pCS9kjQ8P/M1aUCKuF4UUIp.dXjrHyvnE4PerAVJ93bIu4U' WHERE uid = 1;
</code></pre>

<h2>Dealing with Cache</h2>

<p>At this point if you try to login in the Drupal 8 website you will rejected, it's because the login system don't read directly the table <strong>users_field_data</strong> instead of a cache for entities is used.</p>

<p>To flush the cache for a specific user entity with compromise the rest of cache of your system you can use the following SQL statement.</p>

<pre><code>DELETE FROM cache_entity WHERE cid = 'values:user:1';
</code></pre>

<p>Now you can grab a cup of coffee/tea and enjoy your Drupal 8 website.</p>

<p>I hope you found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/12/07/resetting-the-administrator-password-with-sql-query-in-drupal-8</link>
                    <pubDate>Sun, 07 Dec 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/12/07/resetting-the-administrator-password-with-sql-query-in-drupal-8</guid>
                </item>
                                                <item>
                    <title>How to work with Drupal 8 forms with Ajax.</title>
                    <description><![CDATA[<p>Nowadays Drupal 8 has couple of beta releases so the official release is around the corner. For that reason I start to test the typical features required in a Drupal 7 site.</p>

<p>Today I will share with you my experiences with Form with Ajax effects.</p>

<h1>Create a Form</h1>

<p>I will skip the explanation about how to create a Form in Drupal 8 because could be generated using the project <a href="http://drupalconsole.com/" target="_blank">Drupal Console</a> executing the following command.</p>

<pre><code>$ php console.phar generate:form:config
</code></pre>

<h1>Drupal 8 FAPI + Ajax</h1>

<p>The current documentation of FAPI for Drupal 8 about <a href="https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/8#ajax" target="_blank">ajax</a> is not updated.</p>

<p>But the property is still name <strong>#ajax</strong> check the following implementation.</p>

<pre><code>   $form['source']['version'] = array(
      '#type' =&gt; 'radios',
      '#title' =&gt; $this-&gt;t('Drupal Version'),
      '#default_value'=&gt;"d6",
      '#options' =&gt; $options,
      '#description' =&gt; t('Choise what version of Drupal you want migrate'),
      '#required' =&gt; TRUE,
      '#ajax' =&gt; array(
        'callback' =&gt; '::updateDestinationIds',
        'wrapper' =&gt; 'edit-destinations',
        'progress' =&gt; array(
          'type' =&gt; 'throbber',
          'message' =&gt; "searching",
        ),
      ),
    );
</code></pre>

<p>If you are a old developer of Drupal you will recognize the properties <strong>wrapper</strong>, <strong>progress</strong>, these properties work equal in Drupal 7.</p>

<p>The main change is in callback property, in my example the value '::updateDestinationIds' means the method <em>updateDestinationIds</em> is part of the Form class. I didn't test but looks like we can assign a static method like 'Drupal::StaticMethod'.</p>

<h1>Response method</h1>

<p>Similar to Drupal 7 the method has to return the portion of the Form must be overwritten via ajax, let me show you an example.</p>

<pre><code>/**
 * Gets migration configurations.
 *
 * @return array
 *   An array of migration names.
 */
function updateDestinationIds($form, FormStateInterface $form_state) {
    $form ['source']['migration_ids']['#options'] = $this-&gt;getDestinationIds($form_state-&gt;getValue('version'));
    return $form ['source']['migration_ids'];
}
</code></pre>

<h1>Known Issues</h1>

<p>After implement the Ajax function I detect a problem when I try to select values populated via Ajax and submit the form I get this error message "An illegal choice has been detected. Please contact the site administrator."</p>

<p>When I debug I can determine the method <a href="https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Installer!Form!SiteSettingsForm.php/function/SiteSettingsForm%3A%3AbuildForm/8" target="_blank">buildForm</a> is executed in different moments listed below</p>

<ul>
<li><strong>Form load</strong>: To build the form</li>
<li><strong>Ajax request</strong>: To re-build the form and determine elements to overwrite.</li>
<li><strong>Form submit</strong>: To process the form</li>
</ul>

<p>My problem was in the last one <em>Form Submit</em> because the submit run the implementation of class <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormValidator.php/8" target="_blank">FormValidator</a>.</p>

<p>The FormValidator ignore the Ajax process and validate the FormState values against the list of values allowed and because took this values from buildForm they are always the initial values ignoring the user interaction.</p>

<p>To resolve this problem I use the  <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/class/FormState/8" target="_blank">FormState</a> object to determine if buildForm was executed to render the form at first time or if has human interaction (ajax or submit) to define the allowed list of values based in user interaction, check the following snippet.</p>

<pre><code>$form_state_complete_form=$form_state-&gt;getCompleteForm();
if(empty($form_state_complete_version)){
    $form ['source']['migration_ids']['#options'] = $this-&gt;getDestinationIds("d6");
 }
  else  {
   $form ['source']['migration_ids']['#options'] = $this-&gt;getDestinationIds($form_state_complete_version);
 }
</code></pre>

<p>Don't be worry about this behavior as you can see is easy to fix and I'm sure won't be necessary when Drupal 8 get the first official release.</p>

<h1>Caveats</h1>

<p>The current status of Drupal 8 only support the ajax update in <em>Select</em> elements, I tried with <strong>tableselect</strong> and <strong>checkboxes</strong> and doesn't work.</p>

<p>There is an issue for this problem at <a href="https://www.drupal.org/node/1458824" target="_blank">Ajax doesn't work with Tableselect with checkboxes</a>.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/11/25/how-to-work-with-drupal-8-forms-with-ajax</link>
                    <pubDate>Tue, 25 Nov 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/11/25/how-to-work-with-drupal-8-forms-with-ajax</guid>
                </item>
                                                                                                                                                    <item>
                    <title>How to enable CORS requests against Drupal 8</title>
                    <description><![CDATA[<h1>The Problem</h1>

<p>Nowadays I was creating a new version of my library <a target="_blank" href="https://github.com/enzolutions/backbone.drupal">https://github.com/enzolutions/backbone.drupal</a> to enable to use Drupal 8 in mode <strong>Headless Drupal</strong> using front end in a different domain or subdomain.</p>

<p>The problem I found with <a href="http://enzolutions.com/articles/2014/05/31/what-is-cross-origin-resource-sharing-cors/">CORS</a> requests is related with the way jQuery execute the first request Ajax, because before to do an execution of a GET|PUT|DELETE|POST|PATCH request an <a target="_blank" href="http://restpatterns.org/HTTP_Methods/OPTIONS">OPTIONS</a> request is executed to validate request methods accepted for backend server more information at <a href="http://api.jquery.com/jquery.ajax/">http://api.jquery.com/jquery.ajax/</a> in <strong>contentType</strong> section.</p>

<p>The current status of Rest module (part of Drupal Core) doesn't implement the OPTIONS method, so my first approach was implement that method in class <strong>Drupal\rest\Plugin\rest\resource\EntityResource</strong> using the following code</p>

<pre><code>public function options(EntityInterface $entity) {
   $response = new ResourceResponse();
   $response-&gt;setStatusCode(ResourceResponse::HTTP_OK);
   $response-&gt;headers-&gt;set('Allow', 'GET,POST,PATCH,DELETE,OPTIONS');
   return $response-&gt;send();
  }
</code></pre>

<p>After add that extra function in class <strong>EntityResource</strong> the method was available and double checked with module <a target="_blank" href="https://www.drupal.org/project/restui">RestUI</a>, but this solution wasn't enough because I can't enable OPTIONS method without authentication and jQuery trigger the OPTIONS method without CRC Token or Basic Auth method even if you provide in the original call.</p>

<h1>The Solution</h1>

<p>In order to resolve the problem I use .htaccess and Apache <a target="_blank" href="http://httpd.apache.org/docs/current/mod/mod_rewrite.html">mod_rewrite</a> to enable CORS and intercept the OPTIONS request to avoid Drupal reject the request because doesn't have the proper credentials, I did a patch for Drupal 8 and you can download the patch <a target="_blank" href="https://www.drupal.org/files/issues/core-cors-headers-1869548-26.patch">here</a>.</p>

<p>But let me explain the changes introduced in my patch.</p>

<h2>Intercept OPTIONS Request</h2>

<p>I add a Mod Rewrite Condition and Rule to avoid all OPTIONS request be processed by Drupal and rejected, instead of a <a target="_blank" href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success">HTTP 200 OK</a> code is returned in order to enable jQuery request continue with the normal workflow.</p>

<p>Check the code below.</p>

<pre><code>RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
</code></pre>

<h2>Enable CORS</h2>

<p>If you search how to enable CORS using .htaccess you will find tons of similar information and this information usually works, but in our case we have a special situation the intercept process we implemented above.</p>

<p>Because the interception the normal statements to enable CORS doesn't work and apache will reject our request, to resolve this problem I found the condition <a target="_blank" href="http://httpd.apache.org/docs/2.0/mod/mod_headers.html">always</a> for Header directive.</p>

<p>Check the implementation below.</p>

<pre><code>Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Headers: Authorization
</code></pre>

<p>I strongly recommend to change <strong>*</strong> for your frontend domain i.e frontend-example.com.</p>

<p>I expect you have found this entry useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/09/08/how-to-enable-cors-requests-against-drupal-8</link>
                    <pubDate>Mon, 08 Sep 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/09/08/how-to-enable-cors-requests-against-drupal-8</guid>
                </item>
                                                <item>
                    <title>Understanding Configuration Management in Drupal 8</title>
                    <description><![CDATA[<p>In few months we will get the new release of Drupal the #8 (I hope) and I think it's time to start to test, learn and write about the new ways we have in Drupal 8 to do our old tricks.</p>

<p>Today I want to talk about the Drupal 8 <a target="_blank" href="http://drupal8cmi.org/">Initiative Configuration Management</a>, this initiative pretend to facilitate the process of pass Site Building stuffs from Dev environments to Production.</p>

<p>As you can imagine this feature will be a replacement of Drupal <a target="_blank" href="https://www.drupal.org/project/features">Features</a> and if you don't use or don't like Features also will be a replacement for Drupal <a target="_blank" href="https://www.drupal.org/project/bundle_copy">Bundle Copy</a></p>

<h1>Installing Drupal 8</h1>

<p>Right now there isn't an official Drupal release for Drupal 8, but if you can start to test you can get directly from git repository.</p>

<p>If you don't have plans to contribute with code to Drupal 8 you can use the following command to get just the latest version of Drupal 8 but without the whole git history reducing dramatically the download process.</p>

<pre><code>git clone -depth 1 --branch 8.0.x http://git.drupal.org/project/drupal.git [FOLDER_NAME]
</code></pre>

<p>After that you just need create a Database and point your webserver to this folder and start the installation in the same way you usually do for Drupal 7.</p>

<h1>Configuration Management Install</h1>

<p>You don't need install Configuration Management module, because is part of Drupal 8 Core and is already installed when you complete a standard Drupal 8 installation, as you can see in the following image.</p>

<p><img src="http://enzolutions.com/assets/img/configuration_management_module_enable.png"/></p>

<p>As you can imagine, you can't disable the Configuration Management module.</p>

<h1>Export Configuration</h1>

<p>As I said at the beginning Configuration Management is a replacement for Features, so you need to work in your website doing Site Building tasks like creating or modifying content types and other tasks like creating Views(part of Drupal 8 Core).</p>

<p>Now we will call the first Drupal 8 Installation <strong>Devel#1</strong> of a new Drupal 8 project and as you can imagine we need to share our progress with the rest of team and to avoid to create a DB Dump and force the rest of the team import we will use the Configuration Management.</p>

<p>The administrator of <strong>Devel#1</strong> has to go page: example.com/admin/config/development/configuration/full/export the UI will looks similar to image below.</p>

<p><img src="http://enzolutions.com/assets/img/configuration_management_full_export.png"></p>

<p>After press the button Export you will get a zip file named <strong>config.tar.gz</strong>, after you uncompress the zip file you will get a config folder with severals files in <a target="_blank" href="http://symfony.com/doc/current/components/yaml/yaml_format.html">YAML</a> format and each one represent a isolate piece of configuration of our site. Below you can a partial list of files created by export.</p>

<pre><code>block.block.bartik_footer.yml       menu.entity.node.page.yml
block.block.bartik_help.yml       menu_link.static.overrides.yml
block.block.bartik_login.yml        menu_ui.settings.yml
block.block.bartik_powered.yml        node.settings.yml
block.block.bartik_search.yml       node.type.article.yml
block.block.bartik_tools.yml        node.type.book.yml
block.block.seven_breadcrumbs.yml     node.type.page.yml
block.block.seven_content.yml       rdf.mapping.comment.comment.yml
block.block.seven_help.yml        rdf.mapping.node.article.yml
</code></pre>

<p>Now we have the options to share all files or just one of them with the rest of the team.</p>

<h1>Importing Configuration</h1>

<p>Now we have the files required to import the configuration in other Drupal installation <strong>Devel#2</strong> but we need to prepare the destination.</p>

<p>The Drupal 8 installation process create two folders to handle the import and export process, the installer create two folders inside <DOCROOT>/sites/default/files using random names, but we can check the proper names checking our configuration at <DOCROOT>/sites/default/setting.php.</p>

<p>Let me show you an example of that configuration file:</p>

<pre><code>$settings['install_profile'] = 'standard';
$config_directories['active'] = 'sites/default/files/config_0HU-CmGmyKok3uG6Ao8Lv4WCsVZDwqitSKnQcUNPJmtrKWdgQuM4nhQNZO_T5Mcsmaz-bFcOyA/active';
$config_directories['staging'] = 'sites/default/files/config_0HU-CmGmyKok3uG6Ao8Lv4WCsVZDwqitSKnQcUNPJmtrKWdgQuM4nhQNZO_T5Mcsmaz-bFcOyA/staging';
</code></pre>

<p>As you can see now we have two concepts <strong>active</strong> and <strong>staging</strong>.</p>

<p>The <strong>active</strong> folder must contain the current site configuration, but by default is empty because the default storage for current site is Database but is possible change I will write about that in other blog entry.</p>

<p>The <strong>staging</strong> folder contain any configuration we want to import in our site, here we must copy the files we get from export process.</p>

<p>I recommend use a version system like GIT to control the staging files and change configuration to use a non hash folder name, check my recommendation below:</p>

<pre><code>$settings['install_profile'] = 'standard';
$config_directories['active'] = 'sites/default/files/config_rK_6KVDPn-s9l-ea_L0XBN1GzJlcnrZ3CssUXn1eQ7G98viRJXesYsSdsf_KjxkCRgelximKzg/active';
$config_directories['staging'] = 'sites/default/config/staging';
</code></pre>

<p>Is required your web server have permissions to read the configuration files, for instance if _www is the user running your web server you must run the following commands:</p>

<pre><code>$ sudo chown -R _www sites/default/config/staging/
$ sudo chmod -R 755 sites/default/config/staging/
</code></pre>

<p>Until here all looks OK, but If you go to the page example.com/admin/config/development/configuration you will get the following error</p>

<p><img src="http://enzolutions.com/assets/img/configuration_management_sync_error.png"/></p>

<p>We will solve this issue in next section.</p>

<h2>Force Site UUID match</h2>

<p>The Configuration Management only allow sync configuration between same site or project to avoid issues importing configuration from site a.com to b.com, to accomplish this validation Drupal 8 generate a <a target="_blank" href="https://www.drupal.org/project/uuid">UUID</a> for each site.</p>

<p>You cat get your current site UUDI executing the following command</p>

<pre><code>$ drush cget system.site
</code></pre>

<p>The command above we will have a similar output to next listing</p>

<pre><code>uuid: 236fa77c-d83e-42de-8a03-03c574c00160
name: backend.com
mail: enzo@enzolutions.com
slogan: ''
page:
  403: ''
  404: ''
  front: node
admin_compact_mode: false
weight_select_max: 100
langcode: en
</code></pre>

<p>The config import has a different UUID, you can confirm the UID with the following command</p>

<pre><code>$ cat sites/default/config/staging/system.site.yml
</code></pre>

<p>For that reason uou need to change the value of Site UUID using the following Drush command:</p>

<pre><code>$ drush cedit system.site
</code></pre>

<p>The command above enable you to use your favorite text editor to set the same UUID present in staging config files.</p>

<h2>Run Sync</h2>

<p>After change the UUID and change the permissions, if you visit again the page example.com/admin/config/development/configuration you will see all changes, deletions, renames, and additions as you can see in the following image:</p>

<p><img src="http://enzolutions.com/assets/img/configuration_management_sync.png"/></p>

<p>You can review the differences and remove some files from staging folder if you are not happy with the result and finally execute the Import All process.</p>

<p>If you are a Drush lover you still can run this process with Drush with the following command:</p>

<pre><code>$ drush config-import staging
</code></pre>

<p>After complete the import you have now site sync.</p>

<p>I hope you have found this article useful.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/08/27/understanding-configuration-management-in-drupal-8</link>
                    <pubDate>Wed, 27 Aug 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/08/27/understanding-configuration-management-in-drupal-8</guid>
                </item>
                                                                                                                                                                        <item>
                    <title>Yeoman Generator: Marionette JS + Drupal</title>
                    <description><![CDATA[<p><a href="http://yeoman.io">Yeoman</a> <a href="http://marionettejs.com">MarionetteJS</a> + <a href="drupical.org">Drupal</a> generator</p>

<p>Today I release the version 0.1.0-beta of <a href="http://enzolutions.com/projects/yeoman_generator_marionette_drupal">Yeoman Generator: Marionette + Drupal</a>.</p>

<p>If you want to create your own version of this generator, you can fork or download my version at</p>

<pre><code>$ git clone git@github.com:enzolutions/generator-marionette-drupal.git
</code></pre>

<p>This generator create a structured HTML 5 application generating modules using RequireJS, includes Grunt support to automate tasks.</p>

<p>Compass is used to generate CSS using bootstrap-sass.</p>

<p>The HTML 5 application is defined using a MVC pattern implemented with MarionetteJS and Backbone.Drupal for data model.</p>

<p>Includes scaffolding commands to create templates, models, collections, views and layouts.</p>
]]></description>
                    <link>http://enzolutions.com/articles/2014/06/16/yeoman-generator-marionette-js-drupal</link>
                    <pubDate>Mon, 16 Jun 2014 00:00:00 +0000</pubDate>
                    <guid>http://enzolutions.com/articles/2014/06/16/yeoman-generator-marionette-js-drupal</guid>
                </item>
                                                                                                                                                </channel>
</rss>
