<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jon McLaughlin 🍄</title>
    <description>The latest articles on DEV Community by Jon McLaughlin 🍄 (@jonmcl).</description>
    <link>https://dev.to/jonmcl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F329684%2F59d6a4fe-cb5f-4bc4-bdbe-c039c37b4e0a.jpg</url>
      <title>DEV Community: Jon McLaughlin 🍄</title>
      <link>https://dev.to/jonmcl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonmcl"/>
    <language>en</language>
    <item>
      <title>Replacing the included PHP Xdebug module in MAMP Pro</title>
      <dc:creator>Jon McLaughlin 🍄</dc:creator>
      <pubDate>Tue, 16 Jun 2020 18:10:52 +0000</pubDate>
      <link>https://dev.to/jonmcl/replacing-the-included-php-xdebug-module-in-mamp-pro-3nj4</link>
      <guid>https://dev.to/jonmcl/replacing-the-included-php-xdebug-module-in-mamp-pro-3nj4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I'm a fan of MAMP Pro (&lt;a href="https://www.mamp.info/mamp-pro/"&gt;https://www.mamp.info/mamp-pro/&lt;/a&gt;). I do all my web development work on a Mac and I like the simplicity of having one MySQL server, one Apache (or Nginx) server, a centralized GUI tool for modifying /etc/hosts, and I can switch between any of the supported PHP versions by linking a virtual host to a different PHP-FPM service.&lt;/p&gt;

&lt;p&gt;Where MAMP Pro fails me is that I am reliant on the PHP versions they have made a decision to build into the the app. Each PHP-FPM service is actually installed with the app's package. MAMP doesn't use the OS' PHP, and I'm mostly okay with this.&lt;/p&gt;

&lt;p&gt;Unfortunately, the most recent version of PHP 7.3 that has been included in MAMP Pro 5.7 is PHP 7.3.9. There are probably a lot of reasons why I should be using a more current version of PHP (7.3.19), but this old PHP version also means that MAMP has bundled a bugged version of Xdebug (2.9.0). This particular version of Xdebug has a bug that will cause the PHPStorm debugger to trigger at the declaration of a function that contains a breakpoint rather than at the actual breakpoint. More information on this Xdebug 2.9.0 bug is at &lt;a href="https://bugs.xdebug.org/view.php?id=1727"&gt;https://bugs.xdebug.org/view.php?id=1727&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, Xdebug is a module and not part of the actual PHP build. Modules can be compiled independently of the PHP code and I was able to easily upgrade the Xdebug that is included as part of MAMP. The Xdebug module does need to have knowledge of the PHP that you are going to install it into, so for that reason you can't simply link the PHP-FPM service to another Xdebug installed somewhere else for another PHP.&lt;/p&gt;

&lt;p&gt;Xdebug has a great tool to assist: &lt;a href="http://xdebug.org/wizard"&gt;http://xdebug.org/wizard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I use a Homebrew installation of PHP CLI instead of MAMP and simply following the standard Xdebug install or compile instructions would lead the an Xdebug module that was configured the the CLI PHP and not MAMP's PHP.&lt;/p&gt;

&lt;p&gt;So some slightly modified instructions for when you get to the &lt;code&gt;phpize&lt;/code&gt; part of the compile instructions found on &lt;a href="http://xdebug.org/docs/install"&gt;http://xdebug.org/docs/install&lt;/a&gt;. My paths are based on a standard MAMP Pro installation on a Mac and are specific to PHP version 7.3.9 that comes with MAMP Pro 5.7.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instructions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In a new Terminal window, enter &lt;code&gt;/Applications/MAMP/bin/php/php7.3.9/bin/php -i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy-and-paste the output of this command into the textarea that appears on &lt;a href="http://xdebug.org/wizard.Click"&gt;http://xdebug.org/wizard.Click&lt;/a&gt; the form button to analyze your MAMP's phpinfo() output.&lt;/li&gt;
&lt;li&gt;Follow the presented instructions, including downloading the most recent version of Xdebug to your &lt;code&gt;~/Downloads&lt;/code&gt; folder (xdebug-2.9.6.tgz at the time of this post)&lt;/li&gt;
&lt;li&gt;If you used Mac OS's tar extractor instead of the tar command, you may have to go one level deeper for step 4 of the Xdebug instructions (&lt;code&gt;cd ~/Downloads/xdebug-2.9.6/xdebug-2.9.6&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;For step 5 on that page, you are instructed to run &lt;code&gt;phpize&lt;/code&gt; from within the source code directory. Substitute this command:
&lt;code&gt;/Applications/MAMP/bin/php/php7.3.9/bin/phpize&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For step 6 on the Xdebug instructions, substitute this command:
&lt;code&gt;./configure --with-php-config=/Applications/MAMP/bin/php/php7.3.9/bin/php-config&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;make&lt;/code&gt; as normal from within the source code directory.&lt;/li&gt;
&lt;li&gt;Follow the cp instructions on step 8. It should be something like:
&lt;code&gt;cp modules/xdebug.so /Applications/MAMP/bin/php/php7.3.9/lib/php/extensions/no-debug-non-zts-20180731&lt;/code&gt; (make sure you are still inside the Xdebug source code directory)&lt;/li&gt;
&lt;li&gt;You will not have to edit the MAMP &lt;code&gt;php.ini&lt;/code&gt; file as instructed in step 9 of the Xdebug compile installation instructions. This is because we are replacing the older version of Xdebug with our newly compiled one. The MAMP php.ini will include the Xdebug module (&lt;code&gt;xdebug.so&lt;/code&gt;) when you enable Xdebug in the MAMP Pro GUI.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Hopefully this helps you. It still might be better to build a whole new PHP, with a more up-to-date Xdebug, to replace the outdated PHP 7.3.9 that is currently included with MAMP Pro 5.7. However, this was quicker and simpler for me to accomplish, probably because of the great instructions wizard included on xdebug.org, and this solution got me back in business with PHP 7.3.&lt;/p&gt;

