<?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>Forem: Elliot Derhay</title>
    <description>The latest articles on Forem by Elliot Derhay (@jsn1nj4).</description>
    <link>https://forem.com/jsn1nj4</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%2F73543%2Ffcafec56-6670-4bab-ab25-e3ca3216f75e.png</url>
      <title>Forem: Elliot Derhay</title>
      <link>https://forem.com/jsn1nj4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jsn1nj4"/>
    <language>en</language>
    <item>
      <title>How to make Laravel Pennant features that apply globally</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Fri, 05 May 2023 11:54:43 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/how-to-make-laravel-pennant-features-that-apply-globally-3gg6</link>
      <guid>https://forem.com/jsn1nj4/how-to-make-laravel-pennant-features-that-apply-globally-3gg6</guid>
      <description>&lt;p&gt;If you use feature flags, Laravel Pennant probably caught your attention in the Laravel 10 announcement. This was the part of upgrading to Laravel 10 that I was looking forward to the most.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Laravel Pennant?
&lt;/h2&gt;

&lt;p&gt;Pennant is &lt;a href="https://laravel.com/docs/10.x/pennant#defining-features"&gt;a package&lt;/a&gt; that provides standardized feature flags out of the box. Features are saved in a dedicated table &lt;code&gt;features&lt;/code&gt;, along with their scope(s) and status.&lt;/p&gt;

&lt;p&gt;Here’s a simple example of how to define a Pennant feature:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nc"&gt;Feature&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'new-feature'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&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="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isBetaTester&lt;/span&gt;&lt;span class="p"&gt;()&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="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&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;&lt;em&gt;(This is a simpler version of a snippet from the Pennant docs.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now if you were to check ‘&lt;code&gt;new-feature'&lt;/code&gt; like &lt;code&gt;Feature::active('new-feature')&lt;/code&gt;, you might find an entry like this in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id | name        | scope             | value | created_at          | updated_at
 1 | new-feature | App\Models\User:1 | true  | 2023-01-01 00:00:00 | 2023-01-01 00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also define features in a service provider, or as dedicated &lt;a href="https://laravel.com/docs/10.x/pennant#class-based-features"&gt;feature classes&lt;/a&gt;.&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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Features&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewFeature&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
      * Resolve the feature's initial value.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&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="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isBetaTester&lt;/span&gt;&lt;span class="p"&gt;()&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="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(This is a simpler version of a snippet from the Pennant docs.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you checked or updated a class-based feature, you might find an entry like this in the &lt;code&gt;features&lt;/code&gt; table instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id | name                    | scope             | value | created_at          | updated_at
 1 | App\Features\NewFeature | App\Models\User:1 | true  | 2023-01-01 00:00:00 | 2023-01-01 00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The value returned in both examples is the &lt;em&gt;default&lt;/em&gt; value. You decide the default based on whatever conditions you want. After it’s initialized, the table is checked instead.&lt;/p&gt;

&lt;p&gt;As you can see, this example feature is based on a &lt;code&gt;User&lt;/code&gt; class. Pennant’s doc explains that Pennant, by default, scopes features to the authenticated user.&lt;/p&gt;

&lt;p&gt;This means if you check a feature like &lt;code&gt;Feature::active('new-feature')&lt;/code&gt;, Pennant will automatically use a &lt;code&gt;User&lt;/code&gt; object to check or act on a feature. If no matching entry for that feature and &lt;code&gt;User&lt;/code&gt; scope is found in the DB, a new one will be saved based on the feature’s defaults.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing a feature’s scope
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://laravel.com/docs/10.x/pennant#specifying-the-scope"&gt;Pennant docs&lt;/a&gt; give an example on how to change the scope. Basically, you type the parameter for default resolution to something else (say &lt;code&gt;Team&lt;/code&gt; instead of &lt;code&gt;User&lt;/code&gt;), and then use &lt;code&gt;Feature::for()&lt;/code&gt; to pass the scope value.&lt;/p&gt;

&lt;p&gt;If there were no default scope, you’d do &lt;code&gt;Feature::for($user)-&amp;gt;active('new-feature')&lt;/code&gt; or something similar &lt;em&gt;every time&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  So how do we make a feature global?
&lt;/h2&gt;

&lt;p&gt;By “global”, I mean on or off for &lt;em&gt;everyone&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You probably don’t want to do this &lt;em&gt;too much&lt;/em&gt; on larger projects. But if you have a small public project, you’ll probably use it more.&lt;/p&gt;

&lt;p&gt;The simplest way is to make your feature expect &lt;code&gt;null&lt;/code&gt;.&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="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// I use `false` as an example only. You can default your&lt;/span&gt;
&lt;span class="c1"&gt;// features to `true` (active) if you want.&lt;/span&gt;
&lt;span class="nc"&gt;Feature&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'new-feature'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;null&lt;/span&gt; &lt;span class="nv"&gt;$scope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then when you check features, you will pass &lt;code&gt;null&lt;/code&gt; explicitly:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nc"&gt;Feature&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;active&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That technically &lt;code&gt;resolve&lt;/code&gt;s this question, but what if most of your features will be “global”?&lt;/p&gt;

&lt;h2&gt;
  
  
  Defaulting to “global scope”
&lt;/h2&gt;

&lt;p&gt;Pennant’s docs have a section on setting the &lt;a href="https://laravel.com/docs/10.x/pennant#default-scope"&gt;default scope&lt;/a&gt;. This is something you call in a service provider, like in the &lt;code&gt;AppServiceProvider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our case, we can write something like this:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Providers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Auth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Pennant\Feature&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppServiceProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
      * Bootstrap any application services.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Feature&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;resolveScopeUsing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&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;Now anytime we don’t call &lt;code&gt;Feature::for()&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; will be passed automatically.&lt;/p&gt;

