<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Barnesian</title>
	<atom:link href="https://barnesian.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://barnesian.com</link>
	<description>Software Development and Audio Engineering</description>
	<lastBuildDate>Fri, 19 Jun 2020 00:23:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.8.2</generator>
	<item>
		<title>Getting The Root Path of an Electron Application</title>
		<link>https://barnesian.com/getting-the-root-path-of-an-electron-application/</link>
					<comments>https://barnesian.com/getting-the-root-path-of-an-electron-application/#comments</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Fri, 19 Jun 2020 00:23:01 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[electron]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://barnesian.com/?p=1206</guid>

					<description><![CDATA[If you wound up here somehow, you are no doubt confused about how to get the root directory of an Electron app. It's surprisingly complicated depending on the environmental setup. The path works a little differently in development mode than it does in a fully packaged application in an asar archive. If you're having trouble, make sure you test both scenarios. ]]></description>
										<content:encoded><![CDATA[
<p>If you wound up here somehow, you are no doubt confused about how to get the root directory of an Electron app. It&#8217;s surprisingly complicated depending on the environmental setup. The path works a little differently in development mode than it does in a fully packaged application in an <a href="https://github.com/electron/asar">asar archive</a>. If you&#8217;re having trouble, make sure you test both scenarios. </p>



<p>There&#8217;s an <a href="https://www.electronjs.org/docs/api/app#appgetapppath">API that was added at some point that does exactly this</a>. Unfortunately, that won&#8217;t work in the renderer process. If you&#8217;re in the background process, then that should work just fine. Also worth noting, if you&#8217;re doing file access and dealing with paths, you probably ** should ** be in the background process. Take a minute to think about that and whether or not you should refactor to make that a reality. There&#8217;s also another way to get at this, as suggested by <a href="https://stackoverflow.com/questions/37213696/how-can-i-get-the-path-that-the-application-is-running-with-typescript">this StackOverflow post</a>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
require('electron').remote.app.getAppPath();
</pre></div>


<p>For whatever reason, perhaps an outdated Electron version, that did not work when I tried it. There&#8217;s a surprisingly simple solution to this. If you&#8217;re using a bundler, this may be a little different.</p>



<p>Here&#8217;s the trick that works no matter what. Put a file at the root of the application, called <code>rootPath.js</code> and return <code>__dirname</code>. <a href="https://nodejs.org/docs/latest/api/globals.html#globals_dirname">__dirname in Node</a> is the directory of the currently executing file. Since it is at the root, this will always give you the root path.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
export default function rootPath() {
  return __dirname;
} 
</pre></div>


<p>Import it however you usually import things, and call it and you&#8217;ll get the root path.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
import rootPath from 'rootPath';
import path from 'path';
//or
const rootPath = require('rootPath');
const path = require('path');

const somePath = path.resolve(`${rootPath()}/some/path/to/something`);

</pre></div>


<p>That&#8217;s it! After some hand wringing, that works all the time, everywhere, no matter what. Undoubtedly, it won&#8217;t work for someone, and we&#8217;ll hear from them in the comments <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f606.png" alt="😆" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/getting-the-root-path-of-an-electron-application/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Deep Merging JavaScript Objects</title>
		<link>https://barnesian.com/deep-merging-javascript-objects/</link>
					<comments>https://barnesian.com/deep-merging-javascript-objects/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Wed, 25 Mar 2020 23:30:36 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://barnesian.com/?p=1181</guid>

					<description><![CDATA[Deep merging objects in JavaScript is a bit tricky. Here&#8217;s one solution; there are many many others. While this was fun to write, you&#8217;ll probably want to go use the merge function in lodash instead. None the less here&#8217;s some code golf]]></description>
										<content:encoded><![CDATA[
<p>Deep merging objects in JavaScript is a bit tricky. Here&#8217;s one solution; there are many many others. While this was fun to write, you&#8217;ll probably want to go <a href="https://lodash.com/docs#merge">use the merge function in lodash instead</a>. None the less here&#8217;s some code golf</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
function merge(...sources) {
  return sources.reduce((target, source) =&gt; {  // enumerate the sources
    return Object.entries(source).reduce((result, &#91;key, value]) =&gt; {  // enumerate the properties
      if(Array.isArray(value)) {
        if(Array.isArray(result&#91;key])) {
          result&#91;key] = result&#91;key].concat(value); // got two arrays, merge them
        } else {
          result&#91;key] = value;  // clobber it, either undefined or not an array
        }
      } else if(value === Object(value)) {
        if(result&#91;key] === Object(result&#91;key])) {
          result&#91;key] = merge(result&#91;key], value); // two objects, recurse and merge them
        } else {
          result&#91;key] = merge(value); // recurse and clobber it, either undefined or not an object
        }
      } else {
        result&#91;key] = value;  // must be a primitive, clobber it
      }
      return result;
    }, target);
  }, {});
}
</pre></div>]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/deep-merging-javascript-objects/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fastmail Settings for WP Mail SMTP</title>
		<link>https://barnesian.com/fastmail-settings-for-wp-mail-smtp/</link>
					<comments>https://barnesian.com/fastmail-settings-for-wp-mail-smtp/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Wed, 25 Mar 2020 23:20:02 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Wordpress]]></category>
		<guid isPermaLink="false">https://barnesian.com/?p=1184</guid>

					<description><![CDATA[After having migrated my mail provider from Outlook.com to Fastmail I needed to get the contact form up and running for WordPress.]]></description>
										<content:encoded><![CDATA[
<p>After having migrated my mail provider from <a href="https://outlook.com/">Outlook.com</a> to <a href="https://www.fastmail.com/">Fastmail</a> I needed to get the contact form up and running for <a href="https://wordpress.org">WordPress</a>. The Fastmail settings are <a href="https://www.fastmail.com/help/clients/defineimap.html">plainly available and located over here</a>.</p>



<p class="panel callout radius">SMTP Host: smtp.fastmail.com<br>Encryption: SSL<br>SMTP Port: 465<br>Auto TLS: On<br>Authentication: On<br>SMTP Username: your primary email address<br>SMTP Password: &lt;your password, use at your own risk, it&#8217;s better to use WordPress variables for this&gt;</p>



<p>While your primary password may work, it&#8217;s better to create a unique password per application using Fastmail. This password can be revoked easily if something goes wrong. In Fastmail, under <code>Settings -&gt; Password &amp; Security</code> you&#8217;ll see there is a section called App Passwords. Generate a new password here and put these two variables into <code>wp-config.php</code></p>



<p class="panel callout radius">define(&#8216;WPMS_ON&#8217;, true);<br>define(&#8216;WPMS_SMTP_PASS&#8217;, &#8216;your per application password&#8217;);</p>



<p>Use the “Send a Test Email” section to make sure everything works.</p>



<p>If you have a firewall setup (and you should), you’ll have to let  that traffic out as well. If you are using Linux and iptables here are the iptables rules that allow that traffic to&nbsp;get out while still  blocking new incoming connections on port 465. Note these must be run with <code>sudo</code></p>



<p class="panel callout radius"> iptables -A OUTPUT -p tcp –sport 465 -m state –state NEW,ESTABLISHED -j ACCEPT<br> iptables -A OUTPUT -p tcp –dport 465 -m state –state NEW,ESTABLISHED -j ACCEPT<br> iptables -A INPUT -p tcp –sport 465 -m state –state RELATED,ESTABLISHED -j ACCEPT </p>



<p>And now you’ve got WordPress using Fastmail for all of the notifications. Enjoy</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/fastmail-settings-for-wp-mail-smtp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Perfect Footers</title>
		<link>https://barnesian.com/perfect-footers/</link>
					<comments>https://barnesian.com/perfect-footers/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Thu, 16 Feb 2017 04:19:58 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=1067</guid>

					<description><![CDATA[Styling footers proves to be a bit tricky. On a site where there's a lot of content, this is not an issue. However, if you want to have the page be full height and scroll when the content overflows, there is some subtlety to styling the footer. It's pretty easy to accidentally have the footer float in the middle of the page when the content overflows and the page scrolls. It's also pretty easy to have the content hide underneath the footer. Head past the break for the details.]]></description>
										<content:encoded><![CDATA[<p>Styling footers proves to be a bit tricky. On a site where there&#8217;s a lot of content, this is not an issue. However, if you want to have the page be full height and scroll when the content overflows, there is some subtlety to styling the footer. It&#8217;s pretty easy to accidentally have the footer float in the middle of the page when the content overflows and the page scrolls. It&#8217;s also pretty easy to have the content hide underneath the footer. I am hardly the first person to write about this; this post was inspired by and slightly modified from <a href="http://matthewjamestaylor.com/blog/keeping-footers-at-the-bottom-of-the-page">this blog post</a>.</p>
<p>Here&#8217;s how to deal with that. First of all, if you don&#8217;t have a normalize and reset, you should probably do that. In the example I&#8217;ve included a quick reset of body and all of the header elements. Without that reset this won&#8217;t quite work like you might expect. The kernel of getting the page to be full height while allowing it to scroll is setting <code>html</code> to <code>height: 100%</code> and setting <code>body</code> to <code>min-height: 100%</code> and <code>position: relative</code>. With those styles, it allows the short pages to be full height, without scroll bars, and allows longer pages to scroll and keep the footer at the bottom. Finally, another important note: the main content container needs to have some padding so its content doesn&#8217;t hide underneath the footer.</p>
<p>A demo is worth many words; here&#8217;s a CodePen:</p>
<p class="codepen" data-height="400" data-theme-id="0" data-slug-hash="egoOoX" data-default-tab="result" data-user="chrishalebarnes" data-embed-version="2" data-pen-title="Perfect Footer">See the Pen <a href="http://codepen.io/chrishalebarnes/pen/egoOoX/">Perfect Footer</a> by Chris (<a href="http://codepen.io/chrishalebarnes">@chrishalebarnes</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<p><script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script></p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/perfect-footers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Quick Tip: Download Offline Documentation with wget</title>
		<link>https://barnesian.com/download-offline-documentation-with-wget/</link>
					<comments>https://barnesian.com/download-offline-documentation-with-wget/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Sat, 17 Dec 2016 19:11:05 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=1045</guid>

					<description><![CDATA[Here's a quick way to download developer documentation for any language or framework that has a public website. Maybe you're about to get on a plane or train that doesn't have WiFi and you want to use that dead time to actually get some development work done. The key here is two switches in the wget command, -r  and -k.]]></description>
										<content:encoded><![CDATA[<p>Here’s a quick way to download developer documentation for any language or framework that has a public website. Maybe you’re about to get on a plane or train that doesn’t have WiFi and you want to use that dead time to actually get some development work done. The key here is two switches in the <code>wget</code> command,  <code>–r</code>  and <code>–k</code>.</p>
<p>Given any URL you can download all pages recursively and have wget convert the links to local links after the download is complete. You could, for example, run this with the <a href="http://guides.rubyonrails.org/" target="_blank" rel="noopener">Ruby on Rails Guides</a>. There is a wait included, which you can remove, but be aware that it might not be nice to overload some poor web server.</p>
<p>Here’s the command:</p>
<pre class="brush: bash; title: ; notranslate">wget —mirror —convert–links —adjust–extension —wait=1 &lt;url&gt;</pre>
<p>or the short form:</p>
<pre class="brush: bash; title: ; notranslate">wget –mkE –w 1 &lt;url&gt;</pre>
<p>There are a lot more options which are all <a href="https://www.gnu.org/software/wget/manual/wget.html" target="_blank" rel="noopener">documented here</a>. However, here are the options used here.</p>
<blockquote><p>-k or –convert-links</p></blockquote>
<p>Converts links on the downloaded pages into local filesystem links 1ctvbeq.</p>
<blockquote><p>-E or –adjust-extension</p></blockquote>
<p>Saves files according their content type; CSS will be saved as a .css file for example</p>
<blockquote><p>–mirror or -m</p></blockquote>
<p>Flips on a bunch of options for exactly this kind of purpose. It is equivalent to<br />
<span id="crayon-58a04789163d1621895876" class="crayon-syntax crayon-syntax-inline crayon-theme-sublime-text crayon-theme-sublime-text-inline crayon-font-consolas" style="font-size: 14px !important; line-height: 15px !important;"><span class="crayon-pre crayon-code" style="font-size: 14px !important; line-height: 15px !important;"><span class="crayon-o">–</span><span class="crayon-v">r</span> <span class="crayon-o">–</span><span class="crayon-v">N</span> <span class="crayon-o">–</span><span class="crayon-i">l</span> <span class="crayon-v">inf</span> <span class="crayon-o">—</span><span class="crayon-v">no</span><span class="crayon-o">–</span><span class="crayon-v">remove</span><span class="crayon-o">–</span><span class="crayon-v">listing</span></span></span></p>
<blockquote><p>-r –recursive</p></blockquote>
<p>Downloads all webpages recursively. All links will be followed and those pages will be downloaded as well.</p>
<blockquote><p>-l inf</p></blockquote>
<p>Sets the recursion level to infinite, so it will follow all links. This could be made smaller if you don’t want it to follow that many links.</p>
<blockquote><p>-N or –timestamping</p></blockquote>
<p>Turns on timestamping so that if you fetch the pages again it will not download the file unless the timestamp has changed.</p>
<blockquote><p>–no-remove-listing</p></blockquote>
<p>Not entirely sure about this one, but it has something to do with FTP files. See the <a href="https://www.gnu.org/software/wget/manual/wget.html" target="_blank" rel="noopener">documentation for it here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/download-offline-documentation-with-wget/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix Dell XPS 13 Touchscreen and Suspend Issues In Fedora</title>
		<link>https://barnesian.com/how-to-fix-dell-xps-13-touchscreen/</link>
					<comments>https://barnesian.com/how-to-fix-dell-xps-13-touchscreen/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Fri, 11 Nov 2016 22:58:44 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Dell]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Grub]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[XPS13]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=1037</guid>

					<description><![CDATA[After updating Fedora on my Dell XPS 13 Developer Edition, the suspend/resume stopped functioning. After resuming from being suspended, the laptop would immediately reboot. There had also been a long running issue where the touchscreen would not work after resuming from being suspended. The latter did not bother me that much, since I don't feel the need to use the touchscreen all that often. The former, however, was going to be a huge issue. After a lot of digging and trying out all kinds of things, I stumbled upon something that finally worked. Head past the break for the fix.]]></description>
										<content:encoded><![CDATA[<p>After updating <a href="https://getfedora.org/">Fedora</a> on my <a href="http://www.dell.com/us/business/p/xps-13-linux/pd">Dell XPS 13 Developer Edition</a>, the suspend/resume stopped functioning. After resuming from being suspended, the laptop would immediately reboot. There had also been a long running issue where the touchscreen would not work after resuming from being suspended. The latter did not bother me that much, since I don&#8217;t feel the need to use the touchscreen all that often. The former, however, was going to be a huge issue. After a lot of digging and trying out all kinds of things, I stumbled upon something that finally worked. As it turns out, this also seems to have fixed the touchscreen issue as well. I&#8217;m still not entirely sure if the update fixed the touchscreen or if this kernel parameter fixed the touchscreen. I&#8217;m also still not entirely sure what this parameter actually does or if there are some drawbacks to using it. Anyway, I wanted to write this down here in case it helped someone else who has the same issue.</p>
<p>The fix ended up being adding a parameter to the Linux kernel via Grub. That parameter is <code>acpi_sleep=nonvs</code></p>
<p>Edit <code>/etc/default/grub</code>  using whatever text editor you prefer and find the line that looks like this <code>GRUB_CMDLINE_LINUX="rhgb quiet"</code>. And you&#8217;ll need <code>sudo</code><br />
Add <code>acpi_sleep=nonvs</code>  to the end of that string so it looks something like this</p>
<pre class="brush: bash; title: ; notranslate">GRUB_CMDLINE_LINUX=&quot;&lt;a bunch of other parameters&gt;; rhgb quiet acpi_sleep=nonvs pcie_aspm=force acpi_osi=Linux&quot;</pre>
<p>Now you have to update Grub. In Fedora there is no <a href="http://manpages.ubuntu.com/manpages/trusty/man8/update-grub.8.html">update-grub command</a> so you have to update it like this and then reboot. You&#8217;ll also need <code>sudo</code> to run this command.</p>
<pre class="brush: bash; title: ; notranslate">grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg</pre>
<p>According to the <a href="https://github.com/torvalds/linux/blob/master/Documentation/kernel-parameters.txt">kernel parameters documentation</a>, this parameter &#8220;prevents the kernel from saving/restoring the ACPI NVS memory during suspend/hibernation and resume.&#8221;</p>
<p>Thanks to <a href="http://askubuntu.com/questions/24048/suspend-fails-reboot-on-resume-and-no-hibernate-option">this helpful thread</a> and this other <a href="https://ask.fedoraproject.org/en/question/80362/how-do-i-update-grub-in-fedora-23/">helpful thread over here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/how-to-fix-dell-xps-13-touchscreen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Quick Tip: Routes for a Non-Resourceful Rails Controller</title>
		<link>https://barnesian.com/quick-tip-routes-for-a-non-resourceful-rails-controller/</link>
					<comments>https://barnesian.com/quick-tip-routes-for-a-non-resourceful-rails-controller/#comments</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Fri, 19 Aug 2016 02:50:40 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=1031</guid>

					<description><![CDATA[Let's say you have a few routes that are all related, but don't really map to the usual resources. For example, a login/logout controller named SessionsController  doesn't really fit the usual resourceful route model. Head past the break for all the details.]]></description>
										<content:encoded><![CDATA[<p>Let&#8217;s say you have a few routes that are all related, but don&#8217;t really map to the usual resources. For example, a login/logout controller named <span class="lang:default decode:true crayon-inline ">SessionsController</span>  doesn&#8217;t really fit the usual resourceful route model. One could use the usual routes HTTP verb syntax like this</p>
<pre class="brush: ruby; title: ; notranslate">
Rails.application.routes.draw do
  #...
  get  'login',  to: 'sessions#index'
  post 'login',  to: 'sessions#login'
  post 'logout', to: 'sessions#logout'
end
</pre>
<p>However, there&#8217;s a nifty little helper that&#8217;s not in the <a href="http://guides.rubyonrails.org/routing.html">routing guide</a> but is in the <a href="http://api.rubyonrails.org/classes/ActionDispatch/Routing.html">API docs</a> called <span class="lang:default decode:true crayon-inline ">controller</span> which feels a bit cleaner.</p>
<pre class="brush: ruby; title: ; notranslate">
Rails.application.routes.draw do
  #...
  controller :sessions do
    get  :login,  action: :index
    post :login,  action: :login
    post :logout, action: :logout
  end
end
</pre>
<p>After running <code>rake routes</code>  or <code>rails routes</code> to see what routes we&#8217;ve got, we&#8217;ll see three routes.</p>
<pre class="brush: plain; title: ; notranslate">
login  GET  /login(.:format)  sessions#index
       POST /login(.:format)  sessions#login
logout POST /logout(.:format) sessions#logout
</pre>
<p>If there&#8217;s an even better way, let me know in the comments!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/quick-tip-routes-for-a-non-resourceful-rails-controller/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SASS Antipattern: The Selector Bomb</title>
		<link>https://barnesian.com/sass-antipattern-selector-bomb/</link>
					<comments>https://barnesian.com/sass-antipattern-selector-bomb/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Fri, 15 Jan 2016 02:48:15 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[SASS]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=934</guid>

					<description><![CDATA[SASS is a really powerful tool, which sometimes means that one has to be careful. It can generate all kinds of insane CSS that is hard for debugging and hard for the browser to parse and apply. Now and then, you have to take a step back and ask yourself if you really need to use SASS for the task at hand. I'd like to attempt to coin a new term for an anti-pattern that I, and many others, have stumbled upon.]]></description>
										<content:encoded><![CDATA[<p>SASS is a really powerful tool, which sometimes means that one has to be careful. It can generate all kinds of insane CSS that is hard for debugging and hard for the browser to parse and apply. Now and then, you have to take a step back and ask yourself if you really need to use SASS for the task at hand. I&#8217;d like to attempt to coin a new term for an anti-pattern that I, and many others, have stumbled upon.</p>
<blockquote>
<h4>The Selector Bomb</h4>
<p>A gigantic selector that is hard to debug and hard for the browser to parse and apply, generated by SASS when using <code>@extend</code>  as a utility that spans across many selectors.</p></blockquote>
<h4 style="text-align: left;">An Example</h4>
<p>There is a lot of jargon in the above statement. Let&#8217;s break it down with a clear example with three pages. Keep in mind that three pages is not really a problem, but when you scale this up to a huge amount of pages, it really becomes a problem. This especially applies to utility classes &#8211; something like a clearfix class or a text-align class. Each page has a panel with a different background color. This is a fairly common pattern, especially if you&#8217;re concatenating all of your CSS into a single file. You want to share the common styles and yet still change the background color. You decide to use a <a href="http://thesassway.com/intermediate/understanding-placeholder-selectors" target="_blank">SASS placeholder</a> and use <code>@extend</code>  to bring in the common styles. Let&#8217;s have a look at the markup and SASS for each page.</p>
<h4 style="text-align: left;">First Page</h4>
<pre class="brush: xml; title: ; notranslate">
  &lt;div class=&quot;panel&quot;&gt;
    &lt;h2&gt;Sass&lt;/h2&gt;
    &lt;p&gt;CSS with superpowers&lt;/p&gt;
  &lt;div&gt;
</pre>
<pre class="brush: css; title: ; notranslate">
.page.sass {
  .panel {
    @extend %panel;
    background-color: #e1faea;
  }
}
</pre>
<h4 style="text-align: left;">Second Page</h4>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;page stylus&quot;&gt;
  &lt;div class=&quot;panel css-library&quot;&gt;
    &lt;h2&gt;Stylus&lt;/h2&gt;
    &lt;p&gt;Expressive, dynamic, robust CSS&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: css; title: ; notranslate">
.page.stylus {
  .panel {
    @extend %panel;
    background-color: #def0fc;
  }
}
</pre>
<h4 style="text-align: left;">Third Page</h4>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;page less&quot;&gt;
  &lt;div class=&quot;panel&quot;&gt;
    &lt;h2&gt;Less&lt;/h2&gt;
    &lt;p&gt;Leaner CSS&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: css; title: ; notranslate">
.page.less {
  .panel {
    @extend %panel;
    background-color: #ebebeb;
  }
}
</pre>
<p>And finally, the common styles are in the placeholder, which is extended in each panel.</p>
<pre class="brush: css; title: ; notranslate">
%panel {
  padding: 1em;
  margin: 1em;
  width: 300px;
}
</pre>
<p>This will render these three components on each of the three different pages.</p>
<p><a href="https://www.barnesian.com/wp-content/uploads/2016/01/sass-panels.png" rel="attachment wp-att-970"><img loading="lazy" class="alignnone size-full wp-image-970" src="https://www.barnesian.com/wp-content/uploads/2016/01/sass-panels.png" alt="sass-panels" width="1034" height="158" /></a></p>
<p>Unfortunately that will compile to this. See how it merges all of the selectors into one for the common styles? This is the <em><strong>selector bomb</strong></em>. Every time you add a page that has <code>@extend %panel</code> , it will add one more selector here. Do that across enough pages and you can get a huge selector that is hard to debug and hard for the browser to parse and apply.</p>
<pre class="brush: css; title: ; notranslate">
.page.sass .panel, .page.stylus .panel, .page.less .panel {
  padding: 1em;
  margin: 1em;
  width: 300px;
}

.page.sass .panel {
  background-color: #e1faea;
}

.page.stylus .panel {
  background-color: #def0fc;
}

.page.less .panel {
  background-color: #ebebeb;
}
</pre>
<h4>Solutions</h4>
<p>There are a couple ways to get around this. Depending upon the context of what you&#8217;re doing, one of these (or even something else) may make sense. First, a mixin will alleviate the pain, since a mixin will actually copy the CSS everywhere it is included. This could cause more pain, since it makes the file size a bit larger. However, worrying about the size of a CSS file is very likely to be overthinking the problem.</p>
<pre class="brush: css; title: ; notranslate">
@mixin panel() {
  padding: 1em;
  margin: 1em;
  width: 300px;
}

.page.sass {
  .panel {
    @include panel();
    background-color: #e1faea;
  }
}

.page.stylus {
  .panel {
    @include panel();
    background-color: #def0fc;
  }
}

.page.less {
  .panel {
    @include panel();
    background-color: #ebebeb;
  }
}
</pre>
<p>Secondly, CSS is called Cascading Stylesheets for a reason. Depending upon the context, it&#8217;s probably better to not even bother with SASS features. Sometimes SASS makes you forget about some of the reusability features that plain old HTML and CSS have in the first place. Just add a class for scope and style it globally. I know, I know, global is bad from what you&#8217;ve heard, but often it makes sense.  Here is what that might look like.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;page sass&quot;&gt;
  &lt;div class=&quot;panel css-library&quot;&gt;
    &lt;h2&gt;Sass&lt;/h2&gt;
    &lt;p&gt;CSS with superpowers&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;page stylus&quot;&gt;
  &lt;div class=&quot;panel css-library&quot;&gt;
    &lt;h2&gt;Stylus&lt;/h2&gt;
    &lt;p&gt;Expressive, dynamic, robust CSS&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;page less&quot;&gt;
  &lt;div class=&quot;panel css-library&quot;&gt;
    &lt;h2&gt;Less&lt;/h2&gt;
    &lt;p&gt;Leaner CSS&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: css; title: ; notranslate">
.page .panel.css-library {
  padding: 1em;
  margin: 1em;
  width: 300px;
}

.page.sass {
  .panel {
    background-color: #e1faea;
  }
}

.page.stylus {
  .panel {
    background-color: #def0fc;
  }
}

.page.less {
  .panel {
    background-color: #ebebeb;
  }
}
</pre>
<p>Don&#8217;t avoid <code>@extend</code> and placeholders out of principle, but do be very careful, particularly if <code>@extend</code> is used for some kind of common utility. It will not scale out to many, many pages. Know what you&#8217;re using, and know what CSS it&#8217;s generating.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/sass-antipattern-selector-bomb/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Multiple Background Images in CSS</title>
		<link>https://barnesian.com/multiple-background-image-in-css/</link>
					<comments>https://barnesian.com/multiple-background-image-in-css/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Sat, 19 Dec 2015 21:19:45 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[HTML]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=910</guid>

					<description><![CDATA[Nearly every software developer who works with front-end code has probably used the CSS property background-image. What some might not know is that background-image can take many images and set how those images are positioned. This could be particularly useful if you don't have full control over the HTML that is being generated for whatever reason. You could also have multiple elements and use an nth-of-type selector to achieve the same effect. Click through for the code and a JSFiddle demo.]]></description>
										<content:encoded><![CDATA[<p>Nearly every software developer who works with front-end code has probably used the CSS property <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-image" target="_blank">background-image</a>. What some might not know is that background-image can take many images and set how those images are positioned. This could be particularly useful if you don&#8217;t have full control over the HTML that is being generated for whatever reason. You could also have multiple elements and use an <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/%3Anth-of-type" target="_blank">nth-of-type</a> selector to achieve the same effect. Here is a quick demo of how you can use the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-image" target="_blank">background-image</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-size" target="_blank">background-size</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-position" target="_blank">background-position</a> in concert to apply three images to a single div on top of a span of text.</p>
<p>HTML:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;box&quot;&gt;
  &lt;div class=&quot;icon&quot;&gt;&lt;/div&gt;
  &lt;span&gt;
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.      
  &lt;/span&gt;
&lt;/div&gt;
</pre>
<p>CSS:</p>
<pre class="brush: css; title: ; notranslate">
&lt;pre class=&quot;lang:css decode:true&quot; title=&quot;CSS Snippet for Multiple Background Images&quot;&gt;.box {
  margin: 20px;
  border: 1px solid black;
  padding: 20px;
  background-color: #eee;
  min-width: 430px;  /* Set a min-width, so the images don't spill outside of the container */
}

.icon {
  height: 100px;
  width: 450px;        /* Set a fixed width, so the images don't float off to the left and right */
  margin: 0 auto;      /* Center the images */
  margin-bottom: 20px; /* Push the text away by 20px */
  background-image:
    url('https://www.barnesian.com/wp-content/uploads/2015/12/ruby.png'),
    url('https://www.barnesian.com/wp-content/uploads/2015/12/php.png'),
    url('https://www.barnesian.com/wp-content/uploads/2015/12/go.png');
  background-repeat: no-repeat, no-repeat, no-repeat;    
  background-size:
    100px,       /* height and width of 100px */
    auto 100px,  /* height auto and width of 100px */
    100px;       /* height and width of 100px */
  background-position: left, center, right;  /* You can also set an offset here if you need to */
}
</pre>
<p>Those will produce the following result:</p>
<p><a href="https://www.barnesian.com/wp-content/uploads/2015/12/multiple-background-images.png" rel="attachment wp-att-914"><img loading="lazy" class="alignnone size-full wp-image-914" src="https://www.barnesian.com/wp-content/uploads/2015/12/multiple-background-images.png" alt="Image showing how the HTML and CSS in this blog post render" width="556" height="285" /></a></p>
<p>Here&#8217;s a quick demo on JSFiddle:</p>
<p><iframe loading="lazy" width="100%" height="300" src="//jsfiddle.net/4h5wL5gd/embedded/result,html,css,js/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/multiple-background-image-in-css/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Quick Tip: Parsing a Config String in Ruby</title>
		<link>https://barnesian.com/quick-tip-parsing-a-config-string-in-ruby/</link>
					<comments>https://barnesian.com/quick-tip-parsing-a-config-string-in-ruby/#respond</comments>
		
		<dc:creator><![CDATA[Chris Barnes]]></dc:creator>
		<pubDate>Fri, 20 Mar 2015 00:26:47 +0000</pubDate>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://www.barnesian.com/?p=879</guid>

					<description><![CDATA[Recently I came across the need to parse a bit of a config file, in this kind of format: "Category=filetype;..." Here is how one would do such a thing using split, inject and map.]]></description>
										<content:encoded><![CDATA[<p>Recently I came across the need to parse a bit of a config file, in this kind of format: “Category=filetype;…” Here is how one would do such a thing using <a href="http://ruby-doc.org/core-2.2.1/String.html#method-i-split">split</a>, <a title="Docs for enumerable inject" href="http://ruby-doc.org/core-2.2.1/Enumerable.html#method-i-inject" target="_blank" rel="noopener">inject</a> and <a title="Docs for enumerable map" href="http://ruby-doc.org/core-2.2.1/Enumerable.html#method-i-map" target="_blank" rel="noopener">map</a>.</p>
<pre class="brush: ruby; title: ; notranslate">
raw_config = &quot;Image=jpg,tiff,png;Document=docx,doc,pdf;Other=rb,cs,c;&quot;
 
config = raw_config.split(&quot;;&quot;).inject({}) do |result, fragment|
  type, extensions = fragment.split(&quot;=&quot;)
  result[type.strip.downcase.to_sym] = extensions.split(&quot;,&quot;).map{ |s| s.strip }
  result
end
</pre>
<p>The result is a <a title="Docs for Ruby Hash" href="http://ruby-doc.org/core-2.2.1/Hash.html" target="_blank" rel="noopener">hash</a> where you can get an array of the file extensions for a given category like this<br />
<code>config[:image]</code><br />
and the resulting hash looks like this:</p>
<pre class="brush: ruby; title: ; notranslate">
{
  :image =&gt; [&quot;jpg&quot;, &quot;tiff&quot;, &quot;png&quot;],
  :document =&gt; [&quot;docx&quot;, &quot;doc&quot;, &quot;pdf&quot;],
  :other =&gt; [&quot;rb&quot;, &quot;cs&quot;, &quot;c&quot;]
}
</pre>
<p>Let me know in the comments if you have a better way!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://barnesian.com/quick-tip-parsing-a-config-string-in-ruby/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
