<?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: Lucas Dasso</title>
    <description>The latest articles on DEV Community by Lucas Dasso (@lukas238).</description>
    <link>https://dev.to/lukas238</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%2F212490%2F45b1ec3c-bfb0-439b-8f05-ec7a11b14048.jpeg</url>
      <title>DEV Community: Lucas Dasso</title>
      <link>https://dev.to/lukas238</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lukas238"/>
    <language>en</language>
    <item>
      <title>Launch git-fork app from WSL</title>
      <dc:creator>Lucas Dasso</dc:creator>
      <pubDate>Fri, 25 Oct 2019 01:14:39 +0000</pubDate>
      <link>https://dev.to/lukas238/launch-git-fork-app-from-wsl-4pip</link>
      <guid>https://dev.to/lukas238/launch-git-fork-app-from-wsl-4pip</guid>
      <description>&lt;p&gt;As a web developer, I usually work on a Mac at work, and on my Windows 10 PC at home.&lt;/p&gt;

&lt;p&gt;This article descrieve how I mange to use the Windows &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; app from my &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL:DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;From WSL edit your ~/.bashrc file&lt;/li&gt;
&lt;li&gt;Add the following alias:&lt;code&gt;alias fork='/mnt/c/Windows/System32/cmd.exe /c "%USERPROFILE%\\AppData\Local\Fork\Fork.exe "$(wslpath -w -a .)'
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Save your changes.&lt;/li&gt;
&lt;li&gt;Restart the terminal, so the new alias become available.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;From WSL, navigate to a project folder that use git.&lt;/li&gt;
&lt;li&gt;Run the alias: &lt;code&gt;fork&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On Windows, the &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; app will open an the project git will be selected for view.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://code.visualstudio.com/"&gt;vscode&lt;/a&gt; and the integrated terminal to manage my projects (for example to run Gulp.js tasks).&lt;/p&gt;

&lt;p&gt;And as I do prefer the Linux/Mac terminal better, I configured &lt;a href="https://code.visualstudio.com/"&gt;vscode&lt;/a&gt; to work with the &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; bash as default.&lt;/p&gt;

&lt;p&gt;Now, and &lt;strong&gt;this is important&lt;/strong&gt;, I made symbolic link between my Window installation &lt;code&gt;Work&lt;/code&gt; folder at &lt;code&gt;C:\Work\&lt;/code&gt; and my &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; installation at &lt;code&gt;/home/ubuntu/Work/&lt;/code&gt; folder.&lt;br&gt;
This make super easy to work with any of my project, regardless if I'm working from Windows or from &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;One tool I like a lot is the free git client &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While I usually use git from between the &lt;a href="https://code.visualstudio.com/"&gt;vscode&lt;/a&gt;, or from the &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; terminal, I like &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; the best to visualize and manage my projects git branches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; is available for Mac and Windows, but not for Linux. :(&lt;/p&gt;

&lt;p&gt;And as I configured &lt;a href="https://code.visualstudio.com/"&gt;vscode&lt;/a&gt; to use &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; as the default bash, I was unable to launch &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; from the terminal in the current working folder, as I regulary can on Mac or Windows.&lt;/p&gt;

&lt;p&gt;Or that is what I thought, &lt;em&gt;at first&lt;/em&gt;. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  "wslpath" to the rescue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blogs.msdn.microsoft.com/commandline/2017/12/22/share-environment-vars-between-wsl-and-windows/"&gt;wslpath&lt;/a&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; tool that converts WSL paths to Windows paths.&lt;/p&gt;

&lt;p&gt;And since I already created a symbolic link for my &lt;code&gt;Work&lt;/code&gt; folder under &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt;, all what was left was &lt;em&gt;just&lt;/em&gt; to find a way to launch &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; on Windows from the &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; terminal, and to pass the current working &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; folder path converted to a Windows path.&lt;/p&gt;

&lt;p&gt;The first part was easy enough. You can launch any Windows app fro &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; using this command: &lt;code&gt;/mnt/c/Windows/System32/cmd.exe /c [PATH TO THE WINDOWS .EXE FILE]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So to launch &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; I can use this command: &lt;code&gt;/mnt/c/Windows/System32/cmd.exe /c "%USERPROFILE%\AppData\Local\Fork\Fork.exe&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Windows variable &lt;code&gt;%USERPROFILE%&lt;/code&gt; will be automatically replaced with your Windows User folder path (ex.: &lt;code&gt;C:\Users\yourusername&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can pass a path to &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; executable file to launch the app and to automatically open the git repository on that path.&lt;br&gt;
On linux, the current folder path is represented by &lt;code&gt;.&lt;/code&gt;. But passing this to the &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; executable on Windows means nothing. I needed a way to convert this to a full and absolute Windows path.&lt;/p&gt;