&lt;p&gt;Now features will have entries like this in the DB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id | name        | scope          | value | created_at          | updated_at
 1 | new-feature | __laravel_null | true  | 2023-01-01 00:00:00 | 2023-01-01 00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;null&lt;/code&gt; is used in the scope, Pennant saves &lt;code&gt;__laravel_null&lt;/code&gt; as the scope.&lt;/p&gt;

&lt;p&gt;Incidentally, if you were to test or update a feature using something like a command or queued job, this is also the scope. The docs aren’t explicit about this, but at the bottom of the &lt;a href="https://laravel.com/docs/10.x/pennant#checking-features"&gt;“Checking Features”&lt;/a&gt; section of the doc, it implies this type of behavior is because it’s running in an unauthenticated context—meaning, there’s no auth’d user interacting with the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;With a little digging, we were able to create features that apply globally instead of being scoped to specific contexts and even learn a little extra about Pennant that’s not spelled out in the docs.&lt;/p&gt;

&lt;p&gt;I hope you found this post useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>feature</category>
      <category>flags</category>
    </item>
    <item>
      <title>Caching Laravel configs that use objects</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Sat, 29 Apr 2023 19:51:44 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/caching-laravel-configs-that-use-objects-1pp0</link>
      <guid>https://forem.com/jsn1nj4/caching-laravel-configs-that-use-objects-1pp0</guid>
      <description>&lt;p&gt;&lt;strong&gt;Real quick:&lt;/strong&gt; If you’re using &lt;code&gt;spatie/laravel-markdown&lt;/code&gt; and having this issue (how I ran into this), it was partially fixed with &lt;a href="https://github.com/spatie/laravel-markdown/pull/53"&gt;PR#53&lt;/a&gt; recently. 🎉&lt;/p&gt;




&lt;p&gt;This headline might be a bit of a head-scratcher for you. It comes from an issue that I ran into recently—and that I didn’t dig into right away.&lt;/p&gt;

&lt;p&gt;Basically, running &lt;code&gt;artisan config:cache&lt;/code&gt; started giving me errors about not being able to serialize my configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rewind ⏪
&lt;/h2&gt;

&lt;p&gt;If you haven’t used Laravel before, one of its directories in the project root is &lt;code&gt;config/&lt;/code&gt;. This directory houses PHP files for project settings—mostly Laravel’s, but you can create and register your own too. Some installed packages also let you publish &lt;em&gt;their&lt;/em&gt; configs to that directory for you to customize.&lt;/p&gt;

&lt;p&gt;The combined application config is normally rebuilt for every request. To speed this up, Laravel has a &lt;code&gt;config:cache&lt;/code&gt; command to generate 1 config file. This includes any values that might’ve been resolved dynamically, like from function calls. And it usually “just works”.&lt;/p&gt;

&lt;h2&gt;
  
  
  When “just works”, doesn’t 💥
&lt;/h2&gt;

&lt;p&gt;Sometimes you might need an object in your config, like if you’re using Spatie’s &lt;a href="https://spatie.be/docs/laravel-markdown/v1"&gt;Laravel Markdown&lt;/a&gt; package and creating custom renderers.&lt;/p&gt;

&lt;p&gt;For example:&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="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;‌?&lt;/span&gt;&lt;span class="na"&gt;php&lt;/span&gt;
&lt;span class="na"&gt;return&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;
  &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;block_renderers&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; [
    ['class' =&amp;gt; BlockQuote::class, 'renderer' =&amp;gt; new BlockQuoteRenderer(), 'priority' =&amp;gt; 1],
    ['class' =&amp;gt; Heading::class, 'renderer' =&amp;gt; new HeadingRenderer(), 'priority' =&amp;gt; 1],
    ['class' =&amp;gt; ListItem::class, 'renderer' =&amp;gt; new ListItemRenderer(), 'priority' =&amp;gt; 1],
  ],
  //...
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this doesn’t look bad. But if you do this as-is and then run &lt;code&gt;config:cache&lt;/code&gt;, you'll get an error similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  LogicException

  Your configuration files are not serializable.

  at /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConfigCacheCommand.php:80
     76▕             require $configPath;
     77▕         } catch (Throwable $e) {
     78▕             $this-&amp;gt;files-&amp;gt;delete($configPath);
     79▕
  ➜  80▕             throw new LogicException('Your configuration files are not serializable.', 0, $e);
     81▕         }
     82▕
     83▕         $this-&amp;gt;info('Configuration cached successfully!');
     84▕     }

  1   /path/to/project/bootstrap/cache/config.php:&amp;lt;line-number&amp;gt;
      Error::("Call to undefined method App\Markdown\Renderers\BlockQuoteRenderer::__set_state()")

  2   /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConfigCacheCommand.php:76
      require()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What causes this? 🤨
&lt;/h2&gt;

&lt;p&gt;The error message might need clarifying. For 1, it says “not serializeable”. That might lead you to believe &lt;code&gt;config:cache&lt;/code&gt; is calling &lt;code&gt;serialize()&lt;/code&gt; under the hood, but it’s not.&lt;/p&gt;

&lt;p&gt;It’s also not pointing out &lt;em&gt;which&lt;/em&gt; config it’s having trouble with.&lt;/p&gt;