&lt;p&gt;Consider supporting continued Xdebug development financially:  &lt;a href="https://xdebug.org/support"&gt;https://xdebug.org/support&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>xdebug</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Power Of Twig's Merge Filter With Drupal 8 Templates</title>
      <dc:creator>Jon McLaughlin 🍄</dc:creator>
      <pubDate>Thu, 05 Mar 2020 19:12:52 +0000</pubDate>
      <link>https://dev.to/jonmcl/the-power-of-twig-s-merge-filter-with-drupal-8-templates-4l7b</link>
      <guid>https://dev.to/jonmcl/the-power-of-twig-s-merge-filter-with-drupal-8-templates-4l7b</guid>
      <description>&lt;p&gt;Rendering web content in Drupal is a little bit like building a web page that is an onion. You have to peel back the layers to find the right place to make changes. Luckily, most everything ends up at a suggested Twig template. The Twig template engine is one of the best things about Drupal 8. It is powerful and easy to use for all levels of developer proficiencies.&lt;/p&gt;

&lt;p&gt;I often find myself creating Twig templates for different node content types and view modes. So, for example, I might have a Twig template in my theme that is named "node--project--full.html.twig". This template will get utilized for the "project" content types and when the "full" view mode is used.&lt;/p&gt;

&lt;p&gt;This method allows me to put one field of the project content type in a specific place on the page. Maybe below it will be more fields that are in a 9 column space on the left, and a few more fields are in a 3 column space on the right.&lt;/p&gt;

&lt;p&gt;Twig lets you use regular HTML to create the layout for this content type &amp;amp; view mode. You can then use simple Twig syntax to place various fields in various places of the layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight twig"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;title_attributes&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"columns medium-9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.body&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"columns medium-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_project_date&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
        &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_project_link&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
        &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_tags&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Very simple and works well, but what if you want to customize the rendered output that comes from each of those content.field elements? Drupal and Twig definitely allow you to peel back the onion and use a usage specific templates for each of those field elements. For example, you can put a Twig template named "field--node--field-project-date--project--full.html.twig" in your theme, rebuild the Drupal cache, and then you can get as specific as you want for the rendered HTML of that particular field when it is used in that particular content type ("project") and for that particular view mode ("full").&lt;/p&gt;

&lt;p&gt;I use this pattern for simple changes to the fields. Maybe I want to add a "button" class to a link field when it is used in a specific view mode. Or maybe I want to use a specific field label. Drupal's pattern of template suggestions works well, but in the end you do end up with potentially dozens of field templates in your theme.&lt;/p&gt;

&lt;p&gt;For simple customization of individually fields, particularly when the customization only applies to a node &amp;amp; view template, I realized there is a way to use Twig's merge filter.&lt;/p&gt;

&lt;p&gt;Twig &lt;a href="https://twig.symfony.com/doc/2.x/filters/index.html"&gt;filters&lt;/a&gt; are simple utility functions that you can call on any variable that is in the Twig template's context.&lt;/p&gt;

&lt;p&gt;Let's say I need to use a different label for a field in one particular view mode. Instead of creating a specific field template, I can just alter the node's template like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight twig"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;title_attributes&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"columns medium-9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.body&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"columns medium-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_project_date&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'#label_display'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'above'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'#title'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Year'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
      &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_project_link&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
      &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_tags&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this level of Drupal's render onion, content is an array of fields and each field is another array.&lt;/p&gt;

&lt;p&gt;In this case, I'm changing the field label from "Project Launch Date" to simply "Year". I will still have to customize the output of the field formatter to just display a year, but most Drupal field formatters don't allow for label customization beyond showing or hiding it.&lt;/p&gt;

&lt;p&gt;Most standard Drupal field formatters also don't allow for customization of the class attributes that get used when the field is rendered. You could create separate field templates or you could use various preprocess hooks in your front-end theme. A possibly simpler way is to just use the merge filter in your node Twig template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight twig"&gt;&lt;code&gt;    &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;content.field_project_link&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'#attributes'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'class'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'my-custom-class'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'another-custom-class'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It is worth noting that these additional class attributes are being applied to the field wrapper. If you want to apply changes to the individual items of the field this would likely not be possible to do at this level of the onion. You might still need to create a "field--field-project-link.html.twig" template, but you could maybe avoid having to write a preprocess function for it if you just wanted to add some additional attributes to the link items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight twig"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;attributes.addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;items&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
      &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;item.content&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'#attributes'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'class'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
      &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
    &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To do any of this you will have to have a good understanding of all the various Drupal render arrays that your fields might be using. One of the best ways to learn what is going on inside of a Twig template is to configure your IDE to allow you to place debug breakpoints within the template itself. Then you can just inspect the $context variable and see which theme function is being called when something like item.content is rendered.&lt;/p&gt;

&lt;p&gt;I'd love to hear if you think this method makes things simpler or more complicated.&lt;/p&gt;

</description>
      <category>twig</category>
      <category>drupal</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