&lt;p&gt;And that is what &lt;a href="https://blogs.msdn.microsoft.com/commandline/2017/12/22/share-environment-vars-between-wsl-and-windows/"&gt;wslpath&lt;/a&gt; does!.&lt;/p&gt;

&lt;p&gt;So the final command looks like this: &lt;code&gt;/mnt/c/Windows/System32/cmd.exe /c "%USERPROFILE%\AppData\Local\Fork\Fork.exe "$(wslpath -w -a .)&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I added two parameters.&lt;br&gt;&lt;br&gt;
The &lt;code&gt;-w&lt;/code&gt; parameter &lt;em&gt;translate from a WSL path to a Windows path&lt;/em&gt;.&lt;br&gt;
And the &lt;code&gt;-a&lt;/code&gt; parameter &lt;em&gt;force result to absolute path format&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The final step is to add this working command as a &lt;code&gt;fork&lt;/code&gt; alias on my &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; installation, on your [WLS] user &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;br&gt;
From your &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; installation, edit the &lt;code&gt;~/.bashrc&lt;/code&gt; file and add the following line: &lt;code&gt;alias fork='/mnt/c/Windows/System32/cmd.exe /c "%USERPROFILE%\AppData\Local\Fork\Fork.exe "$(wslpath -w -a .)'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result is that I can use &lt;a href="https://git-fork.com/"&gt;Fork&lt;/a&gt; transparently from. between my &lt;a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux"&gt;WSL&lt;/a&gt; installation. I love it!&lt;/p&gt;

&lt;p&gt;Happy coding!!&lt;/p&gt;

</description>
      <category>wsl</category>
      <category>fork</category>
      <category>vscode</category>
      <category>git</category>
    </item>
    <item>
      <title>Custom module configuration form for Drupal</title>
      <dc:creator>Lucas Dasso</dc:creator>
      <pubDate>Fri, 16 Aug 2019 22:13:38 +0000</pubDate>
      <link>https://dev.to/lukas238/custom-module-configuration-form-for-drupal-j0b</link>
      <guid>https://dev.to/lukas238/custom-module-configuration-form-for-drupal-j0b</guid>
      <description>&lt;p&gt;Recently I found my self in the need to add a configuration page to a custom module in Drupal 7.&lt;/p&gt;

&lt;p&gt;This module was used to send daily email notification to the users, but settings like the recipient list email address were hardcoded in the code.&lt;/p&gt;

&lt;p&gt;To update this list I was forced to update the code repository and make a deploy on production. So this was not ideal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rvLjEiJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/p1MJTSh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rvLjEiJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/p1MJTSh.png" alt="Oh C'mon!" width="252" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I put my self to the task to learn how to &lt;em&gt;improve&lt;/em&gt; the custom module by adding its own configuration page. &lt;/p&gt;

&lt;p&gt;Finally it only took a couple of hours to read the relevant documentation, implement the code, and perform the relevant tests.&lt;/p&gt;

&lt;h1&gt;
  
  
   TL;DR
&lt;/h1&gt;

&lt;p&gt;You can skip directly to the documentation on this links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drupal 7 HowTos - Creating custom modules: &lt;a href="https://www.drupal.org/docs/7/creating-custom-modules"&gt;https://www.drupal.org/docs/7/creating-custom-modules&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Preparing for a module configuration form: &lt;a href="https://www.drupal.org/docs/7/creating-custom-modules/preparing-for-a-module-configuration-form"&gt;https://www.drupal.org/docs/7/creating-custom-modules/preparing-for-a-module-configuration-form&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Creating the configuration form: &lt;a href="https://www.drupal.org/docs/7/creating-custom-modules/creating-the-configuration-form"&gt;https://www.drupal.org/docs/7/creating-custom-modules/creating-the-configuration-form&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Validating the data: &lt;a href="https://www.drupal.org/docs/7/creating-custom-modules/validating-the-data"&gt;https://www.drupal.org/docs/7/creating-custom-modules/validating-the-data&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Drupal 7 form API: &lt;a href="https://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7.x"&gt;&lt;/a&gt;&lt;a href="https://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7.x"&gt;https://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7.x&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;You will need a Drupal instance with a custom module already created for witch you also have access to the source code.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to
&lt;/h1&gt;