&lt;p&gt;But with some digging through &lt;code&gt;laravel/framework&lt;/code&gt;, we find &lt;a href="https://github.com/laravel/framework/blob/10.x/src/Illuminate/Foundation/Console/ConfigCacheCommand.php#L62-L69"&gt;this section of code&lt;/a&gt;:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;//...&lt;/span&gt;
        &lt;span class="nv"&gt;$configPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;laravel&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCachedConfigPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;$configPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;?php return '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;';'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;$configPath&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In there, there’s a call to &lt;code&gt;var_export()&lt;/code&gt;. If we look at the &lt;a href="https://www.php.net/manual/en/function.var-export.php"&gt;PHP manual&lt;/a&gt; for that function, it shows examples of different types of output.&lt;/p&gt;

&lt;p&gt;But look specifically at &lt;strong&gt;Example #3: Exporting Classes&lt;/strong&gt;. It has this sample output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A::__set_state(array(
   'var' =&amp;gt; 5,
))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might remember that that static method, &lt;code&gt;__set_state()&lt;/code&gt;, appears in the stack trace from earlier.&lt;/p&gt;

&lt;p&gt;If we read &lt;a href="https://www.php.net/manual/en/language.oop5.magic.php#object.set-state"&gt;PHP’s magic methods page&lt;/a&gt;, we’ll see that this static method allows parsing an exported object string back into an object while automatically providing it with its old exported data!&lt;/p&gt;

&lt;p&gt;And rereading that snippet from &lt;code&gt;laravel/framework&lt;/code&gt;, what’s happening makes sense now. When calling &lt;code&gt;config:cache&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Laravel is reading in the full, generated config and generating a combined PHP file from that. Then,&lt;/li&gt;
&lt;li&gt;it’s immediately reading in this pre-built PHP file, triggering calls to that magic method.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So it seems this error is just a side effect of how config caching works.&lt;/p&gt;

&lt;h2&gt;
  
  
  So how do we get around this? 🤔
&lt;/h2&gt;

&lt;p&gt;We can implement &lt;code&gt;__set_state()&lt;/code&gt; for classes we “new up” in our configs. The &lt;code&gt;return&lt;/code&gt; value should be an instance of that class too.&lt;/p&gt;

&lt;p&gt;For my renderers, I wrote a trait:&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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;Resumeable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$state_array&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;static&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;static&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$state_array&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$prop&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;)&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;property_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prop&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$prop&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$state&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;$object&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;I tested this on PHP 8.1. Since it’s being called from within the class it affects, it also works on &lt;code&gt;private&lt;/code&gt; and &lt;code&gt;protected&lt;/code&gt; properties.&lt;/p&gt;

&lt;p&gt;Good thing too, because &lt;code&gt;var_export()&lt;/code&gt; exports data from &lt;code&gt;private&lt;/code&gt; and &lt;code&gt;protected&lt;/code&gt; properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary 📋
&lt;/h2&gt;

&lt;p&gt;You may not need this very often. And if you’re using &lt;code&gt;spatie/laravel-markdown&lt;/code&gt;, &lt;a href="https://github.com/spatie/laravel-markdown/pull/53"&gt;PR#53&lt;/a&gt; did get merged pretty quickly, so you can just use class strings now (Thanks &lt;a href="https://github.com/erikn69"&gt;erikn69&lt;/a&gt; and &lt;a href="https://github.com/freekmurze"&gt;freekmurze&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;But this is 1 way to get around config caching issues you may run into.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt; 👋&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>caching</category>
    </item>
    <item>
      <title>Doing it Wrong #1: Using CSS to Render Content</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Wed, 19 Apr 2023 12:07:00 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/doing-it-wrong-1-using-css-to-render-content-50ka</link>
      <guid>https://forem.com/jsn1nj4/doing-it-wrong-1-using-css-to-render-content-50ka</guid>
      <description>&lt;p&gt;It should go without saying, if you’re adding blocks of written content to a page using CSS, you’re “doing it wrong”.&lt;/p&gt;

&lt;p&gt;But since we’re just having fun here, why not? Also, I’ll be using Sass right from the beginning to save some keystrokes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial idea
&lt;/h2&gt;

&lt;p&gt;At first I thought I’d just style a bunch of HTML tags with &lt;code&gt;content&lt;/code&gt; and be done with it. That’s how that property works, right?&lt;/p&gt;

&lt;p&gt;So this was more-or-less my initial solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.event&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Awesome Regional Conference 2023"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.date&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5/21/2023"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.venue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Totally Real Conference Hall"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.location&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"123 Totally Real Blvd, Austin, Tx"&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;And I thought it was done. Let’s throw this into &lt;a href="https://jsfiddle.net/jsn1nj4/kxLphyf0/3/"&gt;JSFiddle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7vUUIxxr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wiqaq6fstkbakzp5z9nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7vUUIxxr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wiqaq6fstkbakzp5z9nt.png" alt="Attempt 1" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wow, who else didn’t see that coming…? Really, only me…?
&lt;/h2&gt;

&lt;p&gt;If you use &lt;code&gt;content&lt;/code&gt; a lot, you probably saw this coming. I obviously don’t. So first I confirmed it was being set on the elements I expected it to be set on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ltvrNLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3eq44zdcagpr5i9z0pf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ltvrNLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3eq44zdcagpr5i9z0pf.png" alt="Confirming styles are there" width="315" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I started messing around with styles: margins, dimensions, font sizes and colors etc.&lt;/p&gt;

&lt;p&gt;After scratching my head for a little while, I remembered that the only times I actually had used &lt;code&gt;content&lt;/code&gt; were on &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt;. So I &lt;a href="https://jsfiddle.net/jsn1nj4/kxLphyf0/5/"&gt;gave that a shot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And look at that, it worked right away!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--grHeqbHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b0l3k4brdiq3ol11nmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--grHeqbHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b0l3k4brdiq3ol11nmf.png" alt="It works!" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I suppose it makes sense that &lt;code&gt;content&lt;/code&gt; can’t work directly on the main content area of an HTML element. That would probably break its actual HTML and text content. In hindsight, I should’ve learned how &lt;code&gt;content&lt;/code&gt; worked sooner when messing with &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; styles defined by tools like Bootstrap and FontAwesome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it further
&lt;/h2&gt;

