2019-09-24T17:26:11+00:00https://www.minh.ioInstagram Hashtag Tools2017-11-26T00:00:00+00:00https://www.minh.io/tech/2017/11/26/17-instagram-hastag-tool<section class="container">
<p class="drop-cap">
Recently, I created a tool to help myself when posting tags to instagram. It can difficult to manage many hashtags, so this tool assists with counting the hashtags, sorting them, and removing duplicates. Hopefully this helps someone else out there.
</p>
<p><a href="/hashtag"><button class="btn red">Open web app</button><a></a></a></p>
</section>
CSS Drop Caps2015-09-28T00:00:00+00:00https://www.minh.io/design/2015/09/28/dropcaps<section class="container">
<p><span class="drop-caps">D</span>rop caps are a design pattern that can decorate and emphasize
the start of text. They’re used extensively on this website to aid navigation
through heavy text. While drop caps are found commonly in magazines and books, they’re rare on the web, most likely
because they’re difficult to properly implement. In this post, I’ll show a technique for creating drop caps using CSS
that loads fast, is widely supported, and works in a responsive design.</p>
<p><span class="btn red" id="button-change">Set Random Dropcap</span></p>
<h2 id="tutorial">Tutorial</h2>
<p>This is how you would write HTML/CSS with a drop cap:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><p</span> <span class="na">class=</span><span class="s">"drop-cap"</span><span class="nt">></span>
Drop caps are a design pattern ...
<span class="nt"></p></span></code></pre></figure>
<p>Below is the <a href="http://sass-lang.com/">SCSS</a> code I use to implement the drop cap. Most of the functionality needed comes
from the :first-letter, float:left, line-height, and padding. The additional mixins and variables are necessary for
making it work responsively</p>
<figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// specify font sizes here
</span><span class="nv">$font-size-mobile</span><span class="p">:</span> <span class="m">16px</span><span class="p">;</span>
<span class="nv">$font-size-tablet</span><span class="p">:</span> <span class="m">18px</span><span class="p">;</span>
<span class="nv">$font-size-desktop</span><span class="p">:</span> <span class="m">18px</span><span class="p">;</span>
<span class="nv">$font-size-large-desktop</span><span class="p">:</span> <span class="m">20px</span><span class="p">;</span>
<span class="c1">// specify breakpoints here
</span><span class="nv">$width-tablet</span><span class="p">:</span> <span class="m">780px</span><span class="p">;</span>
<span class="nv">$width-desktop</span><span class="p">:</span> <span class="m">970px</span><span class="p">;</span>
<span class="nv">$width-large-desktop</span><span class="p">:</span> <span class="m">1170px</span><span class="p">;</span>
<span class="c1">// handy breakpoint mixin
</span><span class="k">@mixin</span> <span class="nf">bp</span><span class="p">(</span><span class="nv">$point</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@if</span> <span class="nv">$point</span> <span class="o">==</span> <span class="n">tablet</span> <span class="p">{</span>
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="nv">$tablet-width</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@content</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">@else</span> <span class="n">if</span> <span class="nv">$point</span> <span class="o">==</span> <span class="n">desktop</span> <span class="p">{</span>
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="nv">$width-desktop</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@content</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">@else</span> <span class="n">if</span> <span class="nv">$point</span> <span class="o">==</span> <span class="n">large-desktop</span> <span class="p">{</span>
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="nv">$width-large-desktop</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@content</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// adjusts the drop cap font-size and line-height
// each dropcap should align with the line height / baseline of each row
</span><span class="k">@mixin</span> <span class="nf">dropcap-size</span><span class="p">(</span><span class="nv">$font-size</span><span class="o">,</span> <span class="nv">$drop-cap-height</span><span class="o">:</span> <span class="m">3</span><span class="o">,</span> <span class="nv">$line-height</span><span class="o">:</span> <span class="m">1</span><span class="mi">.6</span><span class="p">)</span> <span class="p">{</span>
<span class="nl">font-size</span><span class="p">:</span> <span class="nf">floor</span><span class="p">((</span><span class="nv">$font-size</span> <span class="o">*</span> <span class="nv">$line-height</span><span class="p">))</span> <span class="o">*</span> <span class="nv">$drop-cap-height</span> <span class="o">*</span> <span class="m">1</span><span class="mi">.20</span><span class="p">;</span>
<span class="nl">line-height</span><span class="p">:</span> <span class="nf">floor</span><span class="p">((</span><span class="nv">$font-size</span> <span class="o">*</span> <span class="nv">$line-height</span><span class="p">))</span> <span class="o">*</span> <span class="nv">$drop-cap-height</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">@mixin</span> <span class="nf">dropcaps</span><span class="p">(</span><span class="nv">$font-family</span><span class="o">:</span> <span class="n">Georgia</span><span class="p">)</span> <span class="p">{</span>
<span class="nl">float</span><span class="p">:</span> <span class="nb">left</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">0px</span> <span class="m">10px</span> <span class="m">0px</span> <span class="m">0px</span><span class="p">;</span>
<span class="nl">font-family</span><span class="p">:</span> <span class="nv">$font-family</span><span class="p">;</span>
<span class="k">@include</span> <span class="nd">dropcap-size</span><span class="p">(</span><span class="nv">$font-size-mobile</span><span class="p">);</span>
<span class="k">@include</span> <span class="nd">bp</span><span class="p">(</span><span class="n">tablet</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">dropcap-size</span><span class="p">(</span><span class="nv">$font-size-tablet</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">@include</span> <span class="nd">bp</span><span class="p">(</span><span class="n">desktop</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">dropcap-size</span><span class="p">(</span><span class="nv">$font-size-desktop</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">@include</span> <span class="nd">bp</span><span class="p">(</span><span class="n">large-desktop</span><span class="p">)</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">dropcap-size</span><span class="p">(</span><span class="nv">$font-size-large-desktop</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// this is the output css class used in the html above
</span><span class="nc">.drop-cap</span><span class="nd">:first-letter</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">dropcaps</span><span class="p">();</span>
<span class="p">}</span>
<span class="c1">// hacky but firefox requires top padding to align with the baseline
</span><span class="k">@-moz-document</span> <span class="nt">url-prefix</span><span class="o">()</span> <span class="p">{</span>
<span class="nc">.drop-cap</span><span class="nd">:first-letter</span> <span class="p">{</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span> <span class="m">10px</span> <span class="m">0px</span> <span class="m">0px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> </code></pre></figure>
<h2 id="browser-support">Browser Support</h2>
<p><span class="btn red">Chrome 9+</span> <span class="btn red">Safari 8+</span> <span class="btn red">FF 3.5+</span> <span class="btn red">IE9+</span></p>
<h2 id="design-details">Design Details</h2>
<p>Initially I looked at various JavaScript solutions but noticed an initial flicker of content for all of them as
the browser would take a moment for the JS to render the drop cap. The above CSS/SCSS solution renders drop caps
immediately but requires more work when changing fonts, sizes, line-heights, etc. I would recommend using
<a href="http://webplatform.adobe.com/dropcap.js/">Adobe’s dropcap.js</a> for perfect drop-caps with minimal/zero CSS/SCSS effort.</p>
<h2 id="best-practices">Best Practices</h2>
<ul>
<li>For faster rendering of the drop cap, use a <a href="http://www.w3schools.com/cssref/css_websafe_fonts.asp">websafe font</a></li>
<li>Align drop caps with the baseline of the text lines</li>
<li>Don’t use drop caps for few lines of text (e.g. don’t use a 3 line deep drop cap for a 3 line paragraph)</li>
</ul>
<h2 id="todo">TODO</h2>
<ul>
<li>Various fonts don’t align properly</li>
<li>Firefox doesn’t align properly for all fonts</li>
<li>The W3C is working on an initial letter (drop caps) <a href="http://www.w3.org/TR/2015/WD-css-inline-3-20150917/#initial-letter-styling">specification</a>,
so eventaully the above techniques may become obsolete except for support in older browsers.</li>
</ul>
<h2 id="research-notes">Research Notes</h2>
<p>When researching ways to implement drop caps, I came across several implementations/articles:</p>
<ul>
<li><a href="http://webplatform.adobe.com/dropcap.js/">Adobe’s dropcap.js</a></li>
<li><a href="http://typeplate.com/#drop-caps">Typeplate’s drop cap Sass mixin</a></li>
<li><a href="http://thenewcode.com/961/Big-Beautiful-DropCaps-with-CSS-initial-letter">Paragraph drop caps with initial letter</a></li>
<li><a href="https://css-tricks.com/a-call-for-nth-everything/">Chris Coyer’s call for first-word</a></li>
<li><a href="https://css-tricks.com/snippets/css/drop-caps/">CSS tricks</a></li>
<li><a href="http://sedition.com/a/2453">dropj jQuery plugin</a></li>
<li><a href="http://www.jqueryscript.net/demo/jQuery-Plugin-To-Capitalize-First-Letter-Capital-Letter/">capital letter plugin</a></li>
<li><a href="http://blog.boyet.com/blog/blog/css3-line-height-is-important-for-drop-caps/">drop caps css tutorial</a></li>
</ul>
</section>
Sort Jekyll Pages and Posts2015-09-22T00:00:00+00:00https://www.minh.io/tech/2015/09/22/jekyll-sort-pages-posts<section class="container">
<p class="drop-cap">Liquid isn’t the most verbose language. However, it’s the templating language
that powers Jekyll, so learning its syntax and capabilities is essential when creating Jekyll pages. In this
post I’ll show a technique for sorting Jekyll pages and posts by combining and sorting Liquid arrays.</p>
<h2 id="the-problem">The Problem</h2>
<p>I needed a way to output a sorted array that contained Jekyll pages and posts that contained a
“featured” tag. For example, the following would be the YAML front matter for an example page and post:</p>
<figure class="highlight"><pre><code class="language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="s">layout</span><span class="pi">:</span> <span class="s">page</span>
<span class="s">title</span><span class="pi">:</span> <span class="s">Page1</span>
<span class="s">tags</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">featured</span><span class="pi">]</span>
<span class="s">featuredOrder</span><span class="pi">:</span> <span class="s">1</span>
<span class="nn">---</span>
<span class="nn">...</span></code></pre></figure>
<figure class="highlight"><pre><code class="language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="s">layout</span><span class="pi">:</span> <span class="s">post</span>
<span class="s">title</span><span class="pi">:</span> <span class="s">Post1</span>
<span class="s">tags</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">featured</span><span class="pi">]</span>
<span class="s">featuredOrder</span><span class="pi">:</span> <span class="s">2</span>
<span class="nn">---</span>
<span class="nn">...</span></code></pre></figure>
<p>The goal was to output content from an array that contained these items sorted in ascending order based on the featuredOrder.
Jekyll offers helpful <a href="http://jekyllrb.com/docs/variables/">site variables</a> like site.pages and
site.posts but there isn’t a variable that includes both.</p>
<h2 id="the-solution">The Solution</h2>
<p>I aggregated all posts and tags with a “featured” tag to a “featuredItems” array
and sorted it based on the “featuredOrder”:</p>
<figure class="highlight"><pre><code class="language-liquid" data-lang="liquid"><span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">featuredItems</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">site</span><span class="p">.</span><span class="nv">tags</span><span class="p">.</span><span class="nv">featured</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span>page<span class="w"> </span>in<span class="w"> </span>site.pages<span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="nv">page</span><span class="p">.</span><span class="nv">tags</span><span class="w"> </span><span class="ow">contains</span><span class="w"> </span><span class="s2">"featured"</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">featuredItems</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">featuredItems</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">push</span><span class="p">:</span><span class="w"> </span>page<span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="kr">endif</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">endfor</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">featuredItems</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">featuredItems</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">sort</span><span class="p">:</span><span class="w"> </span><span class="s2">"featuredOrder"</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span>item<span class="w"> </span>in<span class="w"> </span>featuredItems<span class="w"> </span><span class="p">%}</span>
<span class="p">{{</span><span class="w"> </span><span class="nv">item</span><span class="p">.</span><span class="nv">title</span><span class="w"> </span><span class="p">}}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">endfor</span><span class="w"> </span><span class="p">%}</span></code></pre></figure>
<p>This outputs “Page1 Post1” from above, which was the desired output and currently in use to render the content
on my homepage.</p>
</section>
Visualizing Graphs2015-09-18T00:00:00+00:00https://www.minh.io/tech/2015/09/18/visualizing-graphs<section class="container">
<p class="drop-cap">Graphs can be very interesting data visualizations that can be
both eye catching and insightful. They’re all over the place, from social networks to map directions to
<a href="http://economicgraphchallenge.linkedin.com/">digital mappings</a> and more. Today, I experimented with creating a graph using <a href="http://visjs.org/">vis.js</a>. Check it out below, but please
view it from a desktop computer, as performance is not optimal on mobile or tablets:
</p>
<p><a href="/labs/net"><button class="btn red">Open Demo</button><a></a></a></p>
<p><br /></p>
<p>Every time the demo is loaded, a randomly generated graph is created and animated. This isn’t really
useful at the moment but it’s a good first step towards creating more powerful tools like
<a href="http://theantworks.herokuapp.com/industry-report/pfizer-az/">here</a> or <a href="http://quid.com/">here</a>.</p>
<p><a href="/assets/img/hero/1x/graph.jpg" class="img-popup"> <br />
<img class="img-responsive img-rounded img-larger" src="/assets/img/hero/1x/graph.jpg" />
</a> <br />
<br />
Check back later as I’ll probably have something more interesting to show.</p>
</section>
Scrollbars CSS Trick2015-09-05T00:00:00+00:00https://www.minh.io/tech/2015/09/05/unwanted-scrolling<section class="container">
<p class="drop-cap">Recently I came across a nice css trick for debugging unintentional scrolling due
to ghost CSS elements. All credit is due to <a href="http://wernull.com/2013/04/debug-ghost-css-elements-causing-unwanted-scrolling/">Kyle Werner from wernull</a>,
so please visit his site, thank him, and support his projects.</p>
<p>Why did I need to do this? Well, I discovered an issue on my iPad Air 2 with content overflowing outside the page
container if I switched from landscape to portrait mode. This meant that a user could scroll / swipe right and
see unwanted horizontal scrollbars.</p>
<p>Hopefully this screenshot helps a bit:</p>
<p><a href="/assets/img/posts/debugging-scrolling.jpg" class="img-popup"> <br />
<img class="img-responsive img-rounded img-larger" src="/assets/img/posts/debugging-scrolling.jpg" />
</a></p>
<p>The above screenshot was rendered using <a href="http://wernull.com/2013/04/debug-ghost-css-elements-causing-unwanted-scrolling/">Kyle Werner’s css trick</a>:</p>
<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="o">*</span> <span class="p">{</span>
<span class="nl">background</span><span class="p">:</span> <span class="m">#000</span> <span class="cp">!important</span><span class="p">;</span>
<span class="nl">color</span><span class="p">:</span> <span class="m">#0f0</span> <span class="cp">!important</span><span class="p">;</span>
<span class="nl">outline</span><span class="p">:</span> <span class="nb">solid</span> <span class="m">#f00</span> <span class="m">1px</span> <span class="cp">!important</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>This made it easy to track down the issue, which was that my Bootstrap3 “container” class for tablet widths at 768
was too wide, so I decreased its width until the content fit properly within the page. Before this I tried to
fix the problem by setting “overflow-x: hidden;”, which solved the unwanted scrolling problem but
masked the real problem of content overflowing out of the page. It also led to awesome new bugs like scrollbars being
totally invisible.</p>
</section>
Filter and Sort in Jekyll2015-07-19T00:00:00+00:00https://www.minh.io/tech/2015/07/19/filter-sort-jekyll<section class="container">
<p class="drop-cap">
This post will describe how to filter and sort a set of Jekyll pages.
I needed to do this recently because I wanted to display a set of Jekyll pages stored
in <a href="http://jekyllrb.com/docs/pages/">folders</a> that didn’t include every page and was sorted in
a defined order. Initially I came across an excellent
<a href="http://www.leveluplunch.com/blog/2014/04/03/sort-pages-by-title-filter-array-by-layout-jekyllrb/">article</a>
that described the basic syntax but I encountered some Liquid errors perhaps because I’m using Jekyll 3.
The solution I came up with was used to create the projects page:
</p>
<p><a href="/projects"><button class="btn red">Projects Demo</button><a></a></a></p>
<h2 id="yaml-front-matter">YAML Front Matter</h2>
<p>I decided to filter pages by layout and sort by a new front matter variable called “order”, so each of my pages
looked like this:</p>
<figure class="highlight"><pre><code class="language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="s">layout</span><span class="pi">:</span> <span class="s">projects</span>
<span class="s">order</span><span class="pi">:</span> <span class="s">2</span>
<span class="nn">---</span></code></pre></figure>
<h2 id="jekyll-code">Jekyll Code</h2>
<p>Next, I used the following Jekyll code to sort and filter:</p>
<figure class="highlight"><pre><code class="language-liquid" data-lang="liquid"><span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">projects</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">site</span><span class="p">.</span><span class="nv">pages</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">where</span><span class="p">:</span><span class="w"> </span><span class="s2">"layout"</span><span class="p">,</span><span class="w"> </span><span class="s2">"projects"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">sort</span><span class="p">:</span><span class="w"> </span><span class="s2">"order"</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span>page<span class="w"> </span>in<span class="w"> </span>projects<span class="w"> </span><span class="p">%}</span>
// do stuff
<span class="p">{%</span><span class="w"> </span><span class="nt">endfor</span><span class="w"> </span><span class="p">%}</span></code></pre></figure>
<p>So, based on the order specified by the Jekyll YAML front matter, the loop iterates in increasing order.</p>
</section>
Photo Credits2015-07-11T00:00:00+00:00https://www.minh.io/tech/2015/07/11/photo-credits<section class="container">
<p class="drop-cap">
In this post I’ll describe the sources of this site’s cover images. For the most part, I usually use
Google image search to find images that match a post’s contents. I try to find images that are free
to use in the public domain and ask the author’s for permission. However, I wasn’t able to find
the source of all images and some sites don’t list any usage requirements.
</p>
<p>In order to keep page sizes under 1MB and improve load times, I use imagemagick to compress each of the images by
placing all of the images into a directory and running the following command to compress them with a width of 900px
with interlacing so that the images blur into view when loading:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># for 1x mobile photos</span>
mogrify -quality <span class="s2">"92%"</span> -geometry 900 -interlace Plane -format jpg <span class="k">*</span>.jpg
<span class="c"># for 2x higher res photos</span>
mogrify -quality <span class="s2">"92%"</span> -geometry 1600 -interlace Plane -format jpg <span class="k">*</span>.jpg</code></pre></figure>
<figure>
<img class="img-rounded img-responsive" alt="Binary-97561256.jpg" src="/assets/img/hero/1x/wood.jpg" />
<figcaption class="text-center">
<a href="http://feelgrafix.com/920350-wood.html">Wood 920350 by feelgrrafix</a>
</figcaption>
</figure>
<figure>
<img class="img-rounded img-responsive" alt="Binary-97561256.jpg" src="/assets/img/hero/1x/dots-float.jpg" />
<figcaption class="text-center">
<a href="http://wall.alphacoders.com/big.php?i=358473">358473 by Jochi</a>
</figcaption>
</figure>
<figure>
<img class="img-rounded img-responsive" alt="Binary-97561256.jpg" src="/assets/img/hero/1x/red-meteor.jpg" />
<figcaption class="text-center">
<a href="http://www.topbackgroundsfree.com/meteor-wallpaper-downloads-30463-hd-pictures">Meteor Wallpaper by topbackgroundsfree.com</a>
</figcaption>
</figure>
<figure>
<img class="img-rounded img-responsive" alt="Binary-97561256.jpg" src="/assets/img/hero/1x/sf-fog.jpg" />
<figcaption class="text-center">
<a href="http://bgdphotooftheday.com/san-francisco-bay-bridge/">San Francisco by Rob Bye (found on unsplash)</a>
</figcaption>
</figure>
<figure>
<img class="img-rounded img-responsive" alt="earth-wallpapers-5.jpg" src="/assets/img/hero/1x/earth2.jpg" />
<figcaption class="text-center">
<a href="http://wonderfulengineering.com/50-earth-wallpapers-in-full-hd-for-free-download/">Earth Wallpaper by wonderfulengineering.com</a>
</figcaption>
</figure>
<figure>
<img class="img-rounded img-responsive" alt="seattle2.jpg" src="/assets/img/hero/1x/crops-kansas.jpg" />
<figcaption class="text-center">
<a href="https://en.wikipedia.org/wiki/Agriculture_in_the_United_States#/media/File:Crops_Kansas_AST_20010624.jpg">Center Pivot Irrigation in Kansas (June 2001) NASA</a>
</figcaption>
</figure>
</section>
Jekyll Line Numbers2015-06-28T00:00:00+00:00https://www.minh.io/blog/2015/06/28/jekyll-line-numbers<section class="container">
<p class="drop-cap">In this post I’ll describe how to add line numbers to a Jekyll 3 site using Rouge. While this should be
a simple task, it actually took me a bit of effort to allow code to be copied without line numbers also
being copied. Previously I used highlight.js, which was super fast, but I decided to speed things up even more
by switching to Rouge and have the syntax highlighting pre-generated as part of the Jekyll static compilation.
</p>
<h2 id="demo">Demo</h2>
<p>Here’s an example with line numbers:</p>
<figure class="lineno-container">
<figure class="highlight"><pre><code class="language-python" data-lang="python"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span><span class="mi">1</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span><span class="n">a</span><span class="o">+</span><span class="n">b</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">print</span> <span class="n">fib</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></figure>
</figure>
<p>Here’s the same example without line numbers:</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span><span class="mi">1</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span><span class="n">a</span><span class="o">+</span><span class="n">b</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">print</span> <span class="n">fib</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span></code></pre></figure>
<p>Notice that selecting and copying the code in both examples does not also copy the line numbers.</p>
<h2 id="pygments-issues">Pygments Issues</h2>
<p>Initially I added line number with Pygments but had issues copying code within the generated
code blocks because it would also copy the line numbers.
Here’s an example of the code I used:</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="p">{</span><span class="o">%</span> <span class="n">highlight</span> <span class="n">python</span> <span class="n">linenos</span> <span class="o">%</span><span class="p">}</span>
<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span><span class="mi">1</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span><span class="n">a</span><span class="o">+</span><span class="n">b</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">print</span> <span class="n">fib</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="p">{</span><span class="o">%</span> <span class="n">endhighlight</span> <span class="o">%</span><span class="p">}</span></code></pre></figure>
<p>I found some documentation describing how adding linenos=table would separate the code from the line numbers.
Alas, I had no luck with this either because it jacked up my layout.</p>
<h2 id="tutorial">Tutorial</h2>
<p>The solution that worked for me was switching to <a href="https://github.com/jneen/rouge">Rouge</a> and doing a bit of CSS.</p>
<p><strong>Step 1</strong></p>
<p>If you’re using Jekyll 3 then install <a href="https://github.com/jneen/rouge">Rouge</a> and modify your _config.yml to use
Rouge:</p>
<figure class="highlight"><pre><code class="language-yml" data-lang="yml"><span class="s">highlighter</span><span class="pi">:</span> <span class="s">rouge</span> <span class="c1"># or pygments or null</span>
<span class="s">markdown</span><span class="pi">:</span> <span class="s">kramdown</span> <span class="c1"># my examples assume you're using kramdown</span></code></pre></figure>
<p>Similarly to Pygments, you can highlight code like the following example:</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"><span class="o"><</span><span class="n">figure</span><span class="x"> </span><span class="n">class</span><span class="o">=</span><span class="s">"lineno-container"</span><span class="o">></span><span class="x">
</span><span class="p">{</span><span class="o">%</span><span class="x"> </span><span class="n">highlight</span><span class="x"> </span><span class="n">js</span><span class="x"> </span><span class="n">linenos</span><span class="x"> </span><span class="o">%</span><span class="p">}</span><span class="x">
</span><span class="k">var</span><span class="x"> </span><span class="n">recursive</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">function</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="k">if</span><span class="p">(</span><span class="n">n</span><span class="x"> </span><span class="o"><=</span><span class="x"> </span><span class="m">2</span><span class="p">)</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="m">1</span><span class="p">;</span><span class="x">
</span><span class="p">}</span><span class="x"> </span><span class="k">else</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="n">this</span><span class="o">.</span><span class="n">recursive</span><span class="p">(</span><span class="n">n</span><span class="x"> </span><span class="o">-</span><span class="x"> </span><span class="m">1</span><span class="p">)</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">this</span><span class="o">.</span><span class="n">recursive</span><span class="p">(</span><span class="n">n</span><span class="x"> </span><span class="o">-</span><span class="x"> </span><span class="m">2</span><span class="p">);</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">};</span><span class="x">
</span><span class="p">{</span><span class="o">%</span><span class="x"> </span><span class="n">endhighlight</span><span class="x"> </span><span class="o">%</span><span class="p">}</span><span class="x">
</span><span class="o"></</span><span class="n">figure</span><span class="o">></span></code></pre></figure>
<p>This should generate markup similar to the following:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><figure</span> <span class="na">class=</span><span class="s">"lineno-container"</span><span class="nt">></span>
<span class="nt"><figure</span> <span class="na">class=</span><span class="s">"highlight"</span><span class="nt">></span>
<span class="nt"><pre></span>
<span class="nt"><code</span> <span class="na">class=</span><span class="s">"language-js"</span> <span class="na">data-lang=</span><span class="s">"js"</span><span class="nt">></span>
<span class="nt"><table></span>
<span class="nt"><tbody></span>
<span class="nt"><tr></span>
<span class="c"><!-- line numbers --></span>
<span class="nt"><td</span> <span class="na">class=</span><span class="s">"gutter gl"</span><span class="nt">></span>...<span class="nt"></td></span>
<span class="c"><!-- code --></span>
<span class="nt"><td</span> <span class="na">class=</span><span class="s">"code"</span><span class="nt">></span>...<span class="nt"></d></span>
<span class="nt"></tr></span>
<span class="nt"></tbody></span>
<span class="nt"></table></span>
<span class="nt"></code></span>
<span class="nt"></pre></span>
<span class="nt"></figure></span>
<span class="nt"></figure></span></code></pre></figure>
<p><strong>Step 2</strong></p>
<p>It should hopefully be easier to style the line numbers and code now that they’re separate columns (Pygments
kept it as a single pre element with spans intermixed with line numbers and code, which made things tricky.</p>
<p>Specifically for my SCSS/CSS, I used the following code:</p>
<figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// so that the line numbers are not selectable
</span><span class="k">@mixin</span> <span class="nf">unselectable</span><span class="p">()</span> <span class="p">{</span>
<span class="na">-webkit-touch-callout</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="na">-webkit-user-select</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="na">-khtml-user-select</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="na">-moz-user-select</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="na">-ms-user-select</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="na">user-select</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">@mixin</span> <span class="nf">opacity</span><span class="p">(</span><span class="nv">$opacity</span><span class="p">)</span> <span class="p">{</span>
<span class="nl">opacity</span><span class="p">:</span> <span class="nv">$opacity</span><span class="p">;</span>
<span class="nv">$opacity-ie</span><span class="p">:</span> <span class="nv">$opacity</span> <span class="o">*</span> <span class="m">100</span><span class="p">;</span>
<span class="nl">filter</span><span class="p">:</span> <span class="nf">alpha</span><span class="p">(</span><span class="n">opacity</span><span class="o">=</span><span class="nv">$opacity-ie</span><span class="p">);</span> <span class="c1">//IE8
</span><span class="p">}</span>
<span class="c1">// having a lineno-container made it easier to style line number
// code blocks without impacting normal code blocks
</span><span class="nc">.lineno-container</span> <span class="o">></span> <span class="nt">figure</span> <span class="o">></span> <span class="nt">pre</span> <span class="p">{</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.highlight</span> <span class="p">{</span>
<span class="nt">pre</span><span class="nc">.lineno</span> <span class="p">{</span>
<span class="nl">border</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="k">@include</span> <span class="nd">opacity</span><span class="p">(</span><span class="m">0</span><span class="mi">.6</span><span class="p">);</span>
<span class="p">}</span>
<span class="nc">.lineno</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">unselectable</span><span class="p">();</span>
<span class="p">}</span>
<span class="nc">.gutter</span> <span class="p">{</span>
<span class="nl">border-right</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="mh">#ccc</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">pre</span> <span class="p">{</span>
<span class="nt">pre</span> <span class="p">{</span>
<span class="nl">border</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="nl">margin-bottom</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
</section>
Site Refresh2015-06-27T00:00:00+00:00https://www.minh.io/blog/2015/06/27/site-refresh<section class="container">
<p class="drop-cap">I have rebuilt this site again, creating a custom theme and incorporating
everything I've learned in development and design since my <a href="http://design9.minh.io">previous version</a>.
In this post I'll describe the improvements, engineering, and inspirations.
</p>
</section>
<section class="container">
<h2 id="focused-content">Focused Content</h2>
<p>With a bounce rate of 82.35%, I wanted to increase user retention, so I removed a lot of
content, like this single post dedicated to <a href="http://design9.minh.io/2013/07/05/cowsay/">cowsay</a>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code> _______________
< less cows plz >
---------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
</code></pre>
</div>
<h2 id="more-visuals">More Visuals</h2>
<p>This new version includes larger hero <a href="/tech/2015/07/11/photo-credits/">images</a>, intentional colors, and
improved typography in a mobile-first responsive layout. Everything is balanced to keep load times
under 1 second and 1MB.</p>
<figure>
<img src="/assets/img/hero/1x/sf-fog.jpg" alt="sf" class="img-responsive img-round" />
<figcaption class="text-center">Unsplash Imagery</figcaption>
</figure>
<figure class="highlight">
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// no comment</span>
<span class="kd">function</span> <span class="nx">recursive</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">n</span> <span class="o"><=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">recursive</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">recursive</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<figcaption class="text-center">Rouge Syntax Highlighting</figcaption>
</figure>
</section>
<section class="container">
<h2 id="engineering">Engineering</h2>
<p>In addition to improving the design and layout, I improved the tool infrastructure for easier maintainability
and a more enjoyable developer experience.</p>
<p>The current resources and tools I’ve used to build this site are:</p>
<ul>
<li>Jekyll 3</li>
<li>Kramdown</li>
<li>Gulp</li>
<li>Browsersync</li>
<li>Bootstrap 3</li>
<li>jQuery</li>
<li>Sass</li>
<li><a href="http://www.unsplash.com">http://www.unsplash.com</a> for imagery</li>
<li><a href="https://picjumbo.com">https://picjumbo.com</a> for imagery</li>
<li><a href="https://pixabay.com">https://pixabay.com</a> for imagery</li>
<li><a href="http://jekyllrb.com/docs/deployment-methods/">Git hooks</a> for auto-deploys on commits</li>
</ul>
</section>
<section class="container">
<h2 id="inspirations">Inspirations</h2>
<p>I’m not a designer but I try to educate myself on design principles as much as I can. One of the ways I do this is
by observing the world around me and remixing the best design elements I see into a hopefully unique result.</p>
<p>Here are all the places I drew inspiration from:</p>
<ul>
<li><a href="http://www.zachholman.com">Zach Holman’s site</a>. He’s a funny writer and speaker with a really cool blog.</li>
<li><a href="http://paulstamatiou.com/">Paul Stamatiou</a>. A designer with an amazing site with beautiful typography and photos.</li>
<li><a href="http://www.medium.com">Medium</a>, <a href="http://www.ghost.org">Ghost</a>.
Great blogging platforms with eye catching hero images and typography.</li>
</ul>
<h2 id="a-full-and-comphrensive-style-test">A Full and Comphrensive Style Test</h2>
<p>Inspired by Ghost’s style test, this section will cover all of the theme’s UI elements. It’s mostly nonsensical
and only here for testing purposes.</p>
<p class="typl8-drop-cap">Bright Skies is a free and responsive <a href="http://jekyllrb.com/">Jekyll</a> theme with a focus on <strong>imagery and typography</strong>.
The goal of this theme is to minimize distractions and let content be the focus.</p>
<blockquote class="pull-right">
<p>This is a right blockquote.</p>
</blockquote>
<p>Bright Skies is built on top of many great open source frameworks and tools to make it easier to create maintainable
content that loads fast and looks great on many different devices.
<em>This is emphasized.</em> 5<sup>3</sup> = 125.
Water is H<sub>2</sub>O. Aliquam libero nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl.
<cite>The New York Times</cite> (That’s a citation).
<span style="text-decoration:underline;">Underline.</span></p>
<blockquote class="pull-left">
<p>This is a left blockquote.</p>
</blockquote>
<p><abbr title="Hyper Text Markup Language">HTML</abbr> and
<abbr title="Cascading Style Sheets">CSS</abbr> are our tools.
Mauris a ante. Suspendisse quam sem, consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue quis tellus.
Praesent mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu volutpat enim diam eget metus.
To copy a file type <code>COPY <var>filename</var></code>. <del>Dinner’s at 5:00.</del> <ins>Let’s make that 7.</ins>
This <span style="text-decoration:line-through;">text</span> has been struck.</p>
<hr />
<h1 id="heading-1">Heading 1</h1>
<h2 id="heading-2">Heading 2</h2>
<h3 id="heading-3">Heading 3</h3>
<h4 id="heading-4">Heading 4</h4>
<h5 id="heading-5">Heading 5</h5>
<h6 id="heading-6">Heading 6</h6>
<p>Paragraph text</p>
<hr />
<h2 id="blockquotes">Blockquotes</h2>
<p>Let’s keep it simple. Italics are good to help set it off from the body text. Be sure to style the citation.</p>
<section>
<blockquote class="huge">
Good afternoon, gentlemen. I am a HAL 9000 computer. I became operational at the H.A.L. plant in Urbana, Illinois on the 12th of January 1992. My instructor was Mr. Langley, and he taught me to sing a song. If you’d like to hear it I can sing it for you. <cite>— <a href="http://en.wikipedia.org/wiki/HAL_9000">HAL 9000</a></cite>
</blockquote>
</section>
<p>And here’s a bit of trailing text.</p>
<hr />
<h2 id="text-level-semantics">Text-level semantics</h2>
<p>The <a href="#">a element</a> example<br />
The <abbr>abbr element</abbr> and <abbr title="Title text">abbr element with title</abbr> examples<br />
The <b>b element</b> example<br />
The <cite>cite element</cite> example<br />
The <code>code element</code> example<br />
The <del>del element</del> example <br />
The <dfn>dfn element</dfn> and <dfn title="Title text">dfn element with title</dfn> examples <br />
The <em>em element</em> example <br />
The <i>i element</i> example <br />
The <ins>ins element</ins> example<br />
The <kbd>kbd element</kbd> example<br />
The <mark>mark element</mark> example <br />
The <q>q element <q>inside</q> a q element</q> example<br />
The <s>s element</s> example<br />
The <samp>samp element</samp> example<br />
The <small>small element</small> example<br />
The <span>span element</span> example<br />
The <strong>strong element</strong> example<br />
The <sub>sub element</sub> example<br />
The <sup>sup element</sup> example<br />
The <var>var element</var> example<br />
The <u>u element</u> example<br /></p>
<hr />
</section>
Angular scrollbars with Malihu2015-01-11T00:00:00+00:00https://www.minh.io/tech/2015/01/11/angularjs-scrollbars-with-malihu<section class="container">
<p class="drop-cap">
Recently I needed to style scrollbars within a dark themed web application that looked consistent between
different web browsers. TL;DR I created a lightweight AngularJS built on top of Malihu’s scrollbars.
</p>
<p><a href="http://iominh.github.io/ng-scrollbars/"><button class="btn red">Open Demo</button><a></a></a></p>
<h1 id="background">Background</h1>
<p>Initially, I tried to style the scrollbars using CSS but discovered that
Chrome wasn’t accepting my mouse hover styling (which is apparently a bug in Chrome) and Firefox
didn’t accept any styling at all. Another requirement I had was that I needed a library that worked with Angular.</p>
<p>So, after some research, I found the following libraries:</p>
<ul>
<li><a href="https://github.com/asafdav/ng-scrollbar">Ng-scrollbar</a></li>
<li><a href="https://github.com/itsdrewmiller/angular-perfect-scrollbar">Angular-perfect-scrollbar</a></li>
<li><a href="https://github.com/yads/ngTinyScrollbar">ngTinyScrollbar</a></li>
<li><a href="https://github.com/jkuri/ngSlimscroll">ngSlimscroll</a></li>
</ul>
<p>Unfortunately some of these libraries didn’t have builtin styling that immediately worked well with
my dark themed app. However, I found <a href="http://manos.malihu.gr/jquery-custom-content-scroller/">Malihu’s custom content scrollbar by Manos Malihutsakis</a>,
which looked great and came with lots of built-in themes. The only problem was that it’s written in jQuery, so
over the past day or so I wrote a directive that wraps it and makes it more easily usable in AngularJS.</p>
<p>Without further adieu, check out the <a href="http://iominh.github.io/ng-scrollbars/">demo page here</a> and
the <a href="https://github.com/iominh/ng-scrollbars">GitHub repo here</a>. Tentatively I’ve named it
ng-scrollbars.</p>
<p>Although the actual directive and provider wrapper code is very light, I learned a lot about publishing
apps to Bower and setting up project pages on GitHub Pages, so hopefully it’ll be easier to
publish more open source in the future.</p>
<p>Hopefully this helps someone out there</p>
</section>
Jersey 2 on JBoss 72014-10-27T00:00:00+00:00https://www.minh.io/tech/2014/10/27/jersey-2-on-jboss-7<section class="container">
<p class="drop-cap">
I received an email asking how I deployed Jersey 2 on JBoss 7 (specifically 7.1.1) while still being able to
access Jersey resources (<a href="http://stackoverflow.com/questions/21173397/jersey-2-on-jboss-7">see my Stackoverflow post here</a>).
The solution that worked for me was to add a jboss-deployment-structure.xml in my
app’s WEB-INF directory and manually register Jersey resources rather than rely on automatic package scanning:</p>
<p><br /> <br />
Here’s the jboss-deployment-structure.xml:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="nt"><jboss-deployment-structure></span>
<span class="nt"><deployment></span>
<span class="nt"><exclusions></span>
<span class="c"><!-- Exclude RestEasy conflict --></span>
<span class="nt"><module</span> <span class="na">name=</span><span class="s">"javaee.api"</span> <span class="nt">/></span>
<span class="nt"><module</span> <span class="na">name=</span><span class="s">"javax.ws.rs.api"</span><span class="nt">/></span>
<span class="nt"><module</span> <span class="na">name=</span><span class="s">"org.jboss.resteasy.resteasy-jaxrs"</span> <span class="nt">/></span>
<span class="nt"></exclusions></span>
<span class="nt"></deployment></span>
<span class="nt"></jboss-deployment-structure></span></code></pre></figure>
<p>Here’s a simplified web.xml:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><web-app></span>
<span class="nt"><display-name></span>WebApp<span class="nt"></display-name></span>
<span class="nt"><servlet></span>
<span class="nt"><servlet-name></span>WebApp<span class="nt"></servlet-name></span>
<span class="nt"><servlet-class></span>org.glassfish.jersey.servlet.ServletContainer<span class="nt"></servlet-class></span>
<span class="c"><!-- This doesn't work in JBoss7 --></span>
<span class="c"><!--<init-param>--></span>
<span class="c"><!--<param-name>jersey.config.server.provider.packages</param-name>--></span>
<span class="c"><!--<param-value>io.minh.resources</param-value>--></span>
<span class="c"><!--</init-param>--></span>
<span class="nt"><init-param></span>
<span class="nt"><param-name></span>javax.ws.rs.Application<span class="nt"></param-name></span>
<span class="nt"><param-value></span>io.minh.ApplicationConfig<span class="nt"></param-value></span>
<span class="nt"></init-param></span>
<span class="nt"><load-on-startup></span>1<span class="nt"></load-on-startup></span>
<span class="nt"></servlet></span>
<span class="nt"><servlet-mapping></span>
<span class="nt"><servlet-name></span>WebApp<span class="nt"></servlet-name></span>
<span class="nt"><url-pattern></span>/rest/*<span class="nt"></url-pattern></span>
<span class="nt"></servlet-mapping></span>
<span class="nt"><context-param></span>
<span class="nt"><param-name></span>resteasy.scan<span class="nt"></param-name></span>
<span class="nt"><param-value></span>false<span class="nt"></param-value></span>
<span class="nt"></context-param></span>
<span class="nt"><context-param></span>
<span class="nt"><param-name></span>resteasy.scan.providers<span class="nt"></param-name></span>
<span class="nt"><param-value></span>false<span class="nt"></param-value></span>
<span class="nt"></context-param></span>
<span class="nt"><context-param></span>
<span class="nt"><param-name></span>resteasy.scan.resources<span class="nt"></param-name></span>
<span class="nt"><param-value></span>false<span class="nt"></param-value></span>
<span class="nt"></context-param></span>
<span class="nt"><welcome-file-list></span>
<span class="nt"><welcome-file></span>index.htm<span class="nt"></welcome-file></span>
<span class="nt"></welcome-file-list></span>
<span class="nt"></web-app></span></code></pre></figure>
<p><br />
Here’s an implementation of the <a href="https://jersey.java.net/apidocs/2.0/jersey/org/glassfish/jersey/server/ResourceConfig.html">javax.ws.rs.Application / ResourceConfig</a>
referenced in the web.xml above, where each Jersey resource needs to be manually registered (there’s probably a way
to make this work automatically, but as shown below the automatic package scanning wasn’t working in JBoss…):</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="n">io</span><span class="o">.</span><span class="na">minh</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.glassfish.jersey.server.ResourceConfig</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ApplicationConfig</span> <span class="kd">extends</span> <span class="n">ResourceConfig</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">ApplicationConfig</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// package scanning doesn't work in Jboss for some reason</span>
<span class="c1">// packages( true, "io.minh" );</span>
<span class="n">register</span><span class="o">(</span><span class="n">SomeResource</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><br />
Lastly, here’s the Jersey library I used in my Maven pom.xml:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.glassfish.jersey.containers<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>jersey-container-servlet<span class="nt"></artifactId></span>
<span class="nt"><version></span>2.5<span class="nt"></version></span>
<span class="nt"></dependency></span></code></pre></figure>
</section>
Gulp command not found2014-06-01T00:00:00+00:00https://www.minh.io/tech/2014/06/01/gulp-command-not-found<section class="container">
<p class="drop-cap">
The other day I was trying out Gulp (normally I use Grunt) but after running 'npm install -g gulp' everything seemed
to install fine except I got a 'gulp command not found' error after trying to run 'gulp'</p>
<p>So, after looking around on the net, I came across a couple of posts (<a href="http://webbb.be/blog/command-not-found-node-npm/">post1</a>,
<a href="http://travismaynard.com/writing/getting-started-with-gulp">post2</a>) that helped me identify the issue: essentially my
global NPM modules were being installed to the wrong location and couldn’t be accessed on my PATH. For some context,
I’m running Node v0.10.26 with NPM 1.3.23 on OSX 10.9.2.</p>
<p>The following OSX terminal commands helped me narrow down the issue:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># identifies the directory where NPM is installed.</span>
<span class="c"># e.g. /Users/username/.nvm/v0.10.22/bin/npm or /usr/local/bin/npm</span>
which npm
<span class="c"># prints the current project's node_modules</span>
npm root
<span class="c"># prints the location of the global node_modules.</span>
<span class="c"># this was my issue since it showed /usr/local/bin/npm</span>
<span class="c"># but my NPM was installed elsewhere</span>
npm root -g
<span class="c"># so, I modified the config prefix to be something like:</span>
npm config <span class="nb">set </span>prefix /Users/username/.nvm/v0.10.22
<span class="c"># alternatively, /usr/local would work for normal NPM install locations</span>
<span class="c"># finally I reinstalled gulp and it was accessible on the command line. hooray!</span>
npm install -g gulp</code></pre></figure>
</section>
Running Meteor Forever2013-12-01T00:00:00+00:00https://www.minh.io/tech/2013/12/01/running-meteor-forever<section class="container">
<p class="drop-cap">Recently I’ve decided to learn <a href="http://www.meteor.com/">Meteor JS</a>, which is an “open-source platform for building top-quality web apps in a fraction of the time.”
It’s super fast (i.e. great for hackathons) to get an application up and running. I’ve only been using Meteor for a couple of days
but love it so far and possibly will consider using it instead of my current favorite <a href="http://www.playframework.com/">Play Framework</a>.
</p>
<p>One issue I encountered when deploying my application to production was that once I started the app on my
server using “meteor &” I noticed the application would die after I exited the terminal. This is actually a common
“issue” in the NodeJS world and many posts have suggested the use of the <a href="https://npmjs.org/package/forever">NPM Forever</a> tool
for running a Meteor bundle even when you exit the terminal session. One <a href="http://stackoverflow.com/questions/14529677/what-is-the-proper-syntax-for-running-a-meteor-generated-node-bundle-using-forev">StackOverflow post</a>
showed the following commands:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">export </span><span class="nv">MONGO_URL</span><span class="o">=</span>mongodb://localhost:27017/<dbname>
<span class="nb">export </span><span class="nv">PORT</span><span class="o">=</span><server_port>
<span class="nb">export </span><span class="nv">ROOT_URL</span><span class="o">=</span>http://sub.example.com/
forever start bundle/main.js</code></pre></figure>
<p>Unfortunately this didn’t work for me but bsilvereagle from the Meteor IRC channel suggested I
create a <a href="http://tmux.sourceforge.net/">tmux</a> session, start my Meteor server in it, and detach
the session. So, you would roughly run the following commands:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">tmux
<span class="c"># a new tmux session will be created and you'll notice a green bar at the bottom of the terminal</span>
<span class="c"># start your Meteor app: (e.g. "meteor &amp;")</span>
<span class="c"># press CLTR and B, :, and "detach" to detach the session</span>
<span class="c"># Type "tmux list-sessions" to see the session you just created </span>
<span class="c"># You can join your session by typing "tmux attach-session -t <number>"</span></code></pre></figure>
<p>Now Meteor will run even if I exit from my terminal. Yay!</p>
<p>Hopefully this helps someone out there but here’s a couple more tmux resources:</p>
<ul>
<li><a href="http://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session">Ubuntu post</a></li>
<li><a href="http://www.dayid.org/os/notes/tm.html">tmux commands</a></li>
</ul>
</section>
6 Startup Tips2013-11-25T00:00:00+00:00https://www.minh.io/tech/2013/11/25/10-startup-tips<section class="container">
<p class="drop-cap">Lately I’ve been obsessed with learning as much as I can about startups and business. As such, I came across
a fantastic video from Google I/O 2011 titled: <a href="http://www.youtube.com/watch?v=15iWltPLuPY">How to Get Your Startup Idea Funded by Venture Capitalists</a>.
It’s a great ~1 hour talk with a panel including a venture capitalist from YC, a VC from Google Ventures, and a recent founder
who raised funding. Here are the primary tips:
</p>
<h2 id="eliminate-distractions">Eliminate distractions</h2>
<p>An audience member asked how he should find motivation and a panelist gave unorthodox but brilliant advice: find motivation
by making everything else less interesting. Personally I’ve found this works really well. For instance, I used to play
video games quite a bit but I’ve cut back, which gives me time to work on my ideas and projects.</p>
<h2 id="focus-on-an-idea-youre-passionate-about">Focus on an idea you’re passionate about</h2>
<p>One member of the audience mentioned he was an “idea factory” and didn’t know how to select an idea. The panel advised
him to select an idea he would be excited to work on after waking up every morning for 5+ years.</p>
<p>Another panelist even mentioned that “idea factory” founders are not ideal personalities for entrepreneurship since
VCs look for people with focus; he suggested this person should find a cofounder to provide balance. This conflicted
a bit with <a href="http://www.youtube.com/watch?v=rWKUoabjjxg">Mark Zuckerburg’s talk at Startup School 2011</a> when he advised startups
to experiment and do things differently; echoing Facebook’s famous “move fast and break things” philosophy.</p>
<p>Personally I love change and believe that “idea factory” personalities are essential for innovation. However, I can see how
this may be a turn off for VCs especially if a company has too many unfocused, unspecialized products. For example, Apple
has had great success with its very high quality, yet focused product lines.</p>
<p>Overall, maybe the lesson is that there should be balance between focus and exploring ideas but the end result needs to
be a great focused product.</p>
<h2 id="try-to-have-2-3-cofounders">Try to have 2-3 cofounders</h2>
<p>VCs like to see more than one founder because it shows validation of an idea, especially when a founder can convince
another person to leave their job and join them. There has been data showing that 2-3 cofounders are the ideal size; there
isn’t enough data for teams > 3 and solo founders are rare.</p>
<h2 id="have-multiple-offers">Have multiple offers</h2>
<p>An audience member asked how a startup should be valued. One VC panelist mentioned that there are valuations
based on numerous metrics but generally if a number is pitched by the founder it creates an anchor / floor valuation; even
better: if a startup has other VCs interested in it, VCs tend to be more afraid of missing out on great deals than
possibly overpaying.</p>
<p>However, a VC also cautioned that if an initial VC does not do a follow-up round then it can be a red flag.</p>
<h2 id="find-balance">Find balance</h2>
<p>This is a theme I’ve heard over and over. Startups can be exhausting and it’s easy to forget about diet, health,
relationships, other interests, etc. I’ve often heard that you can only select a startup and one of the other categories.
One takeway is never to let your startup dominate your life such that you risk your future health.</p>
<h3 id="dont-create-a-business-plan">Don’t create a business plan</h3>
<p>Apparently VCs from Y combinator and Google Ventures don’t really care about business plans because they generally are
not useful for unpredictable tech companies. Instead they care more about users, traction, passion, and the team.</p>
</section>
ThreadWeaver Race Conditions2013-08-24T00:00:00+00:00https://www.minh.io/tech/2013/08/24/race-conditions-in-java-with-threadweaver<section class="container">
<p class="drop-cap">
Writing code to test race conditions is tough. Recently I looked at
<a href="https://code.google.com/p/thread-weaver/">ThreadWeaver</a>, which is a framework
that <a href="https://code.google.com/u/alasdair.mackintosh/">Alasdair Mackintosh</a> wrote for writing
multi-threaded unit tests in Java. I liked how it allows you to write
deterministic code where you can control the exact sequence/interweaving of operations between
threads. In other words, it allows you to precisely create and test a race condition.
</p>
<p>The only downside to the framework was that it used Ant. This meant it took
a little bit of extra work to set up since I had to download the jars
and figure out the project structure. Considering all of this,
I took some time to “Mavenize” the project and put a version
on <a href="https://github.com/iominh/ThreadWeaver">Github</a>.
I’m currently working with another developer to possibly publish 0.20 to
Maven Central.</p>
<p>Other issues I encountered were “no object instrumented” and
“class not instrumented” errors. After posting a question to the mailing list,
the author responded almost immediately and I <a href="https://groups.google.com/forum/#!topic/thread-weaver/3BS74oiB9Yc">resolved the issue</a> by
placing my ThreadWeaver “Scripts” code within the ThreadWeaver annotations
like @ThreadMain, etc.</p>
<p>Open source is awesome :).</p>
</section>
Highlight.js Line Numbers2013-08-17T00:00:00+00:00https://www.minh.io/tech/2013/08/17/highlightjs-line-numbers<section class="container">
<p class="drop-cap">In this post I will show how to add line numbers with syntax highlighting
provided through <a href="http://softwaremaniacs.org/soft/highlight/en/" target="_blank">Highlight.js</a>.
I decided to give this a whirl after getting a <a href="/tech/2013/06/23/highlightjs-vs-syntaxhighlighter/">comment</a> from the author
<a href="https://github.com/isagalaev" target="_blank">Ivan Sagalaev</a> describing
how Highlight.js supports line numbers on an <a href="https://github.com/isagalaev/highlight.js/compare/line-numbers">experimental code branch</a>
(line numbers are actually <a href="http://highlightjs.readthedocs.org/en/latest/line-numbers.html">not included as a feature</a>).
Hmm, I thought nobody read my random posts but I guess not :).
</p>
<h3 id="changelog">Changelog</h3>
<ul>
<li>7/1/15: I’ve changed syntax highlighters to Rouge, which is currently in use on this page, so see the following
<a href="http://design7.minh.io/tech/2013/08/17/highlightjs-line-numbers/">version</a> to see line numbers with highlightjs.</li>
</ul>
<h3 id="examples">Examples</h3>
<p>So, without further ado, here’s code with line numbers:</p>
<figure class="lineno-container">
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre><span class="kd">function</span> <span class="nx">fibonacci</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">n</span> <span class="o"><=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">fibonacci</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nx">fibonacci</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></figure>
</figure>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">function</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">n</span> <span class="o"><=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>This is just an initial attempt but I’m actually quite happy with
how it turned out, especially since I can copy the text and not have
it also copy the numbers.</p>
<h2 id="details">Details</h2>
<p>So how does this work? Well, from looking at Ivan’s branch, it appeared that
the line numbers were set through a global variable. Instead, I figured that
sometimes you may want line numbers and other times you may not, so I rewrote
the code to detect for a classname called “lineNumbers” and if it detects
that class then it applies line numbering.</p>
<p>For example, if I want code without line numbering I write my HTML like:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><pre></span>
<span class="nt"><code</span> <span class="na">class=</span><span class="s">"java"</span><span class="nt">></span>
System.out.println("hello");
<span class="nt"></code></span>
<span class="nt"></pre></span></code></pre></figure>
<p>Otherwise, if I do want line numbering, I just add a “lineNumbers” class:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><pre></span>
<span class="nt"><code</span> <span class="na">class=</span><span class="s">"java lineNumbers"</span><span class="nt">></span>
System.out.println("hello");
<span class="nt"></code></span>
<span class="nt"></pre></span></code></pre></figure>
<h2 id="github-fork">Github Fork</h2>
<p>If you’re interested in having this for your site, I forked the Highlight.js 7.3
code and added the changes at <a href="https://github.com/iominh/highlight.js">https://github.com/iominh/highlight.js</a>.</p>
<p>A couple of tips to build the JS library:</p>
<ul>
<li>Make sure you have Python3 installed so you can run “python3 tools/build.py.”
Initially I encountered errors building with Python2.</li>
<li>By default, the build creates a highlight.js that supports lots of languages,
which makes it somewhat heavy at 122KB+. I personally just used “python3 tools/build.py :common”
to support the most popular languages.</li>
<li>The highlight.js is produced in the build directory.</li>
<li>Run “python3 tools/build.py -h” if you need further help and of course visit
the highlight.js site for official documentation.</li>
</ul>
<p>You should review the changes described at <a href="https://github.com/isagalaev/highlight.js/compare/line-numbers">https://github.com/isagalaev/highlight.js/compare/line-numbers</a> and in particular the CSS that you will need to add.</p>
<section>
</section>
</section>
Highlight.js vs SyntaxHighlighter2013-06-23T00:00:00+00:00https://www.minh.io/tech/2013/06/23/highlightjs-vs-syntaxhighlighter<section class="container">
<p class="drop-cap">In this post I want to compare two syntax highlighters: <a href="http://softwaremaniacs.org/soft/highlight/en/" target="_blank">Highlight.js</a> and <a href="http://alexgorbatchev.com/SyntaxHighlighter/" target="_blank">Syntax Highlighter</a>.
For whatever reason I cannot understand at the moment, even though I already had Highlight.js in
my blog I decided to try out <a href="http://alexgorbatchev.com/SyntaxHighlighter/" target="_blank">Syntax Highlighter</a>,
which is another nice looking code highlighter.
</p>
<p>Maybe it was because I wanted to change
things after I stumbled across the builtin syntax highlighting in <a href="http://octopress.org/docs/blogging/code/" target="_blank">Octopress</a>
or another great application of the <a href="http://ethanschoonover.com/solarized" target="_blank">Solarized</a> syntax highlighter at <a href="http://thanpol.as/jekyll/jekyll-code-highlight-and-line-numbers-problem-solved/" target="_blank">Thanpol.as</a>. Perhaps it was because it was late at night and I didn’t realize I could change from
the default highlight.js theme to its Solarized theme.</p>
<p>Nonetheless, I switched from HighlightJS to SyntaxHighlighter <a href="http://design3.minh.io/tech/2013/05/13/maven3-on-ubuntu-1304/" target="_blank">briefly</a> but decided to switch back because:</p>
<h3 id="changelog">Changelog</h3>
<ul>
<li>7/12/15: I’m using Rouge now, so this page is out of date</li>
<li>2/1/14: I’ve <a href="/tech/2014/01/30/prettyprint-syntax-highlighting/">changed syntax highlighters</a>, so see
<a href="http://design7.minh.io/tech/2013/06/23/highlightjs-vs-syntaxhighlighter/">this version</a>, which uses Highlight.js</li>
<li>8/17/13: <a href="/tech/2013/08/17/highlightjs-line-numbers/">I figured out the line numbers</a>.</li>
</ul>
<h3 id="syntax-highlighter-requires-more-imports">Syntax Highlighter requires more imports</h3>
<p>You need to import lots of different brushes for different languages. Highlight.js only has 2 imports and you can even use a CDN like Yandex so it’s really only
a couple lines to start using it.</p>
<h3 id="syntax-highlighter-is-noticeably-slower">Syntax Highlighter is noticeably slower</h3>
<p>For whatever reason, despite my best efforts, Syntax Highlighter always
seems to take a moment after loading the page before it applies styling, which
means that a user will briefly see the unhighlighted code. I noticed this
both in official examples as well as other sites.</p>
<p>Highlight.js, however, worked out of the box and I didn’t notice anything similar.</p>
<h3 id="highlightjs-solarized-theme-is-brilliant">Highlight.js’ Solarized theme is brilliant</h3>
<div class="highlight-solarized-dark">
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Float</span>
<span class="k">def</span> <span class="nf">number_decimal_places</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">length</span><span class="o">-</span><span class="mi">2</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">to_fraction</span>
<span class="n">higher</span> <span class="o">=</span> <span class="mi">10</span><span class="o">**</span><span class="nb">self</span><span class="p">.</span><span class="nf">number_decimal_places</span>
<span class="n">lower</span> <span class="o">=</span> <span class="nb">self</span><span class="o">*</span><span class="n">higher</span>
<span class="n">gcden</span> <span class="o">=</span> <span class="n">greatest_common_divisor</span><span class="p">(</span><span class="n">higher</span><span class="p">,</span> <span class="n">lower</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">lower</span><span class="o">/</span><span class="n">gcden</span><span class="p">).</span><span class="nf">round</span><span class="p">,</span> <span class="p">(</span><span class="n">higher</span><span class="o">/</span><span class="n">gcden</span><span class="p">).</span><span class="nf">round</span>
<span class="k">end</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">greatest_common_divisor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
<span class="k">while</span> <span class="n">a</span><span class="o">%</span><span class="n">b</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">.</span><span class="nf">round</span><span class="p">,(</span><span class="n">a</span><span class="o">%</span><span class="n">b</span><span class="p">).</span><span class="nf">round</span>
<span class="k">end</span>
<span class="k">return</span> <span class="n">b</span>
<span class="k">end</span>
<span class="k">end</span></code></pre></figure>
</div>
<p>Next up, I’ll work on figuring out how to add line numbers…</p>
</section>
Subdomains with Linode and Nginx2013-05-20T00:00:00+00:00https://www.minh.io/tech/2013/05/20/subdomains-with-linode-and-nginx<section class="container">
<p class="drop-cap">
This post will show how I created subdomains on my Linode box with Nginx. Although I’m using Linode and Nginx as a
reference, I assume this could be generalized with other types of domains and web servers.
Take a look at one my subdomains at <a href="https://doc1.minh.io/" title="dev1.minh.io">https://doc1.minh.io</a>.
Listed below are the steps I took to get that to work:
</p>
<h3 id="log-into-linode-and-add-an-aaaaa-record">1. Log into Linode and add an A/AAAA record</h3>
<ul>
<li>Log into the Linode Manager</li>
<li>Under A/AAAA Records, take note of the hostname IP address and click Add a new A record</li>
<li>Set the IP address, TTL, and hostname to be the subdomain name:</li>
</ul>
<table class="table">
<tr>
<td>Hostname</td>
<td>IP Address</td>
<td>TTL</td>
</tr>
<tr>
<td>dev</td>
<td>10.10.10.10</td>
<td>Default</td>
</tr>
</table>
<p>One issue I encountered was that my Domain Zone was “www.minh.io” when
I needed it to be “minh.io” so I cloned “www.minh.io” to “minh.io” and deleted
“www.minh.io.” This solved an issue where I couldn’t access “minh.io”
and also my subdomain was “dev.www.minh.io” when it should’ve just been “dev.minh.io”</p>
<p>Also keep in mind that it takes a couple of minutes for the subdomain DNS changes to propagate across
the internet. I initially had some trouble figuring this out and kept trying
new changes until eventualy I saw the subdomain.</p>
<h3 id="update-the-nginx-server-configuration">2. Update the Nginx server configuration</h3>
<p>It depends on how your nginx is set up, but typically Nginx is installed to /etc/nginx/ and the
Nginx configuration in /etc/nginx/nginx.conf usually has ‘include /etc/nginx/sites-enabled/*;’</p>
<p>So, if you have server configuration like “mysite.io” in /etc/nginx/sites-enabled then you could
modify it like the following example:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">server <span class="o">{</span>
listen 80;
server_name mysite.io;
location / <span class="o">{</span>
root /srv/www/mysite.io/public_html/static;
<span class="o">}</span>
<span class="o">}</span>
server <span class="o">{</span>
listen 80;
server_name sub.mysite.io;
location / <span class="o">{</span>
root /srv/www/mysite.io/public_html/static;
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>Lastly, don’t forget to restart Nginx (service nginx restart) and you should see the subdomain after
<a href="https://www.linode.com/docs/networking/dns/dns-manager">~30 minutes</a>.</p>
</section>