&lt;p&gt;All steps are to be applied on the &lt;code&gt;.module&lt;/code&gt; file of your module, except for the step #2 that is to be applied on the &lt;code&gt;.info&lt;/code&gt; file of the module.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Adding a new menu item
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Implements hook_menu().
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;my_custom_module_menu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'admin/modules/my_custom_module'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'My Custom Module configuration'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Configuration for My Custom Module'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'page callback'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'drupal_get_form'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'page arguments'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_admin'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'access arguments'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'administer site configuration'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;MENU_NORMAL_ITEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this example the custom module name is &lt;code&gt;my_custom_module&lt;/code&gt;, so the hook_menu function name must be &lt;code&gt;my_custom_module_menu&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We add a new $items to the menu. The key value is the path to the main menu we want for this new page (in this example &lt;code&gt;admin/modules/my_custom_module&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;page arguments&lt;/code&gt; value points to the function that will be used to populate the form (in this example &lt;code&gt;my_custom_module_admi&lt;/code&gt;). We will build this function in the next step.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;access arguments&lt;/code&gt; value is used to determine who has access to this menu item.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Adding a configuration link in the module description
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--18xjHBdW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/aGWRIUz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--18xjHBdW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/aGWRIUz.png" alt="Configuration link" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding a configuration link on the custom module description page is simple as adding this line to the .info module file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my_custom_module&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This is the same menu path we already used on step #1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Adding items to the form
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;my_custom_module_admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// EMAILS Fieldset&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'fieldset'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Email account settings'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// From&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__from'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'textfield'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'From address'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#default_value'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__from'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Email address to be used as FROM and Reply-To.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#required'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// To&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__to'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'textarea'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'To address'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#default_value'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__to'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Recipient email address. You can add multiple email addresses by separating them by a colon (,) character.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'#required'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;system_settings_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding items to the form is simple enough using the Drupal form API documentation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this example we can find a fieldset and insde two email fields. The first an input text field for the FORM address, and the second a textarea for multiple recipients email addresses.&lt;/li&gt;
&lt;li&gt;In all the &lt;code&gt;#default_value&lt;/code&gt; parameters we make use of the Drupal function &lt;code&gt;variable_get&lt;/code&gt; to retrieve the last saved value of the field.&lt;/li&gt;
&lt;li&gt;The name of the field is the one you specified on the $form array. So, for &lt;code&gt;$form['my_custom_module_settings__emails']['my_custom_module_settings__emails__to']&lt;/code&gt; the variable name will be &lt;code&gt;my_custom_module_settings__emails__to&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The last line &lt;code&gt;return system_settings_form($form);&lt;/code&gt; will take care to save the form values on submit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
   4. Adding custom validating
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;my_custom_module_admin_validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nv"&gt;$from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'values'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__from'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;filter_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_VALIDATE_EMAIL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;form_set_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__from'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'You must enter a valid FROM email address.'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'values'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__to'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$to&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$to&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$to&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;filter_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_VALIDATE_EMAIL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;form_set_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_custom_module_settings__emails__to'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'You must enter a valid TO email address.'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Exit the For/Loop on first error&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While field parameters like '#required' will take care of basic validation like making a field requiered, some fields may require a more complex check up.&lt;/p&gt;

&lt;p&gt;You can add a validation hook with the function name &lt;code&gt;my_custom_module_admin_validate&lt;/code&gt; and add your own validations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All form field values will be available inside the &lt;code&gt;$form_state['values']&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can validate multiple fields, and return errors individually by using the Drupal function &lt;code&gt;form_set_error&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thats all. Happy coding!&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>forms</category>
      <category>php</category>
    </item>
    <item>
      <title>How to backup AWS Security Groups settings</title>
      <dc:creator>Lucas Dasso</dc:creator>
      <pubDate>Thu, 15 Aug 2019 13:21:48 +0000</pubDate>
      <link>https://dev.to/lukas238/how-to-backup-aws-security-groups-settings-5ia</link>
      <guid>https://dev.to/lukas238/how-to-backup-aws-security-groups-settings-5ia</guid>
      <description>&lt;p&gt;If, like me, you have to manage several Security Groups on your AWS account, you can make use of the &lt;code&gt;describe-security-groups&lt;/code&gt; AWS CLI command for download them as a .json file for backup.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;You can jump to the &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-security-groups.html"&gt;official AWS documentation&lt;/a&gt; for the &lt;code&gt;describe-security-groups&lt;/code&gt; AWS CLI command on this link: &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-security-groups.html"&gt;https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-security-groups.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;You will need to have the AWS CLI command line tool &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;installed&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;configured&lt;/a&gt; on your system.&lt;/p&gt;

&lt;p&gt;You can find the necessary information on this two links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open a terminal window on a local folder and run this command:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-security-groups &lt;span class="nt"&gt;--group-ids&lt;/span&gt; sg-123abcd4

&lt;/code&gt;&lt;/pre&gt;


&lt;blockquote&gt;
&lt;p&gt;You will need the ID of the Security Group you want the backup (in this example 'sg-123abcd4').&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Done! You can now backup the newly created .json file with GIT or in any other way you want.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  About the .json file
&lt;/h2&gt;

&lt;p&gt;As a quick reference here is how the .json file looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"SecurityGroups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"IpPermissionsEgress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My security group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"IpPermissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"PrefixListIds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"FromPort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"IpRanges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"CidrIp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.0/24"&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"ToPort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"IpProtocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"UserIdGroupPairs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"GroupName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MySecurityGroup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"OwnerId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789012"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"GroupId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sg-903004f8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>securitygroups</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