&lt;p&gt;Ok, so now we’re rendering written content into HTML via CSS. How can this be a bit more reusable? With &lt;a href="https://jsfiddle.net/jsn1nj4/kxLphyf0/20/"&gt;CSS variables&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sgHHJa4f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yab3tzzvp3tpgcyogy4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sgHHJa4f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yab3tzzvp3tpgcyogy4h.png" alt="Using CSS vars" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! So now we can generate styles for a specific event ID and it’ll work.&lt;/p&gt;

&lt;p&gt;But we’re also making things a bit repetitive now. Imagine if you had 10-20 elements like this with matching vars. Blech.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mixins to the rescue!
&lt;/h2&gt;

&lt;p&gt;Since Sass has mixins, this’ll help us clean up a bit more (I know, this is all wrong and messy anyway, but humor me). If we write a mixin name—say, &lt;code&gt;before&lt;/code&gt;—we can automatically generate all of the classes and look for the right CSS vars, just with a list of strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$labels&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="k"&gt;@for&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="ow"&gt;from&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;to&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;.&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$labels&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$labels&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;$var...&lt;/code&gt; syntax in the mixin signature, we can condense all arguments to the mixin into 1 list.&lt;/p&gt;

&lt;p&gt;If we had 2 params instead of 1, then it would work more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$param1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$param2&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="c1"&gt;// here, $param1 gets the first argument, and $param2 gets all&lt;/span&gt;
&lt;span class="c1"&gt;// other arguments after that: "something else" and&lt;/span&gt;
&lt;span class="c1"&gt;// "something else again".&lt;/span&gt;
&lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"something"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"something else"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"something else again"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then using the &lt;code&gt;@for&lt;/code&gt; loop above combined with &lt;code&gt;length($labels)&lt;/code&gt;, we can loop over the whole list. And using &lt;code&gt;nth&lt;/code&gt;, we can use each string in the list as both the class selector and CSS var name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some things to note about &lt;code&gt;@for&lt;/code&gt; and &lt;code&gt;nth()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;You’ll notice the range in the loop is basically 0 to &lt;code&gt;length($labels)&lt;/code&gt;. This works how you’d expect most &lt;code&gt;for&lt;/code&gt; loops to work: start at &lt;code&gt;0&lt;/code&gt;, stop when you reach &lt;code&gt;length&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But lists in Sass are actually &lt;em&gt;indexed&lt;/em&gt; starting at &lt;code&gt;1&lt;/code&gt;. So there is no “element 0”, and the last element’s index number is the same as the length of the list.&lt;/p&gt;

&lt;p&gt;This forces us to do a little extra math in 1 of 2 places: the loop definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@for&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="ow"&gt;from&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;to&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;… or the loop body, like above: &lt;code&gt;$i + 1&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ahh, nice and clean
&lt;/h2&gt;

&lt;p&gt;Here’s the working version of &lt;a href="https://jsfiddle.net/jsn1nj4/kxLphyf0/23/"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  But wait, there’s more…
&lt;/h2&gt;

&lt;p&gt;What if we wanted to do something even crazier, like adding extra content into our HTML?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O2zaRwN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd3gzbtfapiirs9gllc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O2zaRwN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd3gzbtfapiirs9gllc2.png" alt="Getting crazy" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh right, we’re using &lt;code&gt;::before&lt;/code&gt;, so our CSS content is &lt;em&gt;literally&lt;/em&gt; before the actual HTML content.&lt;/p&gt;

&lt;p&gt;Let’s switch that around a bit: rename the mixin and use the &lt;code&gt;::after&lt;/code&gt; pseudo-element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MdfQE609--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gulss3rb883am75palxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MdfQE609--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gulss3rb883am75palxu.png" alt="Before and After" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there it is, the &lt;a href="https://jsfiddle.net/jsn1nj4/kxLphyf0/26/"&gt;final version&lt;/a&gt; of our backwards little CSS project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls
&lt;/h2&gt;

&lt;p&gt;This is a given, but there are problems with doing this unironically.&lt;/p&gt;

&lt;p&gt;First, content set in &lt;code&gt;content&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/content#accessibility_concerns"&gt;does not exist in the DOM&lt;/a&gt;. This makes getting the content back out very difficult and hurts accessibility.&lt;/p&gt;

&lt;p&gt;Next, it adds overhead where none is needed. CSS is for changing the appearance of content, not &lt;em&gt;rendering&lt;/em&gt; content directly.&lt;/p&gt;

&lt;p&gt;Lastly, along with that last point, it couples entire content placements and even parts of your frontend implementation to your stylesheet. Your frontend should not need to &lt;em&gt;use&lt;/em&gt; your stylesheet to render content when it’s already rendering everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was learned?
&lt;/h2&gt;

&lt;p&gt;For starters, This type of thing is insane to do on a serious project, so maybe &lt;em&gt;don't&lt;/em&gt;—unless you do code golf. Do be crazy in code golf. 😉&lt;/p&gt;

&lt;h3&gt;
  
  
  More practically:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you don't use &lt;code&gt;content&lt;/code&gt; much (raising my hand ✋), you learned it doesn't do anything to HTML elements that actually have their own content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Why&lt;/em&gt; it doesn't affect HTML content is important: what it renders is outside the DOM, which can negatively impact your overall user experience, especially for accessibility.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>sass</category>
      <category>dontdothis</category>
    </item>
    <item>
      <title>As a dev, how much time do you spend learning Docker?</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Sun, 15 May 2022 19:58:38 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/as-a-dev-how-much-time-do-you-spend-learning-docker-1jef</link>
      <guid>https://forem.com/jsn1nj4/as-a-dev-how-much-time-do-you-spend-learning-docker-1jef</guid>
      <description>&lt;p&gt;As devs, do you learn the ins and outs of using Docker with your normal toolset or rely only on working examples and boilerplate you find online?&lt;/p&gt;

&lt;p&gt;I know this probably seems weird to ask about such a universally-known tool as Docker. But being someone who has little time to myself, it's a pretty big question.&lt;/p&gt;

&lt;p&gt;I'm also currently using Lando as much as I can; it's a nice abstraction. But I still occasionally run into use cases that make me wish I knew Docker.&lt;/p&gt;

</description>
      <category>question</category>
      <category>docker</category>
      <category>lando</category>
      <category>devops</category>
    </item>
    <item>
      <title>X is out. Is Y dead?</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Mon, 15 Jun 2020 10:50:23 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/x-is-it-is-y-dead-eoj</link>
      <guid>https://forem.com/jsn1nj4/x-is-it-is-y-dead-eoj</guid>
      <description>&lt;p&gt;No. 😛&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is meant to be a joke, so please don't think I'm making fun of you personally if you've asked this question. I've been guilty of doing this in the past too.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Coffee Tales ☕</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Fri, 29 May 2020 01:52:44 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/coffee-tales-4618</link>
      <guid>https://forem.com/jsn1nj4/coffee-tales-4618</guid>
      <description>&lt;p&gt;&lt;em&gt;You ever have one of those days that your need for coffee is what's making it difficult to get coffee?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My first cup of coffee I usually pour at home where I have my favorite creamer.&lt;/p&gt;

&lt;p&gt;Yesterday however, I completely forgot to start the coffee until it was time to leave... But no matter, there's coffee at work. 🤷‍♂️&lt;/p&gt;

&lt;p&gt;So I go to work, make a cup, and there's no more sugar... So I go looking for some upstairs instead and find some—a freaking baking sugar bag. So... I dunno, maybe I was too tired to think, so I walked 2 minutes up the street and got some caffeine. At least I knew how to do that lol. 🏃‍♂️&lt;/p&gt;

&lt;p&gt;Today I did get my first cup of coffee from home like normal in my tall travel mug—just the way I like it. 😋&lt;/p&gt;

&lt;p&gt;Later on, I decided to reuse that travel mug just to not create more dirty dishes. I prep the coffee machine, stick my coffee cup underneath and start it—and immediately race to get the lid off my cup that I realized I left on before the coffee starts pouring. 😬&lt;/p&gt;

&lt;p&gt;Of course those aren't the only times I've gotten in my own way trying to get my magic wakeup beverage, but it's what happened recently.&lt;/p&gt;




&lt;p&gt;Anyone else have some funny coffee-related stories to share?&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>humor</category>
      <category>coffee</category>
    </item>
    <item>
      <title>The Facepalming Dev 🤦‍♂️ #3</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Wed, 29 Apr 2020 01:11:10 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/the-facepalming-dev-2-47ap</link>
      <guid>https://forem.com/jsn1nj4/the-facepalming-dev-2-47ap</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;I'm primarily a WordPress user at my day job; I'm not sure whether this does or doesn't help my case since being WordPress-Primary means living in the Land of Plugins, but here goes....&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;As with all WordPress sites I work on, most tasks are centered around content and there's a page builder involved. But unlike most WP projects, this one does have at least a handful of actions and filters that I've added to the theme.&lt;/p&gt;

&lt;p&gt;On this project, there's a login page. Anyone can use it, but it's meant for users of a specific kind of role. This doesn't prevent it working if your user &lt;em&gt;doesn't&lt;/em&gt; have this role, but it's important.&lt;/p&gt;

&lt;p&gt;Once this type of user logs in, they then have access to a page full of resources that only this type of user is allowed access to (along with Editors and Admins, who do need to be able to edit content).&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's Episode
&lt;/h2&gt;

&lt;p&gt;The task I happened to be focused on was redirecting this particular kind of user if they were trying to access the login page while logged in. Sounds simple enough, right?&lt;/p&gt;

&lt;p&gt;So I went on a journey that involved searching through hooks, looking for similar solutions, dumping the &lt;code&gt;WP&lt;/code&gt; instance for crying out loud... This whole thing lasted about 2.5 hours.&lt;/p&gt;

&lt;p&gt;After much work, finally deciding to give up, and beginning to log my (lack of) progress in this area, something dawned on me...&lt;/p&gt;

&lt;p&gt;You see, I had created this login page the week before. And in the process of creating this login page, I had 1) installed a powerful redirect-building plugin that 2) included adding URL- and role-specific conditions and 3) had actually &lt;em&gt;created/tested&lt;/em&gt; this particular redirect... I ended up deactivating it for a reason that'll require too much explanation for this article...&lt;/p&gt;

&lt;p&gt;But yes, &lt;em&gt;the working solution already existed and I was the one who implemented it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I also had the equivalent of 6.5 cups of coffee today and that apparently didn't help me (or maybe it made things worse—who knows).&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;So... That's my facepalm-inducing story this time around. Anyone care to share their own stories below?&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus facepalms
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;I was rushing to publish this towards the end of writing and forgot to set &lt;code&gt;published: true&lt;/code&gt;. 🤦‍♂️&lt;/li&gt;
&lt;li&gt;The previous title of this one was "The Facepalming Dev 🤦‍♂️ #2", but I already posted #2 last year... So this is now #3. 🤦‍♂️&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope I'm finally adding bonus facepalms to this. I think I need to go to bed soon.&lt;/p&gt;

</description>
      <category>humor</category>
      <category>fail</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Favorite funny sites and projects</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Fri, 24 Apr 2020 21:12:26 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/favorite-funny-sites-and-projects-2o3m</link>
      <guid>https://forem.com/jsn1nj4/favorite-funny-sites-and-projects-2o3m</guid>
      <description>&lt;p&gt;Every now and then someone I know shares a link to a hilarious project that makes me literally LOL—and also wish I could think of something funny like it to put online.&lt;/p&gt;

&lt;p&gt;This time a friend shared a link to a website called &lt;a href="https://nouptime.com/"&gt;No Uptime Hosting&lt;/a&gt;. The longer I looked at it, the more I laughed. 🤣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2C1G-m1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/7nq562cb9zms31u74dfb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2C1G-m1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/7nq562cb9zms31u74dfb.jpg" alt="No Uptime Hosting screenshot" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There have been some other funny ones, like &lt;a href="https://github.com/RockstarLang/rockstar"&gt;Rockstar&lt;/a&gt; programming language (although I can't remember the others off the top of my head). Incidentally, this one was also shared in the same local Slack group the first one was shared in (at least, that's how I learned about it).&lt;/p&gt;

&lt;p&gt;What are you're favorite funny projects? 🙂&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>funny</category>
      <category>hosting</category>
    </item>
    <item>
      <title>BASH function for printing IP addresses for domains</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Wed, 15 Apr 2020 23:18:19 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/bash-script-for-printing-ip-address-of-domains-in-list-2eij</link>
      <guid>https://forem.com/jsn1nj4/bash-script-for-printing-ip-address-of-domains-in-list-2eij</guid>
      <description>&lt;p&gt;&lt;em&gt;Updated to include a function alternative to the original snippet further down.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;First of all, &lt;em&gt;dang, it's been a while...&lt;/em&gt; 😅&lt;/p&gt;

&lt;p&gt;Anyway, I was trying to find a one-off way to print a list of domains and each domain's main A record's IP address. After a little &lt;code&gt;dig&lt;/code&gt;ing 😉 this is what I ended up with initially.&lt;/p&gt;

&lt;h2&gt;
  
  
  Snippet
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nv"&gt;domains&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;example.com example.net example.org&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;domain &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short a &lt;span class="nv"&gt;$domain&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example.com: 93.184.216.34
example.net: 93.184.216.34
example.org: 93.184.216.34
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  BASH arrays
&lt;/h4&gt;

&lt;p&gt;I'm sorry to say I don't really know much on the subject; the handful of times I've needed them in scripting, I've had to look up syntax for creating them and then accessing. &lt;a href="https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays"&gt;This article&lt;/a&gt; seems to shed some light on the subject though, including how to iterate over array &lt;em&gt;indices&lt;/em&gt; instead of only array &lt;em&gt;elements&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;dig&lt;/code&gt; command
&lt;/h4&gt;

&lt;p&gt;As someone who comes from primarily being a Windows user (only due to work these days), I kept forgetting about this command. It lets you query any kind of DNS records for a domain.&lt;/p&gt;

&lt;p&gt;It's also normally pretty verbose too, but passing it the &lt;code&gt;+short&lt;/code&gt; option cuts down the output. &lt;code&gt;a&lt;/code&gt; also tells it to only query A records.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;tail&lt;/code&gt; command
&lt;/h4&gt;

&lt;p&gt;I don't use this one often, but I have used &lt;code&gt;head&lt;/code&gt; quite a bit to pull the first 10+ lines of a file if I was looking for some information stored at the top. This command pulls content from the bottom of a file (or output piped to it in this case).&lt;/p&gt;

&lt;h2&gt;
  
  
  Function alternative
&lt;/h2&gt;

&lt;p&gt;After digging a bit more and chatting with some local Linux users, I ended up rewriting the above snippet into a function that did the same thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;list_domain_ips&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;domain&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short a &lt;span class="nv"&gt;$domain&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
  &lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Example 1: passing a filename
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# function call&lt;/span&gt;
list_domain_ips example.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# example.txt contents
example.com
example.net
example.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example 2: passing &lt;code&gt;/dev/stdin&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;list_domain_ips /dev/stdin &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"example.com
example.net
example.org"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;while&lt;/code&gt; instead of &lt;code&gt;for...in&lt;/code&gt; loop
&lt;/h4&gt;

&lt;p&gt;This was simpler because the loop will only run as long as the &lt;code&gt;read&lt;/code&gt; command keeps supplying more input.&lt;/p&gt;

&lt;h4&gt;
  
  
  Last line of the loop: &lt;code&gt;done &amp;lt; $1&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This line is what's passing input to the loop. In this case, it's passing the first argument sent to the function, &lt;code&gt;$1&lt;/code&gt;. If the function had second, third, fourth arguments (ad infinitum), they would be &lt;code&gt;$2&lt;/code&gt;, &lt;code&gt;$3&lt;/code&gt;, and &lt;code&gt;$4&lt;/code&gt;, respectively. The first argument is also a filename containing a multi-line list of domains to check.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using &lt;code&gt;/dev/stdin&lt;/code&gt; as the argument
&lt;/h4&gt;

&lt;p&gt;This is useful if, even though this function expects a filename, you still want to pass a list directly yourself. This part of the solution I found on a &lt;a href="https://superuser.com/a/939797"&gt;superuser answer&lt;/a&gt;. Through testing, I found that a blank line will result in undesirable output (just something I wanted to mention for any BASH beginners on here). To prevent this, the opening and closing quotes do need to be in contact with lines that need to be used in the loop.&lt;/p&gt;

&lt;h5&gt;
  
  
  Sample output with blank lines
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: m.root-servers.net. # opening quote on its own line
example.com: 93.184.216.34
example.net: 93.184.216.34
example.org: 93.184.216.34
: m.root-servers.net. # closing quote on its own line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides that minor issue, the output is formatted exactly the same way.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Important note:&lt;/strong&gt; I was told by a local Linux wizard 🧙 by the name of Jās Eckard that &lt;code&gt;/dev/stdin&lt;/code&gt; isn't 100% &lt;em&gt;portable&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just be aware that using /dev/stdin is not portable across all Un*x.  I just read yesterday that it's on Linux and OSX (and even then, symlinks to different files), but not necessarily other Un*x.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I just wanted to include this note from him for reference, in case this doesn't work for a particular user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;So initially I was iterating over an array of domain names, but the better solution ended up being the function since it takes either a filename or a multi-line list sent through &lt;code&gt;/dev/stdin&lt;/code&gt; (and obviously since it's easier to store and call from CLI).&lt;/p&gt;

&lt;p&gt;The old &lt;code&gt;echo&lt;/code&gt; line using a subshell to run the &lt;code&gt;dig&lt;/code&gt; command and piping the output to &lt;code&gt;tail&lt;/code&gt;, and prefixing that output with the domain name itself for reference carried over without needing to be changed.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and enjoy! 🐧 💻&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.compciv.org/topics/bash/loops/"&gt;For and Read-While Loops in Bash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays"&gt;You don't know Bash: An introduction to Bash arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://superuser.com/a/939797"&gt;superuser answer: Pass text to program expecting a file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bash</category>
      <category>dns</category>
      <category>linux</category>
      <category>quickndirty</category>
    </item>
    <item>
      <title>Design Patterns Discussion</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Mon, 22 Jul 2019 01:38:25 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/design-patterns-discussion-1b6k</link>
      <guid>https://forem.com/jsn1nj4/design-patterns-discussion-1b6k</guid>
      <description>&lt;h1&gt;
  
  
  Preface
&lt;/h1&gt;

&lt;p&gt;It's been a while since I've written a post, but I figured I'd ask about something I don't remember learning in college (and also because I've only encountered it while learning Laravel).&lt;/p&gt;

&lt;p&gt;Laravel implements a flavor of a design pattern called MVC (at least, its own flavor of the one common in the PHP world from my basic understanding). I had sort of been following this early on learning Laravel. But when asking for help with part of it (just for the sake of sticking to the pattern), it was mentioned to me that what's called "MVC" typically in PHP projects isn't &lt;em&gt;really&lt;/em&gt; MVC.&lt;/p&gt;

&lt;p&gt;At this point, I was recommended to learn the Action-Domain-Responder pattern instead and pointed to &lt;a href="https://github.com/pmjones/adr"&gt;this reading material&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  To the point...
&lt;/h2&gt;

&lt;p&gt;I'm planning to look into ADR again this week and wanted to ask others for input.&lt;/p&gt;

&lt;p&gt;So what design patterns are you familiar with, and which do you prefer?&lt;/p&gt;

&lt;h3&gt;
  
  
  P.S. (not to be confused with PowerShell)
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/pmjones/adr"&gt;reading material&lt;/a&gt; I mentioned earlier links to some MVC history, including how today's "MVC" came about. This definitely was interesting to read for a design patterns newbie like me (that and I just like learning about software development in general).&lt;/p&gt;




&lt;p&gt;Discuss away! &lt;/p&gt;

</description>
      <category>patterns</category>
      <category>mvc</category>
      <category>adr</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Facepalming Dev 🤦‍♂️ #2</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Sat, 12 Jan 2019 22:14:25 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/the-facepalming-dev--2-1h9j</link>
      <guid>https://forem.com/jsn1nj4/the-facepalming-dev--2-1h9j</guid>
      <description>&lt;h1&gt;
  
  
  Preface 📝
&lt;/h1&gt;

&lt;p&gt;Don't worry, there won't be a preface for all of these, but I felt it was somewhat necessary for this one.&lt;/p&gt;

&lt;p&gt;I'm primarily a Windows user due to my day job, and I had installed WAMP Server so I could have PHP, Apache and MySQL installed all at once pretty easily. I just didn't realize the "automatic install" feature was for first-time WAMP Server installs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Down the rabbit hole 🐇
&lt;/h1&gt;

&lt;p&gt;So, I originally started with PHP 5.5.x and MySQL 5.5.x. Or maybe MySQL was at 5.6.x. I can't remember. But I hadn't upgraded them in a while. I went through the steps I found to manually install PHP 7.2.6 and MySQL 5.7.21. All was well again...for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some time later... 🕰
&lt;/h2&gt;

&lt;p&gt;After a while, WAMP Server could no longer start the MySQL process. I tried switching which MySQL version WAMP Server was using as well as researching the issue. Apache was starting and there were no PHP issues. MySQL just wouldn't start.&lt;/p&gt;

&lt;p&gt;After much frustration, I ended up uninstalling WAMP Server, which also resulted in uninstalling Apache, most of what MySQL versions I had installed, and most of what was in each PHP version. I knew doing this would break this setup, but I really didn't care at this point. Since I had to manually set up any new versions of each of these components anyway, WAMP Server was now virtually useless to me, especially if it would come to one of these components breaking just because WAMP Server wasn't able to start them up properly (minus PHP, which doesn't have a service that WAMP Server needs to start).&lt;/p&gt;

&lt;h2&gt;
  
  
  The unexpected 👀
&lt;/h2&gt;

&lt;p&gt;With WAMP Server out of the way, I installed PHP 7.3.0, set up the php.ini file, and put it in my path. I was ready to go!&lt;/p&gt;

&lt;p&gt;And then I found out I wasn't...&lt;/p&gt;

&lt;p&gt;When I tried to start up a Laravel project I had been working on for a while (one that doesn't use MySQL yet), it kept complaining about not being able to use PHP's OpenSSL-related functions, despite that the extension was enabled in the php.ini.&lt;/p&gt;

&lt;p&gt;Then I scrolled further down the error and noticed it was still using PHP 7.2.6.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Something important:&lt;/strong&gt; I had PHP 7.3.0 in my PATH &lt;em&gt;ahead of&lt;/em&gt; the old 7.2.6 entry that was in &lt;code&gt;c:\wamp\bin\php&lt;/code&gt;. That old version wasn't 100% gone, but &lt;em&gt;most of it&lt;/em&gt; was removed on install (including the extensions). So it could partially run if a project was looking for it, but not completely.&lt;/p&gt;

&lt;p&gt;This project was still trying to use 7.2.6. It didn't make sense. No matter how many times I restarted the project, it wouldn't pick up the newer PHP version.&lt;/p&gt;

&lt;p&gt;So I gave up for a little while.&lt;/p&gt;

&lt;p&gt;Today, I decided to tackle this, but maybe after reinstalling PHP 7.2.6. It's probably best I stick with the same version between machines anyway (my Linux install uses this version currently).&lt;/p&gt;

&lt;p&gt;I was scrolling through the php.ini files for both 7.3.0 and 7.2.6 to see if there was something missing. I then came across this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; When enabled, the ENV, REQUEST and SERVER variables are created when they're
; first used (Just In Time) instead of when the script starts. If these
; variables are not used within a script, having this directive on will result
; in a performance gain. The PHP directive register_argc_argv must be disabled
; for this directive to have any affect.
; http://php.net/auto-globals-jit
&lt;/span&gt;&lt;span class="py"&gt;auto_globals_jit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;On&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;😶...&lt;/p&gt;

&lt;p&gt;I froze for a minute. Then I decided to try something that hadn't crossed my mind before: I opened my terminal, ran &lt;code&gt;php artisan tinker&lt;/code&gt;, and checked the PATH from there.&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="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&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="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PATH'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$path&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&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;And it matched my new path settings!&lt;/p&gt;

&lt;p&gt;I started up my project, opened my browser, and the page loaded. 😑&lt;/p&gt;

&lt;p&gt;I realized something else: the few days I tried to get my project to start, &lt;strong&gt;I had put my laptop into hibernation&lt;/strong&gt;. It was &lt;em&gt;technically&lt;/em&gt; "shut down", but the state was reloaded as it was when hibernated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned 📒
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Comb new configs a bit more, in case there are important extra details&lt;/li&gt;
&lt;li&gt;Find a way to check your PATH &lt;em&gt;as your project sees it&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;If the PATH or other recent settings haven't taken effect yet for some reason, it doesn't hurt to restart&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; if you use &lt;a href="https://github.com/typicode/hotel"&gt;Hotel&lt;/a&gt; for managing project processes on Windows, you may not know right away, but Hotel also stores a copy of the PATH -- and a copy is stored &lt;em&gt;in each project's config, when the project is added to Hotel&lt;/em&gt;. That's another thing I discovered recently after ripping out WAMP Server and manually installing PHP 7.3.0.&lt;/p&gt;

&lt;p&gt;Hope this was a fun read and that someone else can glean from this in the future. Enjoy the rest of your weekend!&lt;/p&gt;

</description>
      <category>facepalm</category>
      <category>humor</category>
      <category>php</category>
    </item>
    <item>
      <title>Why do you use your language/stack?</title>
      <dc:creator>Elliot Derhay</dc:creator>
      <pubDate>Fri, 04 Jan 2019 03:31:46 +0000</pubDate>
      <link>https://forem.com/jsn1nj4/why-do-you-use-your-languagestack-1g60</link>
      <guid>https://forem.com/jsn1nj4/why-do-you-use-your-languagestack-1g60</guid>
      <description>&lt;h1&gt;
  
  
  Where I am currently 🗺
&lt;/h1&gt;

&lt;p&gt;When it comes to web development, I can't say I'm intermediate. I'm not that new to the industry either. But when it comes to what I should use, I sometimes flip between different things.&lt;/p&gt;

&lt;p&gt;Currently, I'm a Laravel + Vue user. I started with PHP, tried Meteor🌠 due to a fantasy of using a single language on both front- and back-end, and ended up back with PHP on Laravel (but with Vue added in). Honestly, I may yet end up back in Node, depending on what I find to use it with.&lt;/p&gt;

&lt;p&gt;But I'm wondering what stacks others use, and why they tend to stick with them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Preempting a flame war 🔥
&lt;/h1&gt;

&lt;p&gt;I intentionally am &lt;em&gt;not&lt;/em&gt; asking why you &lt;em&gt;wouldn't&lt;/em&gt; use a different language or stack. I've come across plenty of arguments (that I tend to shy away from) over PHP vs. Rails vs. .NET w/ C#, and dynamic vs. strongly-typed languages. I'm of the belief that they not only all have their place, but that different languages and paradigms click better with different people. Personality and mentality always play a part in these kinds of decisions.&lt;/p&gt;

&lt;p&gt;Regardless, I'm still curious about what draws others to their toolsets, and what types of projects they tend to work on with them.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
