Tom Norian Site Services 2019-06-05T12:35:58-07:00 http://tomnorian.com Tom Norian tomnorian@gmail.com React Serverless Get Started 2017-10-16T00:00:00-07:00 http://tomnorian.com/React-Serverless-Get-Started <p>Get a quick start on a ReactJS static, serverless site by cloning my git Repo.</p> <p>This starter pack uses Webpack and Babel to compile bundled files into a public directory that can be placed on any cheap server or website enabled S3 bucket.</p> <p>To make it better I’ve got all the settings to use SASS with ReactJS, and a Bootstrap Navbar to have a really nice “Hello World” up in no time.</p> <p>This is not a ReactJS or webpack tutorial … just look at it as a “cheat-sheet for Webpack and ReactJS site launched using SASS and Bootstrap for compiled CSS creation”</p> <p><strong>What I’m Sharing:</strong></p> <ul> <li>a git repo to clone for a basic React site.</li> <li>NPM commands necessary to load the Node dependencies</li> <li>Package.json and wepback examples are also included in this post itself.</li> </ul> <p>Ok, let’s get started !</p> <p>demo: <a class="markdown-external-link" target="_blank" href="http://rankarooski.com/react/index.html">check out the live demo</a></p> <p>GitHub repo: <a class="markdown-external-link" target="_blank" href="https://github.com/Tom2277/ReactStaticSiteStarter">ReactStaticSiteStarter GitHub repository</a>.</p> <p>Download the zip file for the repo above (or clone it at your preference) … then …</p> <p><code class="highlighter-rouge">npm i webpack@3.4.0 -D</code></p> <p><code class="highlighter-rouge">npm i babel-core@6 babel-loader@6 babel-preset-react@6 -D</code></p> <!--more--> <p><code class="highlighter-rouge">npm i react@15 react-dom@15 -D</code></p> <p><code class="highlighter-rouge">npm i css-loader node-sass sass-loader extract-text-webpack-plugin -D</code></p> <p>Check the package.json below to be sure !</p> <h3 id="look-only-dev-dependencies">LOOK! Only Dev dependencies!?</h3> <p>Yep - all the React code gets compiled into a js file</p> <p>.. the SASS gets turned into simple CSS. You might want to use a small subsection of Bootstrap or another libary which you can include within the ‘src/css’ folder. The files will get treated correctly depending on whether they have a .scss or .css extension.</p> <p>Create a basic HTML index file in the PUBLIC folder.</p> <p>NOTE: I am using CDNs for Bootstrap and JQuery - This index.html is in the Repo already.</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="cp">&lt;!DOCTYPE html&gt;</span> <span class="nt">&lt;html&gt;</span> <span class="nt">&lt;head&gt;</span> <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://code.jquery.com/jquery-3.2.1.min.js"</span> <span class="na">integrity=</span><span class="s">"sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;link</span> <span class="na">href=</span><span class="s">"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">integrity=</span><span class="s">"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;</span> <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"</span> <span class="na">integrity=</span><span class="s">"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;title&gt;</span>Tom's React Starter Kit<span class="nt">&lt;/title&gt;</span> <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/bundle.css"</span><span class="nt">&gt;</span> <span class="nt">&lt;/head&gt;</span> <span class="nt">&lt;body&gt;</span> <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"content"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"js/bundle.js"</span><span class="nt">&gt;</span> <span class="nt">&lt;/script&gt;</span> <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"</span> <span class="na">integrity=</span><span class="s">"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;/body&gt;</span> <span class="nt">&lt;/html&gt;</span> </code></pre> </div> <p>All of the JSX is in the jsx folder inside the src folder. (yes this project also uses the JSX choice of syntax DSL with React)</p> <p>Again, this is not a tutorial, but syntax can be tricky.</p> <p>Here is how I configured my Webpack file to compile only the needed code into the public file.</p> <div class="language-javascript highlighter-rouge"><pre class="highlight"><code><span class="c1">// webpack.config.js</span> <span class="kd">var</span> <span class="nx">ExtractTextPlugin</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'extract-text-webpack-plugin'</span><span class="p">);</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span> <span class="na">entry</span><span class="p">:</span> <span class="p">[</span><span class="s1">'./src/jsx/app.jsx'</span><span class="p">,</span> <span class="s1">'./src/css/custom.css'</span><span class="p">,</span> <span class="s1">'./src/css/main.scss'</span><span class="p">,],</span> <span class="na">output</span><span class="p">:</span> <span class="p">{</span> <span class="na">path</span><span class="p">:</span> <span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">'/public/js/'</span><span class="p">,</span> <span class="na">filename</span><span class="p">:</span> <span class="s1">'bundle.js'</span> <span class="p">},</span> <span class="na">module</span><span class="p">:</span> <span class="p">{</span> <span class="na">loaders</span><span class="p">:</span> <span class="p">[</span> <span class="p">{</span> <span class="na">test</span><span class="p">:</span> <span class="sr">/</span><span class="se">\.</span><span class="sr">jsx</span><span class="se">?</span><span class="sr">$/</span><span class="p">,</span> <span class="na">exclude</span><span class="p">:</span> <span class="sr">/</span><span class="se">(</span><span class="sr">node_modules</span><span class="se">)</span><span class="sr">/</span><span class="p">,</span> <span class="na">loaders</span><span class="p">:</span> <span class="p">[</span><span class="s1">'babel-loader'</span><span class="p">]</span> <span class="p">},</span> <span class="p">{</span> <span class="na">test</span><span class="p">:</span> <span class="sr">/</span><span class="se">\.</span><span class="sr">css$/</span><span class="p">,</span> <span class="na">loader</span><span class="p">:</span> <span class="nx">ExtractTextPlugin</span><span class="p">.</span><span class="nx">extract</span><span class="p">([</span><span class="s1">'css-loader'</span><span class="p">]),</span> <span class="p">},</span> <span class="p">{</span> <span class="na">test</span><span class="p">:</span> <span class="sr">/</span><span class="se">\.(</span><span class="sr">sass|scss</span><span class="se">)</span><span class="sr">$/</span><span class="p">,</span> <span class="na">loader</span><span class="p">:</span> <span class="nx">ExtractTextPlugin</span><span class="p">.</span><span class="nx">extract</span><span class="p">([</span><span class="s1">'css-loader'</span><span class="p">,</span> <span class="s1">'sass-loader'</span><span class="p">])</span> <span class="p">}</span> <span class="p">]</span> <span class="p">},</span> <span class="na">plugins</span><span class="p">:</span> <span class="p">[</span> <span class="k">new</span> <span class="nx">ExtractTextPlugin</span><span class="p">({</span> <span class="na">filename</span><span class="p">:</span> <span class="s1">'../css/bundle.css'</span><span class="p">,</span> <span class="na">allChunks</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="p">})</span> <span class="p">]</span> <span class="p">}</span> </code></pre> </div> <p>This excellent article: <a class="markdown-external-link" target="_blank" href="https://jonathanmh.com/webpack-sass-scss-compiling-separate-file/">great reference to enable SASS with webpack</a> got me most of the way.</p> <p>There were some changes you see in my file that differ from his. (things are always changing ! :) )</p> <p>For good measure here is what your final package.json should look like. If we missed any dependencies go and fetch them with <code class="highlighter-rouge">npm i modulename -D</code></p> <div class="language-js highlighter-rouge"><pre class="highlight"><code><span class="c1">// package.json</span> <span class="p">{</span> <span class="s2">"name"</span><span class="err">:</span> <span class="s2">"ReactWithSassQuickStart"</span><span class="p">,</span> <span class="s2">"version"</span><span class="err">:</span> <span class="s2">"1.0.0"</span><span class="p">,</span> <span class="s2">"description"</span><span class="err">:</span> <span class="s2">"This is a starter kit to create a static ReactJS website with Sass, Bootstrap with Navbar"</span><span class="p">,</span> <span class="s2">"main"</span><span class="err">:</span> <span class="s2">"index.js"</span><span class="p">,</span> <span class="s2">"scripts"</span><span class="err">:</span> <span class="p">{</span> <span class="s2">"build"</span><span class="err">:</span> <span class="s2">"./node_modules/.bin/webpack"</span><span class="p">,</span> <span class="s2">"build-watch"</span><span class="err">:</span> <span class="s2">"./node_modules/.bin/webpack -w"</span> <span class="p">},</span> <span class="s2">"author"</span><span class="err">:</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"license"</span><span class="err">:</span> <span class="s2">"ISC"</span><span class="p">,</span> <span class="s2">"babel"</span><span class="err">:</span> <span class="p">{</span> <span class="s2">"presets"</span><span class="err">:</span> <span class="p">[</span> <span class="s2">"react"</span> <span class="p">]</span> <span class="p">},</span> <span class="s2">"devDependencies"</span><span class="err">:</span> <span class="p">{</span> <span class="s2">"babel-core"</span><span class="err">:</span> <span class="s2">"^6.26.0"</span><span class="p">,</span> <span class="s2">"babel-loader"</span><span class="err">:</span> <span class="s2">"^6.4.1"</span><span class="p">,</span> <span class="s2">"babel-preset-react"</span><span class="err">:</span> <span class="s2">"^6.24.1"</span><span class="p">,</span> <span class="s2">"css-loader"</span><span class="err">:</span> <span class="s2">"^0.28.7"</span><span class="p">,</span> <span class="s2">"extract-text-webpack-plugin"</span><span class="err">:</span> <span class="s2">"^3.0.1"</span><span class="p">,</span> <span class="s2">"node-sass"</span><span class="err">:</span> <span class="s2">"^4.5.3"</span><span class="p">,</span> <span class="s2">"react"</span><span class="err">:</span> <span class="s2">"^15.6.2"</span><span class="p">,</span> <span class="s2">"react-dom"</span><span class="err">:</span> <span class="s2">"^15.6.2"</span><span class="p">,</span> <span class="s2">"sass-loader"</span><span class="err">:</span> <span class="s2">"^6.0.6"</span><span class="p">,</span> <span class="s2">"style-loader"</span><span class="err">:</span> <span class="s2">"^0.19.0"</span><span class="p">,</span> <span class="s2">"webpack"</span><span class="err">:</span> <span class="s2">"^3.4.0"</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <p>Again, here is the demo: <a class="markdown-external-link" target="_blank" href="http://rankarooski.com/react/index.html">check out the live demo</a></p> <p>And here is the GitHub repo: <a class="markdown-external-link" target="_blank" href="https://github.com/Tom2277/ReactStaticSiteStarter">ReactStaticSiteStarter GitHub repository</a>.</p> <h3 id="now-compile-and-deploy">Now, Compile and Deploy!</h3> <p>Simply run the script to see that it looks right on your local machine.</p> <p>(the script is defined within the package.json file shown above)</p> <p><code class="highlighter-rouge">root[master]&gt;npm run build-watch</code></p> <p>I serve it using the the node ‘static’ tool (install that globally: npm i static -g ) by typing</p> <p><code class="highlighter-rouge">npm i static -g</code></p> <p><code class="highlighter-rouge">public[master]&gt; static</code></p> <p>Take a look in your web browser at : http://127.0.0.1:8080/#</p> <p>If it looks good, use your favorite server SCP tool or method to push the entire contents of your Public folder - including the ‘css’, ‘js’ and ‘images’ folders which now have compiled versions of your js and css files within them.</p> <p>Presto.. you should be in action just like on the live demo page above.</p> <p>As always, let me know anything I missed with comments and suggestions!</p> All The Named Colors Css 2017-03-13T00:00:00-07:00 http://tomnorian.com/All-The-Named-Colors-CSS <p>How many named colors are there on the web? Well, that is a complicated question that can be answered in the <a class="markdown-external-link" target="_blank" href="https://en.wikipedia.org/wiki/Web_colors">continually updated Wikipedia article on Web Colors</a> .</p> <p>Not all browsers support all colors and while the effective number of colors has grown, the list of named CSS colors I found that almost all browsers supported was about 140… I have 138 below I believe. The are other standards with multiple numbered shades of given colors would add up to a greater number. Again, you can read about it all at Wikipedia.</p> <p>Would you like an array of all named the CSS colors widely accepted on all browsers? Named colors with their both their hexadecimal and their RGB codes available by index ?</p> <p>Here is one…free of charge…all typed up and grouped in a rough way. I have them displayed below that and you can hover for the color name.</p> <p>Do you like guessing colors? Try a <a class="markdown-external-link" target="_blank" href="http://huecolorgame.com">color game</a> that I made right after BootCamp.</p> <p>I hand formatted this array a couple years ago before I knew what I was doing. I probably would have made them objects if I had it to do again but, as Tim Gunn says, if you need something like this quickly you can “make it work”.</p> <div class="language-javascript highlighter-rouge"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">colors</span> <span class="o">=</span> <span class="p">[</span> <span class="p">[</span><span class="s2">"maroon"</span><span class="p">,</span> <span class="s2">"#800000"</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkred"</span><span class="p">,</span> <span class="s2">"#8B0000"</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"firebrick"</span><span class="p">,</span> <span class="s1">'#B22222'</span><span class="p">,</span> <span class="mi">178</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">34</span><span class="p">],</span> <span class="p">[</span><span class="s2">"crimson"</span><span class="p">,</span> <span class="s2">"#DC143C"</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">60</span><span class="p">],</span> <span class="p">[</span><span class="s2">"red"</span><span class="p">,</span> <span class="s2">"#FF0000"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"tomato"</span><span class="p">,</span> <span class="s2">"#FF6347"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">71</span><span class="p">],</span> <span class="p">[</span><span class="s2">"coral"</span><span class="p">,</span> <span class="s2">"#FF7F50"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">80</span><span class="p">],</span> <span class="p">[</span><span class="s2">"indianred"</span><span class="p">,</span> <span class="s2">"#CD5C5C"</span><span class="p">,</span> <span class="mi">205</span><span class="p">,</span> <span class="mi">92</span><span class="p">,</span> <span class="mi">92</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightcoral"</span><span class="p">,</span> <span class="s2">"#F08080"</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">128</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darksalmon"</span><span class="p">,</span> <span class="s2">"#E9967A"</span><span class="p">,</span> <span class="mi">233</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span> <span class="mi">122</span><span class="p">],</span> <span class="p">[</span><span class="s2">"salmon"</span><span class="p">,</span> <span class="s2">"#FA8072"</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">114</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightsalmon"</span><span class="p">,</span> <span class="s2">"#FFA07A"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">122</span><span class="p">],</span> <span class="p">[</span><span class="s2">"bisque"</span><span class="p">,</span> <span class="s2">"#FFE4C4"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">228</span><span class="p">,</span> <span class="mi">196</span><span class="p">],</span> <span class="p">[</span><span class="s2">"blanchedalmond"</span><span class="p">,</span> <span class="s2">"#FFEBCD"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">235</span><span class="p">,</span> <span class="mi">205</span><span class="p">],</span> <span class="p">[</span><span class="s2">"peachpuff"</span><span class="p">,</span> <span class="s2">"#FFDAB9"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">218</span><span class="p">,</span> <span class="mi">185</span><span class="p">],</span> <span class="p">[</span><span class="s2">"wheat"</span><span class="p">,</span> <span class="s2">"#F5DEB3"</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">222</span><span class="p">,</span> <span class="mi">179</span><span class="p">],</span> <span class="p">[</span><span class="s2">"navajowhite"</span><span class="p">,</span> <span class="s2">"#FFDEAD"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">222</span><span class="p">,</span> <span class="mi">173</span><span class="p">],</span> <span class="p">[</span><span class="s2">"cornsilk"</span><span class="p">,</span> <span class="s2">"#FFF8DC"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">248</span><span class="p">,</span> <span class="mi">220</span><span class="p">],</span> <span class="p">[</span><span class="s2">"saddlebrown"</span><span class="p">,</span> <span class="s2">"#8B4513"</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">19</span><span class="p">],</span> <span class="p">[</span><span class="s2">"sienna"</span><span class="p">,</span> <span class="s2">"#A0522D"</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">82</span><span class="p">,</span> <span class="mi">45</span><span class="p">],</span> <span class="p">[</span><span class="s2">"orangered"</span><span class="p">,</span> <span class="s2">"#FF4500"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkorange"</span><span class="p">,</span> <span class="s2">"#FF8C00"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">140</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"orange"</span><span class="p">,</span> <span class="s2">"#FFA500"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">165</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"brown"</span><span class="p">,</span> <span class="s2">"#A52A2A"</span><span class="p">,</span> <span class="mi">165</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="mi">42</span><span class="p">],</span> <span class="p">[</span><span class="s2">"gold"</span><span class="p">,</span> <span class="s2">"#FFD700"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">215</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkgoldenrod"</span><span class="p">,</span> <span class="s2">"#B8860B"</span><span class="p">,</span> <span class="mi">184</span><span class="p">,</span> <span class="mi">134</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span> <span class="p">[</span><span class="s2">"goldenrod"</span><span class="p">,</span> <span class="s2">"#DAA520"</span><span class="p">,</span> <span class="mi">218</span><span class="p">,</span> <span class="mi">165</span><span class="p">,</span> <span class="mi">32</span><span class="p">],</span> <span class="p">[</span><span class="s2">"palegoldenrod"</span><span class="p">,</span> <span class="s2">"#EEE8AA"</span><span class="p">,</span> <span class="mi">238</span><span class="p">,</span> <span class="mi">232</span><span class="p">,</span> <span class="mi">170</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkkhaki"</span><span class="p">,</span> <span class="s2">"#BDB76B"</span><span class="p">,</span> <span class="mi">189</span><span class="p">,</span> <span class="mi">183</span><span class="p">,</span> <span class="mi">107</span><span class="p">],</span> <span class="p">[</span><span class="s2">"khaki"</span><span class="p">,</span> <span class="s2">"#F0E68C"</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">230</span><span class="p">,</span> <span class="mi">140</span><span class="p">],</span> <span class="p">[</span><span class="s2">"moccasin"</span><span class="p">,</span> <span class="s2">"#FFE4B5"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">228</span><span class="p">,</span> <span class="mi">181</span><span class="p">],</span> <span class="p">[</span><span class="s2">"antiquewhite"</span><span class="p">,</span> <span class="s2">"#FAEBD7"</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">235</span><span class="p">,</span> <span class="mi">215</span><span class="p">],</span> <span class="p">[</span><span class="s2">"beige"</span><span class="p">,</span> <span class="s2">"#F5F5DC"</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">220</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lemonchiffon"</span><span class="p">,</span> <span class="s2">"#FFFACD"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">205</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightgoldenrodyellow"</span><span class="p">,</span> <span class="s2">"#FAFAD2"</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">210</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightyellow"</span><span class="p">,</span> <span class="s2">"#FFFFE0"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">224</span><span class="p">],</span> <span class="p">[</span><span class="s2">"chocolate"</span><span class="p">,</span> <span class="s2">"#D2691E"</span><span class="p">,</span> <span class="mi">210</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">30</span><span class="p">],</span> <span class="p">[</span><span class="s2">"peru"</span><span class="p">,</span> <span class="s2">"#CD853F"</span><span class="p">,</span> <span class="mi">205</span><span class="p">,</span> <span class="mi">133</span><span class="p">,</span> <span class="mi">63</span><span class="p">],</span> <span class="p">[</span><span class="s2">"sandybrown"</span><span class="p">,</span> <span class="s2">"#F4A460"</span><span class="p">,</span> <span class="mi">244</span><span class="p">,</span> <span class="mi">164</span><span class="p">,</span> <span class="mi">96</span><span class="p">],</span> <span class="p">[</span><span class="s2">"burlywood"</span><span class="p">,</span> <span class="s2">"#DEB887"</span><span class="p">,</span> <span class="mi">222</span><span class="p">,</span> <span class="mi">184</span><span class="p">,</span> <span class="mi">135</span><span class="p">],</span> <span class="p">[</span><span class="s2">"tan"</span><span class="p">,</span> <span class="s2">"#D2B48C"</span><span class="p">,</span> <span class="mi">210</span><span class="p">,</span> <span class="mi">180</span><span class="p">,</span> <span class="mi">140</span><span class="p">],</span> <span class="p">[</span><span class="s2">"rosybrown"</span><span class="p">,</span> <span class="s2">"#BC8F8F"</span><span class="p">,</span> <span class="mi">188</span><span class="p">,</span> <span class="mi">143</span><span class="p">,</span> <span class="mi">143</span><span class="p">],</span> <span class="p">[</span><span class="s2">"yellow"</span><span class="p">,</span> <span class="s2">"#FFFF00"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"olive"</span><span class="p">,</span> <span class="s2">"#808000"</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkolivegreen"</span><span class="p">,</span> <span class="s2">"#556B2F"</span><span class="p">,</span> <span class="mi">85</span><span class="p">,</span> <span class="mi">107</span><span class="p">,</span> <span class="mi">47</span><span class="p">],</span> <span class="p">[</span><span class="s2">"olivedrab"</span><span class="p">,</span> <span class="s2">"#6B8E23"</span><span class="p">,</span> <span class="mi">107</span><span class="p">,</span> <span class="mi">142</span><span class="p">,</span> <span class="mi">35</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lawngreen"</span><span class="p">,</span> <span class="s2">"#7CFC00"</span><span class="p">,</span> <span class="mi">124</span><span class="p">,</span> <span class="mi">252</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"chartreuse"</span><span class="p">,</span> <span class="s2">"#7FFF00"</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"greenyellow"</span><span class="p">,</span> <span class="s2">"#ADFF2F"</span><span class="p">,</span> <span class="mi">173</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">47</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkgreen"</span><span class="p">,</span> <span class="s2">"#006400"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"green"</span><span class="p">,</span> <span class="s2">"#008000"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"forestgreen"</span><span class="p">,</span> <span class="s2">"#228B22"</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">34</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lime"</span><span class="p">,</span> <span class="s2">"#00FF00"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightcyan"</span><span class="p">,</span> <span class="s2">"#E0FFFF"</span><span class="p">,</span> <span class="mi">224</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"limegreen"</span><span class="p">,</span> <span class="s2">"#32CD32"</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">205</span><span class="p">,</span> <span class="mi">50</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightgreen"</span><span class="p">,</span> <span class="s2">"#90EE90"</span><span class="p">,</span> <span class="mi">144</span><span class="p">,</span> <span class="mi">238</span><span class="p">,</span> <span class="mi">144</span><span class="p">],</span> <span class="p">[</span><span class="s2">"palegreen"</span><span class="p">,</span> <span class="s2">"#98FB98"</span><span class="p">,</span> <span class="mi">152</span><span class="p">,</span> <span class="mi">251</span><span class="p">,</span> <span class="mi">152</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkseagreen"</span><span class="p">,</span> <span class="s2">"#8FBC8F"</span><span class="p">,</span> <span class="mi">143</span><span class="p">,</span> <span class="mi">188</span><span class="p">,</span> <span class="mi">143</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumspringgreen"</span><span class="p">,</span> <span class="s2">"#00FA9A"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">154</span><span class="p">],</span> <span class="p">[</span><span class="s2">"springgreen"</span><span class="p">,</span> <span class="s2">"#00FF7F"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">127</span><span class="p">],</span> <span class="p">[</span><span class="s2">"yellowgreen"</span><span class="p">,</span> <span class="s2">"#9ACD32"</span><span class="p">,</span> <span class="mi">154</span><span class="p">,</span> <span class="mi">205</span><span class="p">,</span> <span class="mi">50</span><span class="p">],</span> <span class="p">[</span><span class="s2">"seagreen"</span><span class="p">,</span> <span class="s2">"#2E8B57"</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">87</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumaquamarine"</span><span class="p">,</span> <span class="s2">"#66CDAA"</span><span class="p">,</span> <span class="mi">102</span><span class="p">,</span> <span class="mi">205</span><span class="p">,</span> <span class="mi">170</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumseagreen"</span><span class="p">,</span> <span class="s2">"#3CB371"</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">179</span><span class="p">,</span> <span class="mi">113</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightseagreen"</span><span class="p">,</span> <span class="s2">"#20B2AA"</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">178</span><span class="p">,</span> <span class="mi">170</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkslategray"</span><span class="p">,</span> <span class="s2">"#2F4F4F"</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">79</span><span class="p">,</span> <span class="mi">79</span><span class="p">],</span> <span class="p">[</span><span class="s2">"teal"</span><span class="p">,</span> <span class="s2">"#008080"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">128</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkcyan"</span><span class="p">,</span> <span class="s2">"#008B8B"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">139</span><span class="p">],</span> <span class="p">[</span><span class="s2">"aqua"</span><span class="p">,</span> <span class="s2">"#00FFFF"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"cyan"</span><span class="p">,</span> <span class="s2">"#00FFFF"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkturquoise"</span><span class="p">,</span> <span class="s2">"#00CED1"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">206</span><span class="p">,</span> <span class="mi">209</span><span class="p">],</span> <span class="p">[</span><span class="s2">"turquoise"</span><span class="p">,</span> <span class="s2">"#40E0D0"</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="mi">224</span><span class="p">,</span> <span class="mi">208</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumturquoise"</span><span class="p">,</span> <span class="s2">"#48D1CC"</span><span class="p">,</span> <span class="mi">72</span><span class="p">,</span> <span class="mi">209</span><span class="p">,</span> <span class="mi">204</span><span class="p">],</span> <span class="p">[</span><span class="s2">"paleturquoise"</span><span class="p">,</span> <span class="s2">"#AFEEEE"</span><span class="p">,</span> <span class="mi">175</span><span class="p">,</span> <span class="mi">238</span><span class="p">,</span> <span class="mi">238</span><span class="p">],</span> <span class="p">[</span><span class="s2">"aquamarine"</span><span class="p">,</span> <span class="s2">"#7FFFD4"</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">212</span><span class="p">],</span> <span class="p">[</span><span class="s2">"powderblue"</span><span class="p">,</span> <span class="s2">"#B0E0E6"</span><span class="p">,</span> <span class="mi">176</span><span class="p">,</span> <span class="mi">224</span><span class="p">,</span> <span class="mi">230</span><span class="p">],</span> <span class="p">[</span><span class="s2">"cadetblue"</span><span class="p">,</span> <span class="s2">"#5F9EA0"</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">158</span><span class="p">,</span> <span class="mi">160</span><span class="p">],</span> <span class="p">[</span><span class="s2">"steelblue"</span><span class="p">,</span> <span class="s1">'#4682B4'</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">130</span><span class="p">,</span> <span class="mi">180</span><span class="p">],</span> <span class="p">[</span><span class="s1">'cornflowerblue'</span><span class="p">,</span> <span class="s2">"#6495ED"</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">149</span><span class="p">,</span> <span class="mi">237</span><span class="p">],</span> <span class="p">[</span><span class="s2">"deepskyblue"</span><span class="p">,</span> <span class="s2">"#00BFFF"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">191</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"dodgerblue"</span><span class="p">,</span> <span class="s2">"#1E90FF"</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">144</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightblue"</span><span class="p">,</span> <span class="s2">"#ADD8E6"</span><span class="p">,</span> <span class="mi">173</span><span class="p">,</span> <span class="mi">216</span><span class="p">,</span> <span class="mi">230</span><span class="p">],</span> <span class="p">[</span><span class="s2">"skyblue"</span><span class="p">,</span> <span class="s2">"#87CEEB"</span><span class="p">,</span> <span class="mi">135</span><span class="p">,</span> <span class="mi">206</span><span class="p">,</span> <span class="mi">235</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightskyblue"</span><span class="p">,</span> <span class="s2">"#87CEFA"</span><span class="p">,</span> <span class="mi">135</span><span class="p">,</span> <span class="mi">206</span><span class="p">,</span> <span class="mi">250</span><span class="p">],</span> <span class="p">[</span><span class="s2">"midnightblue"</span><span class="p">,</span> <span class="s2">"#191970"</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">112</span><span class="p">],</span> <span class="p">[</span><span class="s2">"navy"</span><span class="p">,</span> <span class="s2">"#000080"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">128</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkblue"</span><span class="p">,</span> <span class="s2">"#00008B"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">139</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumblue"</span><span class="p">,</span> <span class="s2">"#0000CD"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">205</span><span class="p">],</span> <span class="p">[</span><span class="s2">"blue"</span><span class="p">,</span> <span class="s2">"#0000FF"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"royalblue"</span><span class="p">,</span> <span class="s2">"#4169E1"</span><span class="p">,</span> <span class="mi">65</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">225</span><span class="p">],</span> <span class="p">[</span><span class="s2">"blueviolet"</span><span class="p">,</span> <span class="s2">"#8A2BE2"</span><span class="p">,</span> <span class="mi">138</span><span class="p">,</span> <span class="mi">43</span><span class="p">,</span> <span class="mi">226</span><span class="p">],</span> <span class="p">[</span><span class="s2">"indigo"</span><span class="p">,</span> <span class="s2">"#4B0082"</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">130</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkslateblue"</span><span class="p">,</span> <span class="s2">"#483D8B"</span><span class="p">,</span> <span class="mi">72</span><span class="p">,</span> <span class="mi">61</span><span class="p">,</span> <span class="mi">139</span><span class="p">],</span> <span class="p">[</span><span class="s2">"slateblue"</span><span class="p">,</span> <span class="s2">"#6A5ACD"</span><span class="p">,</span> <span class="mi">106</span><span class="p">,</span> <span class="mi">90</span><span class="p">,</span> <span class="mi">205</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumslateblue"</span><span class="p">,</span> <span class="s2">"#7B68EE"</span><span class="p">,</span> <span class="mi">123</span><span class="p">,</span> <span class="mi">104</span><span class="p">,</span> <span class="mi">238</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumpurple"</span><span class="p">,</span> <span class="s2">"#9370DB"</span><span class="p">,</span> <span class="mi">147</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">219</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkmagenta"</span><span class="p">,</span> <span class="s2">"#8B008B"</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">139</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkviolet"</span><span class="p">,</span> <span class="s2">"#9400D3"</span><span class="p">,</span> <span class="mi">148</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">211</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkorchid"</span><span class="p">,</span> <span class="s2">"#9932CC"</span><span class="p">,</span> <span class="mi">153</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">204</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumorchid"</span><span class="p">,</span> <span class="s2">"#BA55D3"</span><span class="p">,</span> <span class="mi">186</span><span class="p">,</span> <span class="mi">85</span><span class="p">,</span> <span class="mi">211</span><span class="p">],</span> <span class="p">[</span><span class="s2">"purple"</span><span class="p">,</span> <span class="s2">"#800080"</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">128</span><span class="p">],</span> <span class="p">[</span><span class="s2">"thistle"</span><span class="p">,</span> <span class="s2">"#D8BFD8"</span><span class="p">,</span> <span class="mi">216</span><span class="p">,</span> <span class="mi">191</span><span class="p">,</span> <span class="mi">216</span><span class="p">],</span> <span class="p">[</span><span class="s2">"plum"</span><span class="p">,</span> <span class="s2">"#DDA0DD"</span><span class="p">,</span> <span class="mi">221</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">221</span><span class="p">],</span> <span class="p">[</span><span class="s2">"violet"</span><span class="p">,</span> <span class="s2">"#EE82EE"</span><span class="p">,</span> <span class="mi">238</span><span class="p">,</span> <span class="mi">130</span><span class="p">,</span> <span class="mi">238</span><span class="p">],</span> <span class="p">[</span><span class="s2">"magenta"</span><span class="p">,</span> <span class="s2">"#FF00FF"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"orchid"</span><span class="p">,</span> <span class="s2">"#DA70D6"</span><span class="p">,</span> <span class="mi">218</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">214</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mediumvioletred"</span><span class="p">,</span> <span class="s2">"#C71585"</span><span class="p">,</span> <span class="mi">199</span><span class="p">,</span> <span class="mi">21</span><span class="p">,</span> <span class="mi">133</span><span class="p">],</span> <span class="p">[</span><span class="s2">"palevioletred"</span><span class="p">,</span> <span class="s2">"#DB7093"</span><span class="p">,</span> <span class="mi">219</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">147</span><span class="p">],</span> <span class="p">[</span><span class="s2">"deeppink"</span><span class="p">,</span> <span class="s2">"#FF1493"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">147</span><span class="p">],</span> <span class="p">[</span><span class="s2">"hotpink"</span><span class="p">,</span> <span class="s2">"#FF69B4"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">180</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightpink"</span><span class="p">,</span> <span class="s2">"#FFB6C1"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">182</span><span class="p">,</span> <span class="mi">193</span><span class="p">],</span> <span class="p">[</span><span class="s2">"pink"</span><span class="p">,</span> <span class="s2">"#FFC0CB"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">192</span><span class="p">,</span> <span class="mi">203</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mistyrose"</span><span class="p">,</span> <span class="s2">"#FFE4E1"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">228</span><span class="p">,</span> <span class="mi">225</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lavenderblush"</span><span class="p">,</span> <span class="s2">"#FFF0F5"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">245</span><span class="p">],</span> <span class="p">[</span><span class="s2">"linen"</span><span class="p">,</span> <span class="s2">"#FAF0E6"</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">230</span><span class="p">],</span> <span class="p">[</span><span class="s2">"oldlace"</span><span class="p">,</span> <span class="s2">"#FDF5E6"</span><span class="p">,</span> <span class="mi">253</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">230</span><span class="p">],</span> <span class="p">[</span><span class="s2">"papayawhip"</span><span class="p">,</span> <span class="s2">"#FFEFD5"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">239</span><span class="p">,</span> <span class="mi">213</span><span class="p">],</span> <span class="p">[</span><span class="s2">"seashell"</span><span class="p">,</span> <span class="s2">"#FFF5EE"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">238</span><span class="p">],</span> <span class="p">[</span><span class="s2">"mintcream"</span><span class="p">,</span> <span class="s2">"#F5FFFA"</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">250</span><span class="p">],</span> <span class="p">[</span><span class="s2">"slategray"</span><span class="p">,</span> <span class="s2">"#708090"</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">144</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightslategray"</span><span class="p">,</span> <span class="s2">"#778899"</span><span class="p">,</span> <span class="mi">119</span><span class="p">,</span> <span class="mi">136</span><span class="p">,</span> <span class="mi">153</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightsteelblue"</span><span class="p">,</span> <span class="s2">"#B0C4DE"</span><span class="p">,</span> <span class="mi">176</span><span class="p">,</span> <span class="mi">196</span><span class="p">,</span> <span class="mi">222</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lavender"</span><span class="p">,</span> <span class="s2">"#E6E6FA"</span><span class="p">,</span> <span class="mi">230</span><span class="p">,</span> <span class="mi">230</span><span class="p">,</span> <span class="mi">250</span><span class="p">],</span> <span class="p">[</span><span class="s2">"floralwhite"</span><span class="p">,</span> <span class="s2">"#FFFAF0"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">240</span><span class="p">],</span> <span class="p">[</span><span class="s2">"aliceblue"</span><span class="p">,</span> <span class="s2">"#F0F8FF"</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">248</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"ghostwhite"</span><span class="p">,</span> <span class="s2">"#F8F8FF"</span><span class="p">,</span> <span class="mi">248</span><span class="p">,</span> <span class="mi">248</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"honeydew"</span><span class="p">,</span> <span class="s2">"#F0FFF0"</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">240</span><span class="p">],</span> <span class="p">[</span><span class="s2">"ivory"</span><span class="p">,</span> <span class="s2">"#FFFFF0"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">240</span><span class="p">],</span> <span class="p">[</span><span class="s2">"azure"</span><span class="p">,</span> <span class="s2">"#F0FFFF"</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">],</span> <span class="p">[</span><span class="s2">"snow"</span><span class="p">,</span> <span class="s2">"#FFFAFA"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">250</span><span class="p">],</span> <span class="p">[</span><span class="s2">"black"</span><span class="p">,</span> <span class="s2">"#000000"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="s2">"dimgray"</span><span class="p">,</span> <span class="s2">"#696969"</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">105</span><span class="p">],</span> <span class="p">[</span><span class="s2">"gray"</span><span class="p">,</span> <span class="s2">"#808080"</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">128</span><span class="p">],</span> <span class="p">[</span><span class="s2">"darkgray"</span><span class="p">,</span> <span class="s2">"#A9A9A9"</span><span class="p">,</span> <span class="mi">169</span><span class="p">,</span> <span class="mi">169</span><span class="p">,</span> <span class="mi">169</span><span class="p">],</span> <span class="p">[</span><span class="s2">"silver"</span><span class="p">,</span> <span class="s2">"#C0C0C0"</span><span class="p">,</span> <span class="mi">192</span><span class="p">,</span> <span class="mi">192</span><span class="p">,</span> <span class="mi">192</span><span class="p">],</span> <span class="p">[</span><span class="s2">"lightgray"</span><span class="p">,</span> <span class="s2">"#D3D3D3"</span><span class="p">,</span> <span class="mi">211</span><span class="p">,</span> <span class="mi">211</span><span class="p">,</span> <span class="mi">211</span><span class="p">],</span> <span class="p">[</span><span class="s2">"gainsboro"</span><span class="p">,</span> <span class="s2">"#DCDCDC"</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">220</span><span class="p">],</span> <span class="p">[</span><span class="s2">"whitesmoke"</span><span class="p">,</span> <span class="s2">"#F5F5F5"</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">245</span><span class="p">],</span> <span class="p">[</span><span class="s2">"white"</span><span class="p">,</span> <span class="s2">"#FFFFFF"</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">]</span> <span class="p">];</span> </code></pre> </div> <div class="color-chip" title="maroon" alt="maroon named color" style="height: 80px; width: 80px; display: inline-block; background-color:#800000"> </div> <div class="color-chip" title="darkred" alt="darkred named color" style="height: 80px; width: 80px; display: inline-block; background-color:#8B0000"> </div> <div class="color-chip" title="firebrick" alt="firebrick named color" style="height: 80px; width: 80px; display: inline-block; background-color:#B22222"> </div> <div class="color-chip" title="crimson" alt="crimson named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DC143C"> </div> <div class="color-chip" title="red" alt="red named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF0000"> </div> <div class="color-chip" title="tomato" alt="tomato named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF6347"> </div> <div class="color-chip" title="coral" alt="coral named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF7F50"> </div> <div class="color-chip" title="indianred" alt="indianred named color" style="height: 80px; width: 80px; display: inline-block; background-color:#CD5C5C"> </div> <div class="color-chip" title="lightcoral" alt="lightcoral named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F08080"> </div> <div class="color-chip" title="darksalmon" alt="darksalmon named color" style="height: 80px; width: 80px; display: inline-block; background-color:#E9967A"> </div> <div class="color-chip" title="salmon" alt="salmon named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FA8072"> </div> <div class="color-chip" title="lightsalmon" alt="lightsalmon named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFA07A"> </div> <div class="color-chip" title="bisque" alt="bisque named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFE4C4"> </div> <div class="color-chip" title="blanchedalmond" alt="blanchedalmond named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFEBCD"> </div> <div class="color-chip" title="peachpuff" alt="peachpuff named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFDAB9"> </div> <div class="color-chip" title="wheat" alt="wheat named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F5DEB3"> </div> <div class="color-chip" title="navajowhite" alt="navajowhite named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFDEAD"> </div> <div class="color-chip" title="cornsilk" alt="cornsilk named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFF8DC"> </div> <div class="color-chip" title="saddlebrown" alt="saddlebrown named color" style="height: 80px; width: 80px; display: inline-block; background-color:#8B4513"> </div> <div class="color-chip" title="sienna" alt="sienna named color" style="height: 80px; width: 80px; display: inline-block; background-color:#A0522D"> </div> <div class="color-chip" title="orangered" alt="orangered named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF4500"> </div> <div class="color-chip" title="darkorange" alt="darkorange named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF8C00"> </div> <div class="color-chip" title="orange" alt="orange named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFA500"> </div> <div class="color-chip" title="brown" alt="brown named color" style="height: 80px; width: 80px; display: inline-block; background-color:#A52A2A"> </div> <div class="color-chip" title="gold" alt="gold named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFD700"> </div> <div class="color-chip" title="darkgoldenrod" alt="darkgoldenrod named color" style="height: 80px; width: 80px; display: inline-block; background-color:#B8860B"> </div> <div class="color-chip" title="goldenrod" alt="goldenrod named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DAA520"> </div> <div class="color-chip" title="palegoldenrod" alt="palegoldenrod named color" style="height: 80px; width: 80px; display: inline-block; background-color:#EEE8AA"> </div> <div class="color-chip" title="darkkhaki" alt="darkkhaki named color" style="height: 80px; width: 80px; display: inline-block; background-color:#BDB76B"> </div> <div class="color-chip" title="khaki" alt="khaki named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F0E68C"> </div> <div class="color-chip" title="moccasin" alt="moccasin named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFE4B5"> <!--more--> </div> <div class="color-chip" title="antiquewhite" alt="antiquewhite named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FAEBD7"> </div> <div class="color-chip" title="beige" alt="beige named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F5F5DC"> </div> <div class="color-chip" title="lemonchiffon" alt="lemonchiffon named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFACD"> </div> <div class="color-chip" title="lightgoldenrodyellow" alt="lightgoldenrodyellow named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FAFAD2"> </div> <div class="color-chip" title="lightyellow" alt="lightyellow named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFFE0"> </div> <div class="color-chip" title="chocolate" alt="chocolate named color" style="height: 80px; width: 80px; display: inline-block; background-color:#D2691E"> </div> <div class="color-chip" title="peru" alt="peru named color" style="height: 80px; width: 80px; display: inline-block; background-color:#CD853F"> </div> <div class="color-chip" title="sandybrown" alt="sandybrown named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F4A460"> </div> <div class="color-chip" title="burlywood" alt="burlywood named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DEB887"> </div> <div class="color-chip" title="tan" alt="tan named color" style="height: 80px; width: 80px; display: inline-block; background-color:#D2B48C"> </div> <div class="color-chip" title="rosybrown" alt="rosybrown named color" style="height: 80px; width: 80px; display: inline-block; background-color:#BC8F8F"> </div> <div class="color-chip" title="yellow" alt="yellow named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFF00"> </div> <div class="color-chip" title="olive" alt="olive named color" style="height: 80px; width: 80px; display: inline-block; background-color:#808000"> </div> <div class="color-chip" title="darkolivegreen" alt="darkolivegreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#556B2F"> </div> <div class="color-chip" title="olivedrab" alt="olivedrab named color" style="height: 80px; width: 80px; display: inline-block; background-color:#6B8E23"> </div> <div class="color-chip" title="lawngreen" alt="lawngreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#7CFC00"> </div> <div class="color-chip" title="chartreuse" alt="chartreuse named color" style="height: 80px; width: 80px; display: inline-block; background-color:#7FFF00"> </div> <div class="color-chip" title="greenyellow" alt="greenyellow named color" style="height: 80px; width: 80px; display: inline-block; background-color:#ADFF2F"> </div> <div class="color-chip" title="darkgreen" alt="darkgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#006400"> </div> <div class="color-chip" title="green" alt="green named color" style="height: 80px; width: 80px; display: inline-block; background-color:#008000"> </div> <div class="color-chip" title="forestgreen" alt="forestgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#228B22"> </div> <div class="color-chip" title="lime" alt="lime named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00FF00"> </div> <div class="color-chip" title="lightcyan" alt="lightcyan named color" style="height: 80px; width: 80px; display: inline-block; background-color:#E0FFFF"> </div> <div class="color-chip" title="limegreen" alt="limegreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#32CD32"> </div> <div class="color-chip" title="lightgreen" alt="lightgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#90EE90"> </div> <div class="color-chip" title="palegreen" alt="palegreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#98FB98"> </div> <div class="color-chip" title="darkseagreen" alt="darkseagreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#8FBC8F"> </div> <div class="color-chip" title="mediumspringgreen" alt="mediumspringgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00FA9A"> </div> <div class="color-chip" title="springgreen" alt="springgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00FF7F"> </div> <div class="color-chip" title="yellowgreen" alt="yellowgreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#9ACD32"> </div> <div class="color-chip" title="seagreen" alt="seagreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#2E8B57"> </div> <div class="color-chip" title="mediumaquamarine" alt="mediumaquamarine named color" style="height: 80px; width: 80px; display: inline-block; background-color:#66CDAA"> </div> <div class="color-chip" title="mediumseagreen" alt="mediumseagreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#3CB371"> </div> <div class="color-chip" title="lightseagreen" alt="lightseagreen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#20B2AA"> </div> <div class="color-chip" title="darkslategray" alt="darkslategray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#2F4F4F"> </div> <div class="color-chip" title="teal" alt="teal named color" style="height: 80px; width: 80px; display: inline-block; background-color:#008080"> </div> <div class="color-chip" title="darkcyan" alt="darkcyan named color" style="height: 80px; width: 80px; display: inline-block; background-color:#008B8B"> </div> <div class="color-chip" title="aqua" alt="aqua named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00FFFF"> </div> <div class="color-chip" title="cyan" alt="cyan named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00FFFF"> </div> <div class="color-chip" title="darkturquoise" alt="darkturquoise named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00CED1"> </div> <div class="color-chip" title="turquoise" alt="turquoise named color" style="height: 80px; width: 80px; display: inline-block; background-color:#40E0D0"> </div> <div class="color-chip" title="mediumturquoise" alt="mediumturquoise named color" style="height: 80px; width: 80px; display: inline-block; background-color:#48D1CC"> </div> <div class="color-chip" title="paleturquoise" alt="paleturquoise named color" style="height: 80px; width: 80px; display: inline-block; background-color:#AFEEEE"> </div> <div class="color-chip" title="aquamarine" alt="aquamarine named color" style="height: 80px; width: 80px; display: inline-block; background-color:#7FFFD4"> </div> <div class="color-chip" title="powderblue" alt="powderblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#B0E0E6"> </div> <div class="color-chip" title="cadetblue" alt="cadetblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#5F9EA0"> </div> <div class="color-chip" title="steelblue" alt="steelblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#4682B4"> </div> <div class="color-chip" title="cornflowerblue" alt="cornflowerblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#6495ED"> </div> <div class="color-chip" title="deepskyblue" alt="deepskyblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00BFFF"> </div> <div class="color-chip" title="dodgerblue" alt="dodgerblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#1E90FF"> </div> <div class="color-chip" title="lightblue" alt="lightblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#ADD8E6"> </div> <div class="color-chip" title="skyblue" alt="skyblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#87CEEB"> </div> <div class="color-chip" title="lightskyblue" alt="lightskyblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#87CEFA"> </div> <div class="color-chip" title="midnightblue" alt="midnightblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#191970"> </div> <div class="color-chip" title="navy" alt="navy named color" style="height: 80px; width: 80px; display: inline-block; background-color:#000080"> </div> <div class="color-chip" title="darkblue" alt="darkblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#00008B"> </div> <div class="color-chip" title="mediumblue" alt="mediumblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#0000CD"> </div> <div class="color-chip" title="blue" alt="blue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#0000FF"> </div> <div class="color-chip" title="royalblue" alt="royalblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#4169E1"> </div> <div class="color-chip" title="blueviolet" alt="blueviolet named color" style="height: 80px; width: 80px; display: inline-block; background-color:#8A2BE2"> </div> <div class="color-chip" title="indigo" alt="indigo named color" style="height: 80px; width: 80px; display: inline-block; background-color:#4B0082"> </div> <div class="color-chip" title="darkslateblue" alt="darkslateblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#483D8B"> </div> <div class="color-chip" title="slateblue" alt="slateblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#6A5ACD"> </div> <div class="color-chip" title="mediumslateblue" alt="mediumslateblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#7B68EE"> </div> <div class="color-chip" title="mediumpurple" alt="mediumpurple named color" style="height: 80px; width: 80px; display: inline-block; background-color:#9370DB"> </div> <div class="color-chip" title="darkmagenta" alt="darkmagenta named color" style="height: 80px; width: 80px; display: inline-block; background-color:#8B008B"> </div> <div class="color-chip" title="darkviolet" alt="darkviolet named color" style="height: 80px; width: 80px; display: inline-block; background-color:#9400D3"> </div> <div class="color-chip" title="darkorchid" alt="darkorchid named color" style="height: 80px; width: 80px; display: inline-block; background-color:#9932CC"> </div> <div class="color-chip" title="mediumorchid" alt="mediumorchid named color" style="height: 80px; width: 80px; display: inline-block; background-color:#BA55D3"> </div> <div class="color-chip" title="purple" alt="purple named color" style="height: 80px; width: 80px; display: inline-block; background-color:#800080"> </div> <div class="color-chip" title="thistle" alt="thistle named color" style="height: 80px; width: 80px; display: inline-block; background-color:#D8BFD8"> </div> <div class="color-chip" title="plum" alt="plum named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DDA0DD"> </div> <div class="color-chip" title="violet" alt="violet named color" style="height: 80px; width: 80px; display: inline-block; background-color:#EE82EE"> </div> <div class="color-chip" title="magenta" alt="magenta named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF00FF"> </div> <div class="color-chip" title="orchid" alt="orchid named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DA70D6"> </div> <div class="color-chip" title="mediumvioletred" alt="mediumvioletred named color" style="height: 80px; width: 80px; display: inline-block; background-color:#C71585"> </div> <div class="color-chip" title="palevioletred" alt="palevioletred named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DB7093"> </div> <div class="color-chip" title="deeppink" alt="deeppink named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF1493"> </div> <div class="color-chip" title="hotpink" alt="hotpink named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FF69B4"> </div> <div class="color-chip" title="lightpink" alt="lightpink named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFB6C1"> </div> <div class="color-chip" title="pink" alt="pink named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFC0CB"> </div> <div class="color-chip" title="mistyrose" alt="mistyrose named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFE4E1"> </div> <div class="color-chip" title="lavenderblush" alt="lavenderblush named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFF0F5"> </div> <div class="color-chip" title="linen" alt="linen named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FAF0E6"> </div> <div class="color-chip" title="oldlace" alt="oldlace named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FDF5E6"> </div> <div class="color-chip" title="papayawhip" alt="papayawhip named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFEFD5"> </div> <div class="color-chip" title="seashell" alt="seashell named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFF5EE"> </div> <div class="color-chip" title="mintcream" alt="mintcream named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F5FFFA"> </div> <div class="color-chip" title="slategray" alt="slategray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#708090"> </div> <div class="color-chip" title="lightslategray" alt="lightslategray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#778899"> </div> <div class="color-chip" title="lightsteelblue" alt="lightsteelblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#B0C4DE"> </div> <div class="color-chip" title="lavender" alt="lavender named color" style="height: 80px; width: 80px; display: inline-block; background-color:#E6E6FA"> </div> <div class="color-chip" title="floralwhite" alt="floralwhite named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFAF0"> </div> <div class="color-chip" title="aliceblue" alt="aliceblue named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F0F8FF"> </div> <div class="color-chip" title="ghostwhite" alt="ghostwhite named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F8F8FF"> </div> <div class="color-chip" title="honeydew" alt="honeydew named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F0FFF0"> </div> <div class="color-chip" title="ivory" alt="ivory named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFFF0"> </div> <div class="color-chip" title="azure" alt="azure named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F0FFFF"> </div> <div class="color-chip" title="snow" alt="snow named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFAFA"> </div> <div class="color-chip" title="black" alt="black named color" style="height: 80px; width: 80px; display: inline-block; background-color:#000000"> </div> <div class="color-chip" title="dimgray" alt="dimgray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#696969"> </div> <div class="color-chip" title="gray" alt="gray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#808080"> </div> <div class="color-chip" title="darkgray" alt="darkgray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#A9A9A9"> </div> <div class="color-chip" title="silver" alt="silver named color" style="height: 80px; width: 80px; display: inline-block; background-color:#C0C0C0"> </div> <div class="color-chip" title="lightgray" alt="lightgray named color" style="height: 80px; width: 80px; display: inline-block; background-color:#D3D3D3"> </div> <div class="color-chip" title="gainsboro" alt="gainsboro named color" style="height: 80px; width: 80px; display: inline-block; background-color:#DCDCDC"> </div> <div class="color-chip" title="whitesmoke" alt="whitesmoke named color" style="height: 80px; width: 80px; display: inline-block; background-color:#F5F5F5"> </div> <div class="color-chip" title="white" alt="white named color" style="height: 80px; width: 80px; display: inline-block; background-color:#FFFFFF"> </div> Angularjs Directives With Actions 2017-03-03T00:00:00-08:00 http://tomnorian.com/angularjs-directives-with-actions <p>I decided to take a look back at AngularJS this week after having spent the last few months with other front-end DSL environments and platforms. (EmberJS and, to the extent it qualifies, Jekyll/Liquid).</p> <p>I think the time I spent learning EmberJS late in 2016 really began to get me in the mind-set of web components. More on EmberJS in other posts, and I’ll leave the “meta” discussion of web components up to the trend setters…I’m following you though!</p> <p>AngularJS has been <a class="markdown-external-link" target="_blank" href="https://docs.angularjs.org/guide/component">actively moving toward components</a> itself, even in Angular 1.X which has an aura of being ‘deprecated’.</p> <p>As RTFM works, you can find out these things! What’s more, <em>some precursors to components were there in angularJS all along</em>.</p> <p><strong>What I’m Sharing:</strong></p> <ul> <li>a basic example of a directive that can modularize “sortable tables”</li> <li>a few examples of AngularJS bells and whistles in use</li> <li>an example how you can pass different actions to the same reusable custom directive you create.</li> </ul> <p><span class="tn-image-inline " style="width:40%"> <img src="/images/blog/angularjs-sortable-table.png" alt="sortable table demo" title="" width="100%" /> <label class="tn-image-inline-caption"></label> </span> Really it is that last one, the passing of a function name to a directive, enabling the same directive to be used in different ways, that made me want to share this.</p> <p>While I’m not sure I nailed the “AngularJS way”, the process had me taking a deeper dive.</p> <p>The AngularJS website and style guides didn’t really have any great examples so, maybe seeing my syntax will get your juices flowing.</p> <p><strong>A quick reminder why to use directives</strong></p> <p>First, <a class="markdown-external-link" target="_blank" href="http://rankarooski.com/#/angular-directive-demo">open up the (external) live demo</a> to see the two sortable lists where we’ll reuse page segments that are more than flat information displays. <!--more--></p> <p>Second, open the code toggle below for something ugly!</p> <div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <button data-toggle="collapse" data-target="#long-unrefactored"> Long, Logic in View </button> </h4> </div> <div id="long-unrefactored" class="panel-collapse collapse"> <div class="panel-body"> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"container"</span> <span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-12"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">ng-controller=</span><span class="s">"RatingListController as list "</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-3 master-list"</span><span class="nt">&gt;</span> <span class="nt">&lt;table</span> <span class="na">id=</span><span class="s">"all-performer-table"</span> <span class="na">class=</span><span class="s">"table table-bordered table-striped"</span><span class="nt">&gt;</span> <span class="nt">&lt;thead</span> <span class="na">ng-init=</span><span class="s">"sortType='score'; sortReverse=true "</span><span class="nt">&gt;</span> <span class="nt">&lt;tr&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">ng-click=</span><span class="s">"sortType = '-name'; sortReverse = !sortReverse"</span><span class="nt">&gt;</span> Select From Below <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == '-name' &amp;&amp; sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-down"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == '-name' &amp;&amp; !sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-up"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">ng-click=</span><span class="s">"sortType = 'score'; sortReverse = !sortReverse"</span><span class="nt">&gt;</span> Score <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == 'score' &amp;&amp; !sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-down"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == 'score' &amp;&amp; sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-up"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td</span> <span class="na">class=</span><span class="s">"check-box-label"</span><span class="nt">&gt;</span> +<span class="nt">&lt;span</span> <span class="na">style=</span><span class="s">"color: red;"</span><span class="nt">&gt;</span> -<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/thead&gt;</span> <span class="nt">&lt;tr</span> <span class="na">ng-repeat=</span><span class="s">"item in list.itemsInSet | orderBy:sortType:sortReverse"</span><span class="nt">&gt;</span> <span class="nt">&lt;td</span> <span class="na">ng-class=</span><span class="s">"{limeHighlight: item.selected}"</span> <span class="nt">&gt;</span>{{item.name}}<span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span>{{item.score}}<span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">ng-model=</span><span class="s">item.selected</span> <span class="na">ng-click=</span><span class="s">"list.addOrRemoveFromRatedItems(item)"</span><span class="nt">&gt;&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/table&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-4 selected-list"</span><span class="nt">&gt;</span> <span class="nt">&lt;ol</span> <span class="na">class=</span><span class="s">"selected-item-list"</span><span class="nt">&gt;</span> <span class="nt">&lt;li</span> <span class="na">ng-repeat=</span><span class="s">"selItem in list.ratedItems"</span> <span class="na">class=</span><span class="s">"selected-item-rated"</span><span class="nt">&gt;</span> <span class="nt">&lt;span</span> <span class="nt">&gt;</span>{{selItem.name}}- {{selItem.$$hashKey}}<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"list-making-tools pull-right"</span> <span class="nt">&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-remove-circle text-danger"</span> <span class="na">ng-click=</span><span class="s">"list.removeFromRatedItems(selItem)"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-arrow-down text-warning "</span> <span class="na">ng-click=</span><span class="s">"list.moveDownRatedItems(selItem)"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-arrow-up text-success"</span> <span class="na">ng-click=</span><span class="s">"list.moveUpRatedItems(selItem)"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/li&gt;</span> <span class="nt">&lt;/ol&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="c">&lt;!-- end RatingListController --&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-5 demo-explanation "</span> <span class="na">ng-controller=</span><span class="s">"PhotoDisplayController as photos"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"photo-box"</span><span class="nt">&gt;</span> <span class="nt">&lt;img</span> <span class="na">ng-src=</span><span class="s">"{{photos.chosenPhoto.photo_url}}"</span> <span class="na">alt=</span><span class="s">"{{photos.chosenPhoto.title}}"</span><span class="nt">&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;table</span> <span class="na">id=</span><span class="s">"photo-table"</span> <span class="na">class=</span><span class="s">"table table-bordered table-striped"</span><span class="nt">&gt;</span> <span class="nt">&lt;thead</span> <span class="na">ng-init=</span><span class="s">"sortType='score'; sortReverse=true "</span><span class="nt">&gt;</span> <span class="nt">&lt;tr&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">ng-click=</span><span class="s">"sortType = '-name'; sortReverse = !sortReverse"</span><span class="nt">&gt;</span> Select From Below <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == '-name' &amp;&amp; sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-down"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == '-name' &amp;&amp; !sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-up"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">ng-click=</span><span class="s">"sortType = 'score'; sortReverse = !sortReverse"</span><span class="nt">&gt;</span> Year <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == 'score' &amp;&amp; !sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-down"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"sortType == 'score' &amp;&amp; sortReverse"</span> <span class="na">class=</span><span class="s">"fa fa-caret-up"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td</span> <span class="na">class=</span><span class="s">"check-box-label"</span><span class="nt">&gt;</span> +<span class="nt">&lt;span</span> <span class="na">style=</span><span class="s">"color: red;"</span><span class="nt">&gt;</span> -<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/thead&gt;</span> <span class="nt">&lt;tr</span> <span class="na">ng-repeat=</span><span class="s">"item in photos.itemsInSet | orderBy:sortType:sortReverse"</span><span class="nt">&gt;</span> <span class="nt">&lt;td</span> <span class="na">ng-class=</span><span class="s">"{limeHighlight: item.selected}"</span> <span class="nt">&gt;</span>{{item.name}}<span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span>{{item.year}}<span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">ng-model=</span><span class="s">item.selected</span> <span class="na">ng-click=</span><span class="s">"list.addOrRemoveFromRatedItems(item)"</span><span class="nt">&gt;&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/table&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> </div> <div class="panel-footer">Ugh, logic or display?!</div> </div> </div> </div> <!-- use a syntax like this NOTE spaces have been put in between { and % to allow these comments { % capture text-capture % } ```javascript function someFunction(x){ return x = 2X } ``` That was a double it function. { % endcapture % } { % include widgets/toggle-field.html button="See the Code" toggle-text=text-capture footer= "type your footer string" % } --> <p>That sort of mess of logic in the view is why AngularJS got a bad rap… but! … that was never how it was supposed to be!</p> <p>Here is how that HTML page looks with the content broken out into directives:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-12"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"first-two-columns"</span> <span class="na">ng-controller=</span><span class="s">"RatingListController as list "</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-3 master-list"</span><span class="nt">&gt;</span> <span class="nt">&lt;tn-sortable-table</span> <span class="na">list-data=</span><span class="s">'list'</span> <span class="na">cols-displayed=</span><span class="s">"name,score"</span> <span class="na">cols-labels=</span><span class="s">"Character,Rating"</span> <span class="na">check-action=</span><span class="s">'addOrRemoveFromRatedItems'</span> <span class="na">sort-col=</span><span class="s">'score'</span> <span class="na">sort-desc=</span><span class="s">'true'</span><span class="nt">&gt;</span> <span class="nt">&lt;/tn-sortable-table&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-4 selected-list"</span><span class="nt">&gt;</span> <span class="nt">&lt;user-selected-list&gt;&lt;/user-selected-list&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="c">&lt;!-- end RatingListCotnroller --&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"col-md-5 photo-display-list "</span> <span class="na">ng-controller=</span><span class="s">"PhotoDisplayController as photos"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"photo-box"</span><span class="nt">&gt;</span> <span class="nt">&lt;img</span> <span class="na">ng-src=</span><span class="s">"{{photos.chosenPhoto.photo_url}}"</span> <span class="na">alt=</span><span class="s">"{{photos.chosenPhoto.title}}"</span><span class="nt">&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;tn-sortable-table</span> <span class="na">list-data=</span><span class="s">'photos'</span> <span class="na">cols-displayed=</span><span class="s">"title,category,year"</span> <span class="na">cols-labels=</span><span class="s">"Photos of Tom,Activity,Year"</span> <span class="na">check-action=</span><span class="s">"pickPhoto"</span> <span class="na">sort-col=</span><span class="s">'title'</span> <span class="na">sort-desc=</span><span class="s">'false'</span><span class="nt">&gt;</span> <span class="nt">&lt;/tn-sortable-table&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="c">&lt;!-- end PhotoDisplayController --&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <p>See? The main page segments are called by custom tag with their specific code factored out.</p> <p>The key element is the creation of the DSL like <code class="highlighter-rouge">&lt;sortable-table&gt;</code> tags.</p> <p>You can use data from mutiple controllers, name the data columns you want to see, give custom column labels, and specify which columns and direction to sort by.</p> <p>AND, you can dictate what action will be performed after checking…all from one directive line.</p> <p>I will indent and comment for easier reading:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;tn-sortable-table</span> <span class="na">list-data=</span><span class="s">'list'</span> <span class="err">&lt;!</span><span class="na">--we</span> <span class="na">actually</span> <span class="na">pass</span> <span class="na">all</span> <span class="na">the</span> <span class="na">functions</span> <span class="na">down</span> <span class="na">to</span> <span class="na">the</span> <span class="na">directive</span> <span class="na">to</span> <span class="na">enable</span> <span class="na">action--</span><span class="nt">&gt;</span> <span class="c">&lt;!--for more than a demo controllers another param would be added here for custom data--&gt;</span> cols-displayed="name,score"<span class="c">&lt;!--These Two columns of the data table will be displayed in this order--&gt;</span> cols-labels="Character Name,Rating"<span class="c">&lt;!--Label the headers in a user friendly way--&gt;</span> sort-col='score' sort-desc='true'<span class="c">&lt;!--On load, show table sorted by it's 'score' column descending--&gt;</span> check-action='addOrRemoveFromRatedItems'&gt;<span class="c">&lt;!--this is the Tricky Part : pass a function name--&gt;</span> <span class="nt">&lt;/tn-sortable-table&gt;</span> </code></pre> </div> <p>The first above lets a visitor choose names from a master list and put them into their own order.</p> <p>You can see my project where you can use something similar to <a class="markdown-external-link" target="_blank" href="http://toptenmaker.com">make Top Ten Lists</a> and have your votes added to the public score as well as make image of your own opinions to share via social media.</p> <p>And my second use of the directive, this time as a control feature for a photo display as you saw in the linked demo.</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;tn-sortable-table</span> <span class="na">list-data=</span><span class="s">'photos'</span> <span class="err">&lt;!</span><span class="na">--</span> <span class="na">same</span> <span class="na">directive</span><span class="err">,</span> <span class="na">different</span> <span class="na">controller</span> <span class="na">--</span><span class="nt">&gt;</span> cols-displayed="title,category,year"<span class="c">&lt;!--Three columns this time - any number of cols works--&gt;</span> cols-labels="Photos of Tom,Activity,Year"<span class="c">&lt;!--user can click on any table header label to resort--&gt;</span> sort-col='title' sort-desc='false' check-action="pickPhoto" &gt; <span class="nt">&lt;/tn-sortable-table&gt;</span> </code></pre> </div> <p>The parameters: <strong>list-data</strong> , passes all the list data downward as well as the scope needed to execute your action.</p> <p>The ‘<strong>cols-displayed</strong>’ and ‘<strong>cols-labels</strong>’ do what you think.. the first is used as a key and the second as text in the table headers. Note, AngularJS will not take arrays. I chose comma separated strings as the easiest alternative to type.</p> <p>It is easy to allow a content creator to choose what column the tables should be ranked on when landing with <strong>sort-col</strong> (name of the data key column) and <strong>sort-desc</strong> (true or false).</p> <p>The checkAction is a string name of the function on the controller that will be called.</p> <p>You can see the directive’s JS file below:</p> <p>Here is the directive’s JS file that handles those the <code class="highlighter-rouge">&lt;tn-sortable-table&gt;</code> tags above.</p> <div class="language-javascript highlighter-rouge"><pre class="highlight"><code><span class="c1">// js/directives/sortable-table.js</span> <span class="nx">angular</span> <span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s1">'demo-directive-app'</span><span class="p">)</span> <span class="p">.</span><span class="nx">directive</span><span class="p">(</span><span class="s1">'tnSortableTable'</span><span class="p">,</span> <span class="nx">sortableTable</span><span class="p">);</span> <span class="kd">function</span> <span class="nx">sortableTable</span><span class="p">(){</span> <span class="k">return</span> <span class="p">{</span> <span class="na">restrict</span><span class="p">:</span> <span class="s1">'E'</span><span class="p">,</span> <span class="na">scope</span><span class="p">:{</span> <span class="na">listData</span> <span class="p">:</span> <span class="s2">"=listData"</span> <span class="p">},</span> <span class="na">templateUrl</span><span class="p">:</span> <span class="s1">'templates/directives/sortable-table.html'</span><span class="p">,</span> <span class="na">link</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">element</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">){</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">colsDisplayed</span> <span class="o">=</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">colsDisplayed</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">','</span><span class="p">);</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">colsLabels</span> <span class="o">=</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">colsLabels</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">','</span><span class="p">);</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">sortCol</span> <span class="o">=</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">sortCol</span><span class="p">;</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">sortDesc</span> <span class="o">=</span> <span class="p">(</span><span class="nx">attrs</span><span class="p">.</span><span class="nx">sortDesc</span> <span class="o">==</span> <span class="s2">"true"</span><span class="p">);</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">itemsInSet</span> <span class="o">=</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">listData</span><span class="p">.</span><span class="nx">itemsInSet</span><span class="p">;</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">checkAction</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">){</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">listData</span><span class="p">[</span><span class="nx">attrs</span><span class="p">.</span><span class="nx">checkAction</span><span class="p">](</span><span class="nx">item</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span> <span class="p">};</span> </code></pre> </div> <p>There are a few tricky things there. The kebab - separated names get ‘normalized’ into camel case in the JS file. (i.e. <strong>cols-displayed</strong> must be changed to <strong>colsDisplayed</strong>).</p> <p>I use the setter format “=listData” to expand the page scope into the directive scope. An alternative way that you need when you’ll manipulate the data is the use of the ‘link: function() ‘ syntax.</p> <p>I am going to cop-out on a true explanation of how this all works. That would be longer than this post all together.</p> <p>Here are a few links <a class="markdown-external-link" target="_blank" href="http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs/14049482#14049482">Stack overflow essay on AngularJS inheritance</a> and the <a class="markdown-external-link" target="_blank" href="https://docs.angularjs.org/guide/directive">main AngularJS developer guide on directives</a></p> <p>I worry somewhat about the elegance of passing the entire scope via ‘listData’ however it’s important to realize …. <em>and you might pound your head against the table for a few hours</em> … that you can’t have <code class="highlighter-rouge">ng-click</code>’s given action build a regex or function via interpolated elements of expressions!</p> <p>from their site:</p> <blockquote> <h2 id="no-function-declarations-or-regexp-creation-with-literal-notation">No function declarations or RegExp creation with literal notation</h2> <p>You can’t declare functions or create regular expressions from within AngularJS expressions. This is to avoid complex model transformation logic inside templates. Such logic is better placed in a controller or in a dedicated filter where it can be tested properly.</p> </blockquote> <p>So, that explains why I was sure that the parent scope of the controller was available to the directive via the “listData” param.</p> <p>You CAN use a directive parameter to -be executed- . Ng-click looks at what is between the “quotes” and first tries to execute it rather than interpolating {{}} first then executing. Many work-arounds attempts will stop the entire page from executing.</p> <p>What I do below is one working approach:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="c">&lt;!-- templates/sortable-table.html --&gt;</span> <span class="nt">&lt;table</span> <span class="na">id=</span><span class="s">"all-performer-table"</span> <span class="na">class=</span><span class="s">"table table-bordered table-striped"</span><span class="nt">&gt;</span> <span class="nt">&lt;thead</span> <span class="na">ng-init=</span><span class="s">"sortType=colTwo; sortReverse=true "</span><span class="nt">&gt;</span> <span class="nt">&lt;tr&gt;</span> <span class="nt">&lt;td</span> <span class="na">sortable-table-header</span> <span class="na">inner-type=</span><span class="s">'sortType'</span> <span class="na">inner-reverse =</span><span class="s">'sortReverse'</span> <span class="na">this-col=</span><span class="s">'colOne'</span><span class="nt">&gt;&lt;/td&gt;</span> <span class="nt">&lt;td</span> <span class="na">sortable-table-header</span> <span class="na">inner-type=</span><span class="s">'sortType'</span> <span class="na">inner-reverse =</span><span class="s">'sortReverse'</span> <span class="na">this-col=</span><span class="s">'colTwo'</span><span class="nt">&gt;&lt;/td &gt;</span> <span class="nt">&lt;td</span> <span class="na">class=</span><span class="s">"check-box-label"</span><span class="nt">&gt;</span> +<span class="nt">&lt;span</span> <span class="na">style=</span><span class="s">"color: red;"</span><span class="nt">&gt;</span> -<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/thead&gt;</span> <span class="nt">&lt;tr</span> <span class="na">ng-repeat=</span><span class="s">"item in listData.itemsInSet | orderBy:sortType:sortReverse"</span> <span class="nt">&gt;</span> <span class="nt">&lt;td</span> <span class="na">ng-class=</span><span class="s">"{limeHighlight: item.selected}"</span> <span class="nt">&gt;</span> {{item[colOne]}} <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> {{item[colTwo]}} <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">ng-model=</span><span class="s">item.selected</span> <span class="na">ng-click=</span><span class="s">"listData[checkAction](item)"</span><span class="nt">&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/table&gt;</span> </code></pre> </div> <p>You’ll see that I have yet another directive, the <sortable-table-header> directive, nested withing the <sortable-table> directives.</sortable-table></sortable-table-header></p> <p>That inner hidden directive is passed a column name to label the column from the parent parameter.</p> <ul> <li>the single quotes around ‘colOne’ passes teh value of ‘colOne’, not the string “colOne”.</li> <li>to retrieve the column information using that dynamic parameter, use bracket notation.</li> </ul> <p>**By breaking out the header elements further, we cleans out the repeated glyphicon references. Even more importantly it is a step towards being able to iterate over an array of column names to accommodate a variable number of columns using a single directive. **</p> <p>A developer won’t need to know the internal hand-off as it is encapsulated within the outer tags like a DSL.</p> <p>For good measure though, here is the internal working:</p> <div class="language-js highlighter-rouge"><pre class="highlight"><code><span class="c1">// js/sortable-2col-header.js</span> <span class="nx">angular</span> <span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s1">'demo-directive-app'</span><span class="p">)</span> <span class="p">.</span><span class="nx">directive</span><span class="p">(</span><span class="s1">'sortableTableHeader'</span><span class="p">,</span> <span class="nx">sortableTableHeader</span><span class="p">);</span> <span class="kd">function</span> <span class="nx">sortableTableHeader</span><span class="p">(){</span> <span class="k">return</span> <span class="p">{</span> <span class="na">scope</span><span class="p">:</span> <span class="p">{</span> <span class="na">thisCol</span> <span class="p">:</span> <span class="s2">"=thisCol"</span><span class="p">,</span> <span class="na">innerReverse</span> <span class="p">:</span> <span class="s2">"=innerReverse"</span><span class="p">,</span> <span class="na">innerType</span> <span class="p">:</span> <span class="s2">"=innerType"</span> <span class="p">},</span> <span class="na">templateUrl</span><span class="p">:</span> <span class="s1">'templates/sortable-table-header-cell.html'</span> <span class="p">};</span> <span class="p">};</span> </code></pre> </div> <div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="c">&lt;!-- templates/sortable-table-header-cell.html --&gt;</span> <span class="nt">&lt;table</span> <span class="na">id=</span><span class="s">"all-performer-table"</span> <span class="na">class=</span><span class="s">"table table-bordered table-striped"</span><span class="nt">&gt;</span> <span class="nt">&lt;thead</span> <span class="nt">&gt;</span> <span class="nt">&lt;tr&gt;</span> <span class="nt">&lt;td</span> <span class="na">ng-repeat=</span><span class="s">"label in colsLabels"</span><span class="nt">&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">""</span> <span class="na">ng-click=</span><span class="s">" $parent.sortCol == $parent.colsDisplayed[$index] ? $parent.sortDesc = !$parent.sortDesc : $parent.sortCol = $parent.colsDisplayed[$index]"</span> <span class="nt">&gt;</span> {{label}} <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"$parent.sortCol == $parent.colsDisplayed[$index] &amp;&amp; $parent.sortDesc"</span> <span class="na">class=</span><span class="s">"fa fa-caret-down"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">ng-show=</span><span class="s">"$parent.sortCol == $parent.colsDisplayed[$index] &amp;&amp; !$parent.sortDesc"</span> <span class="na">class=</span><span class="s">"fa fa-caret-up"</span><span class="nt">&gt;&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td &gt;</span> <span class="nt">&lt;td</span> <span class="na">class=</span><span class="s">"check-box-label"</span><span class="nt">&gt;</span> + <span class="nt">&lt;span</span> <span class="na">style=</span><span class="s">"color: red;"</span><span class="nt">&gt;</span> -<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/thead&gt;</span> <span class="nt">&lt;tr</span> <span class="na">ng-repeat=</span><span class="s">"item in itemsInSet | orderBy:sortCol:sortDesc"</span> <span class="nt">&gt;</span> <span class="nt">&lt;td</span> <span class="na">ng-repeat=</span><span class="s">"col in colsDisplayed"</span> <span class="na">ng-class=</span><span class="s">"{limeHighlight: item.selected}"</span> <span class="nt">&gt;</span> {{$parent.item[col]}} <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">ng-model=</span><span class="s">item.selected</span> <span class="na">ng-click=</span><span class="s">"$parent.checkAction(item)"</span> <span class="nt">&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> <span class="nt">&lt;/table&gt;</span> </code></pre> </div> <p>I hope these examples might help someone toying with the same issues out.</p> <p>Note that last line!</p> <div class="language-javascript highlighter-rouge"><pre class="highlight"><code> <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"checkbox"</span> <span class="nx">ng</span><span class="o">-</span><span class="nx">model</span><span class="o">=</span><span class="nx">item</span><span class="p">.</span><span class="nx">selected</span> <span class="nx">ng</span><span class="o">-</span><span class="nx">click</span><span class="o">=</span><span class="s2">"$parent.checkAction(item)"</span> <span class="o">&gt;</span> </code></pre> </div> <p>That might have been worth reading this blog entry alone if you’d been in a pinch. (LOL).</p> <p>I could point out more in the template above, but most of it is basic sorting and filtering mechanisms that make AngularJS so easy to use for state centric displays.</p> <p>I will -not- share the two controllers code with you. They’re very basic scaffolds to let the demo actually do something when you click.</p> <p>Again, <a class="markdown-external-link" target="_blank" href="http://rankarooski.com/#/angular-directive-demo">check out the live demo</a> <strong>And/Or</strong> you can check out the entire little sandbox in this <a class="markdown-external-link" target="_blank" href="https://github.com/Tom2277/angularjs-custom-directive-demo">angularjs-custom-directive-demo GitHub repository</a>.</p> <p>Within that Repo you can check out a few earlier iterations, AND check out my more extensive and ambitious handlebars solution to the same types of displays but with more robust and reusable controllers and interesting approaches to making the pages maintain display state without watches and two way binding.</p> <p>Post on that will be linked here soon!.</p> Angularjs Cors Template Error 2017-02-28T00:00:00-08:00 http://tomnorian.com/AngularJs-CORS-Template-error <p>If you’re like me you often learn new technologies by doing while you read the manuals.</p> <p>In re-exploring the preferred syntax for AngularJS directives, I was coding along with their <a class="markdown-external-link" target="_blank" href="https://docs.angularjs.org/guide/directive">developer guide</a> . I found that my Chrome browser was throwing cross origin errors when using simple examples like:</p> <div class="language-javascript highlighter-rouge"><pre class="highlight"><code> <span class="p">.</span><span class="nx">directive</span><span class="p">(</span><span class="s1">'myCustomer'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="p">{</span> <span class="na">restrict</span><span class="p">:</span> <span class="s1">'E'</span><span class="p">,</span> <span class="na">templateUrl</span><span class="p">:</span> <span class="s1">'templates/sortable-table.html'</span> <span class="p">};</span> <span class="p">});</span> </code></pre> </div> <p>The dev-tools console error:</p> <div class="highlighter-rouge"><pre class="highlight"><code> XMLHttpRequest cannot load file:///Users/tomnorian/Documents/tutorials/demo-code/templates/sortable-table.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource. </code></pre> </div> <p>I hadn’t had this problem in the past as I was usually running a NodeJS or Rails server…but when you’re learning code in the sandbox it might just be you and your sleek code editor. <!--more--></p> <p>I came across this StackOverflow thread which is still <a class="markdown-external-link" target="_blank" href="http://stackoverflow.com/questions/27742070/angularjs-error-cross-origin-requests-are-only-supported-for-protocol-schemes">a good resource for this CORS issue</a>.</p> <p>The problem seems to be more isolated to Google Chrome, although at it’s essence they are putting in a good security constraint on the browser. The best work-arounds from the thread were to serve your static development project, or use an IDE that does, rather than relying on simply opening the HTML pages directly as you usually can.</p> <p>A really nice open source tool is created and maintained here: <a class="markdown-external-link" target="_blank" href="https://github.com/indexzero/http-server">http-server:a command-line HTTP server</a></p> <p>If you have node installed on your development machine all you need to do is:</p> <div class="language-bash highlighter-rouge"><pre class="highlight"><code> npm install http-server -g </code></pre> </div> <p>to use it their directions are:</p> <div class="language-bash highlighter-rouge"><pre class="highlight"><code> http-server <span class="o">[</span>path] <span class="o">[</span>options] </code></pre> </div> <p><strong>More explicitly:</strong></p> <ul> <li>you can simply navigate to the folder of your project you would like to serve and then type ‘http-server’ in your bash terminal to have that directory you are in served as a root.</li> </ul> <p>What you’ll see:</p> <div class="language-bash highlighter-rouge"><pre class="highlight"><code> demo-code :&gt; http-server Starting up http-server, serving ./ Available on: http://127.0.0.1:8080 http://10.0.0.5:8080 Hit CTRL-C to stop the server <span class="o">[</span>Wed Mar 01 2017 11:30:13 GMT-0800 <span class="o">(</span>PST<span class="o">)]</span> <span class="s2">"GET /index.html"</span> <span class="s2">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"</span> </code></pre> </div> <p>Open your browser to http://127.0.0.1:8080 and if you have a index.html file it will be served to you; or type in the filenames (with additional relative paths, if nested) to see them.</p> <p>That quickly got me around the Chrome CORS issue and onto working AngularJS directive templates; working directly from Sublime Text 2 and Chrome.</p> <p>This post is mostly to give those guys working on the http-server some well deserved love!</p> A Liquid Tag Cloud For Jekyll Blogs 2017-02-21T00:00:00-08:00 http://tomnorian.com/a-liquid-tag-cloud-for-jekyll-blogs <p>Even though Jekyll is a “static” site generator, with a little ingenuity you can give add many rich features to the generated site.</p> <p>I wanted a tag-cloud! A good tag cloud. You know, one where the tags showed the number of posts next to them as well as growing in size according to the number of posts. One like you see to the left or in the lead image of this post.(yay!)</p> <p>I also wanted a tagging system that allowed me to combine tags for posts and tags in Jekyll collections: the built-in Jekyll category and tag system doesn’t currently handle tags in collections.</p> <p>To create an across all posts and an across all collections tag system just requires a name other than ‘tags’. You’ll use that custom-tag name in front matter array just as you would add the standard tags to a post. <!--more--></p> <p>Using a custom tag system does lead to some extra looping as you’ll see below. As this tagging system does not use plugins, I believe it could work on a GitHub deployment… no promises there.( I would love to hear if it works at GitHub, though )</p> <p><strong>Issues and Apologies</strong></p> <p>Everything I’ve learned and all my gut wants me to use a hash-map, create the view-partial only once, and keep the time complexity, “big O” to a reasonable level.</p> <p>This solution, forced by the limitations of Jekyll and Liquid in their pursuit of simplicity, loops over every post numerous times. There is the nested loop of looking at every content item for each unique tag after we’ve also loop through all the posts to find unique tags. Clearly a hash tags as keys and values comprised of arrays of associated posts would take a single pass with a second pass to render the tags of various sizes and item counts. If I had used their tag system it could have been a few steps more efficient(but again, that wouldn’t work for collection-tags)</p> <p>Even worse, (yes it gets worse), the generator recreates the the tag map for each page….we’re almost looking at O cubed.</p> <p><strong>Why haven’t I found a work around for that?</strong> I could use a plugin to find the unique tags and set an environmental variable for that. There are also techniques to generate the tag-cloud once using rake or gulp, or even just generate a static page onto a blank layout normally and cutting and pasting it into an _include. To some degree, the simplicity is part of the Jekyll philosophy. These posts might stimulate thoughts on better work-arounds and I’d love to hear ideas. <a class="markdown-external-link" target="_blank" href="http://stackoverflow.com/questions/30523270/jekyll-generate-an-include-once-and-include-it-to-all-pages">Generate an _include file Once at StackOverflow</a> and <a class="markdown-external-link" target="_blank" href="https://github.com/jekyll/jekyll/issues/5868">Define and Compute custom Variables at the Jekyll Github Repository</a>.</p> <p>It would be really nice to be able to us a plugin generate an “_include” or YAML data file.</p> <p>In the end, this current method will work with the number of posts I anticipate making while maintaing the basic Jekyll work-flow. Because we’re generating a static site none of the redundant calculations will effect client experience, there is no database load(as there isn’t one), and it is certainly more simple for non-developers to use. If the number of posts scaled to the point that the generation was impeding workflow, it would be easy enough to comment out the tag-cloud generation for all but the times you were going to push your new content to a production server.</p> <p><strong>On to the code:</strong></p> <p>The comments should explain how it works:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="c">&lt;!-- Create empty arrays to push to --&gt;</span> {% assign many_tags = '' | split: ',' %} {% assign unique_tags = '' | split: ',' %} <span class="c">&lt;!-- get all tags --&gt;</span> {% for c in site.collections %} <span class="c">&lt;!-- Map and flatten --&gt;</span> {% assign collectionTags = c.docs | map: 'subject-tags' | join: ',' | split: ',' %} <span class="c">&lt;!-- Push to tags --&gt;</span> {% for tag in collectionTags %} {% assign many_tags = many_tags | push: tag %} {% endfor %} {% endfor %} <span class="c">&lt;!-- Get Unique subject-tags --&gt;</span> {% assign unique_tags = many_tags | uniq | sort %} <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"tag-cloud"</span><span class="nt">&gt;</span> <span class="c">&lt;!-- go through each tag, find content-items with that tag --&gt;</span> {% for cloud-tag in unique_tags %} <span class="c">&lt;!-- initiate an array to hold related content-items --&gt;</span> {% assign tags_posts = '' | split: ',' %} <span class="c">&lt;!-- go through every collection (posts is also a collection) --&gt;</span> {% for c in site.collections %} <span class="c">&lt;!-- every item in that collection --&gt;</span> {% for content-item in c.docs %} <span class="c">&lt;!-- every subject-tag that a content-item has --&gt;</span> {% for subtag in content-item.subject-tags %} <span class="c">&lt;!-- check if this content item matches the current tag and if so push--&gt;</span> {% if subtag == cloud-tag %} {% assign tags_posts = tags_posts | push: content-item %} {% endif %} {% endfor %} {% endfor %} {% endfor %} <span class="c">&lt;!-- check number of content-items (note, trying simple numeric index had some issues with liquid )--&gt;</span> <span class="c">&lt;!-- as you make more posts you will want to change the thresholds for size to your taste --&gt;</span> {% assign tag-quant = tags_posts | size %} {% if tag-quant <span class="nt">&lt; 3</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-1"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">elsif</span> <span class="na">tag-quant</span> <span class="err">&lt;</span> <span class="na">5</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-2"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">elsif</span> <span class="na">tag-quant</span> <span class="err">&lt;</span> <span class="na">8</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-3"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">elsif</span> <span class="na">tag-quant</span> <span class="err">&lt;</span> <span class="na">12</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-4"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">elsif</span> <span class="na">tag-quant</span> <span class="err">&lt;</span> <span class="na">18</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-5"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">else</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">assign</span> <span class="na">tag-cloud-size =</span><span class="err"> </span><span class="s">"tag-cloud-size-6"</span> <span class="err">%}</span> <span class="err">{%</span> <span class="na">endif</span> <span class="err">%}</span> <span class="err">&lt;!</span><span class="na">--</span> <span class="na">Now</span> <span class="na">generate</span> <span class="na">HTML</span> <span class="na">for</span> <span class="na">the</span> <span class="na">given</span> <span class="na">tag</span> <span class="na">--</span><span class="nt">&gt;</span> <span class="c">&lt;!-- The links are to an index page that uses very similar code --&gt;</span> {% if tag-quant &gt; 0 %} <span class="c">&lt;!-- catch corner case of blank element in array --&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"/site-index.html#{{ cloud-tag|slugify }}"</span><span class="nt">&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"tag-cloud-full-tag"</span> <span class="nt">&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"tag-cloud-title {{tag-cloud-size}}"</span><span class="nt">&gt;</span>{{cloud-tag}}<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"tag-cloud-quantity"</span><span class="nt">&gt;</span>({{tag-quant}})<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;/a&gt;</span> {% endif %} {% endfor %}<span class="c">&lt;!-- do it again for the next tag - Yes, holy-loop-ville --&gt;</span> <span class="c">&lt;!-- NOTE - remove all comments as dozens of them will show up in the generated HTML --&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <p>Yes, there are a lot of loops in there, and like I mentioned in the preceding section, we do this for every page with a tag cloud on it. If I were going to have thousands of pages I would create a static page, with or without a plugin, and do the cut and paste hack I mentioned.</p> <p>There are also a number of contortions to fit Liquid quirks like the technique of initiating the empty arrays to push to and the use of finding the size of an array of objects rather than an incrementing variable.</p> <p>You’ll note that the tags are links to the tag location on an index page.</p> <p><strong>CSS:</strong></p> <div class="language-css highlighter-rouge"><pre class="highlight"><code><span class="nc">.tag-cloud</span><span class="p">{</span> <span class="nl">margin</span><span class="p">:</span> <span class="m">0px</span> <span class="m">0px</span> <span class="m">0px</span> <span class="m">-5px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-full-tag</span><span class="p">{</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">scale</span><span class="p">(</span><span class="m">1.0</span><span class="p">);</span> <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">525ms</span> <span class="n">ease-out</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="nl">padding</span><span class="p">:</span> <span class="m">.1em</span><span class="p">;</span> <span class="nl">border-radius</span><span class="p">:</span> <span class="m">4px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-full-tag</span><span class="nd">:hover</span><span class="p">{</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">scale</span><span class="p">(</span><span class="m">1.35</span><span class="p">);</span> <span class="nl">background-color</span><span class="p">:</span> <span class="err">$</span><span class="n">main-background</span><span class="p">;</span> <span class="nl">opacity</span><span class="p">:</span> <span class="m">1</span><span class="p">;</span> <span class="nl">z-index</span><span class="p">:</span> <span class="m">600</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-title</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">.tag-cloud-size-1</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">.7em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-size-2</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">.9em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-size-3</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1.1em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-size-4</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1.25em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-size-5</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1.5em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-size-6</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1.7em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.tag-cloud-quantity</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">.5em</span><span class="p">;</span> <span class="nl">margin-left</span><span class="p">:</span> <span class="m">-.2em</span><span class="p">;</span> <span class="nl">z-index</span><span class="p">:</span> <span class="m">700</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p><strong>Do you want the index page too?</strong></p> <div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <button data-toggle="collapse" data-target="#index-page-code"> Site-Index page code </button> </h4> </div> <div id="index-page-code" class="panel-collapse collapse"> <div class="panel-body"> <div class="language-html highlighter-rouge"><pre class="highlight"><code> --- layout: side-nav page-label: Site Index permalink: /site-index.html --- {% assign many_tags = '' | split: ',' %} {% assign unique_tags = '' | split: ',' %} {% for c in site.collections %} {% assign collectionTags = c.docs | map: 'subject-tags' | join: ',' | split: ',' %} {% for tag in collectionTags %} {% assign many_tags = many_tags | push: tag %} {% endfor %} {% endfor %} {% assign unique_tags = many_tags | uniq | sort %} {% for index-tag in unique_tags %} {% assign tags_posts = '' | split: ',' %} {% for c in site.collections %} {% for item in c.docs %} {% for subtag in item.subject-tags %} {% if subtag == index-tag %} {% assign tags_posts = tags_posts | push: item %} {% endif %} {% endfor %} {% endfor %} {% endfor %} {% assign tag-quant= tags_posts | size %} {% if tag-quant &gt; 0 %} <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"{{ index-tag|slugify }}"</span> <span class="na">class=</span><span class="s">"subject-tag-container well well-sm"</span> <span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"site-index-label"</span><span class="nt">&gt;</span> <span class="nt">&lt;h2&gt;</span> {{index-tag}} <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">&gt;</span>{{ tags_posts | size }}<span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"#{{index-tag|slugify}}"</span><span class="nt">&gt;</span> <span class="nt">&lt;i</span> <span class="na">class=</span><span class="s">"site-index-target-toggle fa fa-plus-square pull-right"</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">&gt;&lt;/i&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/h2&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;table&gt;</span> {% for content-item in tags_posts %} <span class="nt">&lt;tr&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"../images/{{content-item.lead-image}}"</span> <span class="na">alt=</span><span class="s">""</span><span class="nt">&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;td&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"{{content-item.url}}"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"site-index-title"</span><span class="nt">&gt;</span> {{content-item.post-title}} <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"site-index-subtitle"</span><span class="nt">&gt;</span> {{content-item.subtitle}} <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;/td&gt;</span> <span class="nt">&lt;/tr&gt;</span> {% endfor %} <span class="nt">&lt;/table&gt;</span> <span class="nt">&lt;/div&gt;</span> {% endif %} {% endfor %} </code></pre> </div> <p>And then there is the SCSS (not currently in pure CSS form) Note the use of the :target pseudo element.</p> <div class="language-scss highlighter-rouge"><pre class="highlight"><code><span class="nc">.site-index-label</span><span class="p">{</span> <span class="nt">h2</span><span class="p">{</span> <span class="nl">padding-top</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span> <span class="nl">margin-top</span><span class="p">:</span> <span class="m">0px</span><span class="p">;</span> <span class="nc">.site-index-target-toggle</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span> <span class="nl">font-size</span><span class="p">:</span> <span class="mi">.7em</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="nc">.subject-tag-container</span><span class="p">{</span> <span class="nl">width</span><span class="p">:</span> <span class="m">300px</span><span class="p">;</span> <span class="nl">font-size</span><span class="p">:</span> <span class="mi">.9em</span><span class="p">;</span> <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">525ms</span> <span class="n">ease</span><span class="p">;</span> <span class="nl">background-color</span><span class="p">:</span> <span class="nv">$main-background</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="nt">li</span><span class="p">{</span> <span class="nl">list-style-type</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span> <span class="p">}</span> <span class="nt">img</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span> <span class="p">}</span> <span class="k">&amp;</span><span class="nd">:target</span><span class="p">{</span> <span class="nl">box-shadow</span><span class="p">:</span> <span class="m">5px</span> <span class="m">5px</span> <span class="m">5px</span> <span class="nv">$title-text</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span> <span class="m">600px</span><span class="p">;</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1</span><span class="mi">.2em</span><span class="p">;</span> <span class="nt">a</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="nv">$link-two</span><span class="p">;</span> <span class="k">&amp;</span><span class="nd">:hover</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="nv">$link-hover</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="nt">img</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="n">initial</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span> <span class="m">80px</span><span class="p">;</span> <span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span> <span class="m">0px</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.site-index-target-toggle</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="nt">tr</span><span class="p">{</span> <span class="nl">padding-bottom</span><span class="p">:</span> <span class="m">1em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.site-index-title</span><span class="p">{</span> <span class="c1">// font-size: .8em; </span> <span class="nl">padding-left</span><span class="p">:</span> <span class="m">1em</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.site-index-subtitle</span><span class="p">{</span> <span class="nl">font-size</span><span class="p">:</span> <span class="mi">.8em</span><span class="p">;</span> <span class="nl">padding-left</span><span class="p">:</span> <span class="m">2em</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> </div> <div class="panel-footer">Cheers!</div> </div> </div> </div> <!-- use a syntax like this NOTE spaces have been put in between { and % to allow these comments { % capture text-capture % } ```javascript function someFunction(x){ return x = 2X } ``` That was a double it function. { % endcapture % } { % include widgets/toggle-field.html button="See the Code" toggle-text=text-capture footer= "type your footer string" % } --> <p>….for a completely cheesy finish:</p> <p><strong>Hover over this:</strong></p> <div class="demo-thats-all-container"> <div class="demo-thats-all-folks"> That's All Folks </div> </div> Toggle Code Display Jekyll 2017-02-20T00:00:00-08:00 http://tomnorian.com/toggle-code-display-jekyll <p>In a previous post I described how you can use variables in ‘_includes’. I took advantage of those variables to create a ‘widget’ that allowed something similar to extending liquid with a plugin created tag.</p> <p>In this post I take the same approach to create a widget that creates a data-toggle element to hide blocks of code or text you might only want available to readers on demand. (demo follows later)</p> <p>We’re already using Bootstrap through-out the template we may as well use their tool here as well. Behind the scenes Bootstrap uses JQuery so this isn’t a pure HTML solution but it is an easily reusable element you can access directly while creating markdown content.</p> <p>I’ve gave the ‘widget’ a name of <strong>toggle-field.html</strong> and placed it within a ‘widgets’ folder inside the _includes folder.</p> <p><strong>Directions:</strong> This is how you use the ‘widget’:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> {% capture text-capture %} ```html <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-container"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-folks"</span><span class="nt">&gt;</span> That's All Folks <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> \``` <span class="c">&lt;!-- remove escape '\' in your code --&gt;</span> {% endcapture %} {% include widgets/toggle-field.html toggle-name="toggle-thats" button-text="Cod for Thats All Folks" toggle-text=text-capture footer="cheers!" %} </code></pre> </div> <p><strong>where:</strong></p> <ul> <li><strong>button</strong> allows for a custom button name (defaults to “Open” if omitted) <!--more--></li> <li><strong>toggle-text</strong> is the markdown text that is captured between the curly liquid brackets</li> <li><strong>footer</strong> is for an optional label in the toggle block footer.</li> </ul> <p><strong>how ‘capture’ works:</strong></p> <p>As you can see in the code screen-shot, you’ll need to use Jekyll’s ‘capture’ variable assignment via the liquid capture tags.</p> <p>I use the shorthand notation of three ‘`’s for code blocks, but that is just standard markdown and any markdown, will work between the capture and endcapture tags.</p> <p>Copy, paste and substitute content and you’ll have toggle-blocks quickly accessible.</p> <p>Here is the above code in action:</p> <div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <button data-toggle="collapse" data-target="#toggle-thats"> Code for Thats All Folks </button> </h4> </div> <div id="toggle-thats" class="panel-collapse collapse"> <div class="panel-body"> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-container"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-folks"</span><span class="nt">&gt;</span> That's All Folks <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> </div> <div class="panel-footer">cheers!</div> </div> </div> </div> <!-- use a syntax like this NOTE spaces have been put in between { and % to allow these comments { % capture text-capture % } ```javascript function someFunction(x){ return x = 2X } ``` That was a double it function. { % endcapture % } { % include widgets/toggle-field.html button="See the Code" toggle-text=text-capture footer= "type your footer string" % } --> <p>This second example show’s that this toggle ‘widget’ with any markdown…not just code-blocks.</p> <div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <button data-toggle="collapse" data-target="#toggle-two"> This Toggle has no Code </button> </h4> </div> <div id="toggle-two" class="panel-collapse collapse"> <div class="panel-body"> <h3 id="the-rain-in-spain-falls-mainly-on-the-plain">The rain in Spain falls mainly on the plain.</h3> <ul> <li>How much wood could a woodchuck chop if a woodchuck could chop wood?</li> </ul> </div> <div class="panel-footer">See, no Code</div> </div> </div> </div> <!-- use a syntax like this NOTE spaces have been put in between { and % to allow these comments { % capture text-capture % } ```javascript function someFunction(x){ return x = 2X } ``` That was a double it function. { % endcapture % } { % include widgets/toggle-field.html button="See the Code" toggle-text=text-capture footer= "type your footer string" % } --> <hr /> <p>Behind the scenes, this is the ‘_includes/widgets/toggle-field.html’ ‘widget’ :</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"panel-group"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">&gt;</span> <span class="nt">&lt;h4</span> <span class="na">class=</span><span class="s">"panel-title"</span><span class="nt">&gt;</span> <span class="nt">&lt;button</span> <span class="na">data-toggle=</span><span class="s">"collapse"</span> <span class="na">data-target=</span><span class="s">"#{{include.toggle-name}}"</span> <span class="nt">&gt;</span> {% if include.button-text %} {{include.button-text}} {% else %} Open {% endif %} <span class="nt">&lt;/button&gt;</span> <span class="nt">&lt;/h4&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"{{include.toggle-name}}"</span> <span class="na">class=</span><span class="s">"panel-collapse collapse"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">&gt;</span>{{include.toggle-text | markdownify }}<span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"panel-footer"</span><span class="nt">&gt;</span>{{include.footer}}<span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <p>Note the use of the humorously(to me at least) named liquid filter ‘markdownify’ which translates the captured markdown.</p> <p><strong>Why? Does this really make writing a blog easier?</strong></p> <p>While writing a blog using Jekyll doesn’t have a flashy GUI, getting accustomed to markdown isn’t hard.</p> <p>It is true that more of these ‘widgets’ you use, the more Domain Specific Languages you have to remember. That said, these things like inline photos and toggle text boxes take a bit of a learning curve even within a fancy CMS.</p> <p>Keep the code snippets easy to copy and paste and fill in the variables: the extra media in your posts really helps.</p> Variables In Jekyll Includes 2017-02-17T00:00:00-08:00 http://tomnorian.com/variables-in-jekyll-includes <p><strong>Custom reusable ‘_includes’</strong> - <strong>Alternatives to Plugins</strong></p> <p>This Jekyll Template uses a few ‘plugins’. We have one plugin to allow markdown snippets to be included in HTML pages, and another for external links.</p> <p>While plugins like those let you use custom Liquid tags in your markup, I have a few issues with them. It took a lot of parsing to separate values you want to pass. The custom parsing also made it harder to extend those plugins, and lastly, you had to remember a lot more syntax when utilizing the tags</p> <p>That all lead me to think, “there has to be a better way”. I wanted to be able to pass data using mutiple variables and it turns out you can do just that.</p> <p>We learn by Googling and Experimenting.</p> <p><strong>My first Widget</strong></p> <p>I’m not sure what to call this sort of reusable _include, but “widgets” works well enough. I needed to call them something to keep the includes directory tidy.</p> <p>In Googling the use of variables within ‘liquid’ tags, I cam across <a class="markdown-external-link" target="_blank" href="http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll">this StackOverflow post</a> on how to include a caption on a photo. <!--more--> I wanted to do was similar: creating way to put inline photo’s within my markdown in a way that I could easily not only include caption and ‘alt’ fields, but also adjust the width of a photo.</p> <p>It turned out to be a very straightforward thing to do that really makes it easier to have more media within a post.</p> <p><strong>How to use variables with includes</strong></p> <p>It’s simple.</p> <p>Here is a standard _include that you might use to insert your site title and slogan partial named ‘title-group.html’</p> <div class="language-markdown highlighter-rouge"><pre class="highlight"><code> {% include title-group.html %} </code></pre> </div> <p>You could pass that ‘title-group.htm’ a variable to customize that slogan.</p> <div class="language-markdown highlighter-rouge"><pre class="highlight"><code> {% include title-group.html custom-slogan="whatever you say dude" %} </code></pre> </div> <p>Now, before moving to how that works lets consider the limitations of basic markdown images.</p> <p>Here is how you can use the most basic markdown image tag:</p> <div class="language-markdown highlighter-rouge"><pre class="highlight"><code> !<span class="p">[</span><span class="nv">alt text</span><span class="p">](</span><span class="sx">https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png</span> <span class="nn">"Logo Title Text 1"</span><span class="p">)</span> </code></pre> </div> <p>But, what if you want to change it’s width or add a caption? And, without a class, you’d have a hard time styling those inline images.</p> <p>Here’s the solution I came up with.</p> <p><strong>Directions for inserting Inline images in your blog posts</strong></p> <p>Cut and paste the code below and substitute and delete as desired:</p> <div class="language-markdown highlighter-rouge"><pre class="highlight"><code> {% include image-inline.html url="/images/subfolder-in-images/filename.png" width="33%" alt=page.post-title caption="whatever you want here(or nothing)" class="optional-further-styling-class" %} </code></pre> </div> <ul> <li> <p><strong>url</strong> is the path to the image</p> </li> <li> <p><strong>width</strong> is a string with a number and the ‘%’ symbol (“100%” will span the full text collumn, “33%”” will have blog text wrap around the third it takes up)</p> </li> <li> <p><strong>url</strong> is what screen readers see as well as having important SEO ramifications. You can set it with front matter like I did or include custom text like “whatever words give me the best Google score”</p> </li> <li> <p><strong>caption</strong> is a bold lable text directly beneath the photo. Like with “alt” you could use front matter instead.</p> </li> <li> <p><strong>class</strong> another optional, field, this would help you style different types of inserts(maybe you wanted all table images have a border?).</p> </li> </ul> <hr /> <p><em>If you just want to use this feature you don’t need to read the rest of this: follow the instructions in the section immediately above.</em></p> <p><strong>HTML:</strong> Here is the markup that the using the “image-inline.html” include ‘widget’ will generate:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"tn-image-inline {{include.class}}"</span> <span class="na">style=</span><span class="s">"width:{{include.width}}"</span><span class="nt">&gt;</span> <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"{{ include.url }}"</span> <span class="na">alt=</span><span class="s">"{{ include.alt }}"</span> <span class="na">title=</span><span class="s">"{{include.caption}}"</span> <span class="na">width=</span><span class="s">"100%"</span><span class="nt">&gt;</span> <span class="nt">&lt;label</span> <span class="na">class=</span><span class="s">"tn-image-inline-caption"</span><span class="nt">&gt;</span>{{ include.caption }}<span class="nt">&lt;/label&gt;</span> <span class="nt">&lt;/span&gt;</span> </code></pre> </div> <p><strong>CSS:</strong></p> <div class="language-css highlighter-rouge"><pre class="highlight"><code><span class="nc">.tn-image-inline</span><span class="p">{</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</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">20px</span> <span class="m">0px</span> <span class="m">0px</span><span class="p">;</span> <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>I’m really glad I can use Jekyll create these reusable widgets. They do walk a line towards expanding the liquid domain specific language but short of a GUI on a CMS, it’s a very simple way to go.</p> <p>In another post I show how to use the same concept to <a href="/toggle-code-display-jekyll.html">create togglable page sections</a></p> Css Only Tootips 2017-02-15T00:00:00-08:00 http://tomnorian.com/css-only-tootips <p>There are countless tricks to add a little motion to the page CSS and HTML alone; while I love JavaScript and JQuery, if you can find a native CSS solution it is good practice to take it.</p> <p>I’m not a web-designer so, perhaps it’s silly for me to even post on this. There are terrific references out there on the web and these are pretty basic.</p> <p>Still, because I used these within this blog’s Jekyll template, I thought I’d point out how they work.</p> <p><strong>None of the code below requires Jekyll.</strong></p> <p>Hover over the portions of the sentence below(I’ll explain the code after):</p> <div class="demo-swell-tooltip"> <div>Demo:</div> <span class="demo-swell"> See something SWELL. </span> <div class="demo-tooltip-trigger"> The modal box tool-tip is on the top right on this one. <div class="demo-tooltip"> This tool tip is in absolute position to the parent 'div'. </div> </div> <div> No, the text around the resized items doesn't move! </div> </div> <p>With the use of “_includes” and Jekyll variables you can use front matter to populate more complex ‘flyouts’ like I use on my “about-me” page.</p> <p>Both of the above examples are really simple.</p> <p><strong>HTML:</strong> There really isn’t anything to this, other than the nested tool-tip div which will be hidden until the hover pseudo-class triggers: <!--more--></p> <div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-swell-tooltip"</span><span class="nt">&gt;</span> <span class="nt">&lt;div&gt;</span>Demo:<span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"demo-flyout-left"</span><span class="nt">&gt;</span> See something SWELL. <span class="nt">&lt;/span&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-for-top-right"</span><span class="nt">&gt;</span> The modal box tool-tip is on the top right on this one. <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-tooltip"</span><span class="nt">&gt;</span> This tool tip is in absolute position to the parent 'div' <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div&gt;</span> No, the text around the resized items doesn't move! <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <p><strong>CSS:</strong></p> <p>Be sure to make the <strong>span</strong> container: <code class="highlighter-rouge">position: relative</code> and</p> <ul> <li> <p>If you’d like it smooth, use a transition effect like ‘ease’: <code class="highlighter-rouge">transition: all 525ms ease;</code></p> </li> <li> <p>for the ‘swelling’ technique to transition both ways set the initial scale to 1 <code class="highlighter-rouge">transform: scale(1.0);</code>.</p> </li> </ul> <p>On the <strong>:hover</strong> pseudo-class all you really need for the ‘swelling’ is</p> <ul> <li>the size you want to increase to <code class="highlighter-rouge">transform: scale(2.7);</code></li> <li>and to be sure to set the z-index in front of the other content if you use a background color especially <code class="highlighter-rouge">z-index: 600;</code></li> </ul> <p>Here is the CSS for the swell effect including some stying for a change in color</p> <p>Note the class name and hover syntax:</p> <div class="language-css highlighter-rouge"><pre class="highlight"><code> <span class="nc">.demo-flyout-left</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="no">green</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">scale</span><span class="p">(</span><span class="m">1.0</span><span class="p">);</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">525ms</span> <span class="n">ease</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.demo-flyout-left</span><span class="nd">:hover</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span> <span class="nl">background-color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">scale</span><span class="p">(</span><span class="m">2.7</span><span class="p">);</span> <span class="nl">z-index</span><span class="p">:</span> <span class="m">600</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <hr /> <p><strong>CODE:</strong> for a simple tool-tip:</p> <p>Here I’m using the “absolute” property as well as “display: none” to reveal the tool tip upon hovering over a trigger “&lt;span&gt;”.</p> <p>Note: you also have choices of hiding the elements with <code class="highlighter-rouge">opacity: 0</code> or <code class="highlighter-rouge">visibility: hidden</code> as alternatives to the <code class="highlighter-rouge">display: none</code> I use here. Here is a <a class="markdown-external-link" target="_blank" href="http://stackoverflow.com/questions/272360/does-opacity0-have-exactly-the-same-effect-as-visibilityhidden/273076#273076">discussion of the rendering differences at StackOverflow</a></p> <p><strong>HTML:</strong> Again, the HTML is very simple:</p> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-tooltip-trigger"</span><span class="nt">&gt;</span> The modal box tool-tip is on the top right on this one. <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-tooltip"</span><span class="nt">&gt;</span> This tool tip is in absolute position to the parent 'div' <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <p><strong>CSS:</strong></p> <p>The CSS is also very simple but, like CSS can be, it’s that ‘one thing’ you miss that gets you.</p> <p>The container or “trigger” span or div must be <code class="highlighter-rouge">position: relative</code> as well as an ‘display:inline-block’ element to give the position absolute something to anchor onto. You can then display the styled tooltip at offsets to the left, right, top, or bottom of the trigger block. (you’ll likely want to add a width, border, different colors too)</p> <p>As for the “trigger”, we use the CSS pseudo-element :hover again. The tooltip is initially hidden using <code class="highlighter-rouge">display:none</code> and drawn (see linked discussion) by changing the tip CSS to <code class="highlighter-rouge">display:inline-block</code> on hover.</p> <div class="language-css highlighter-rouge"><pre class="highlight"><code> <span class="nc">.demo-tooltip-trigger</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="no">navy</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.demo-tooltip</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.demo-tooltip-trigger</span><span class="nd">:hover</span> <span class="nc">.demo-tooltip</span><span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span> <span class="nl">background-color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span> <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="no">black</span><span class="p">;</span> <span class="nl">border-radius</span><span class="p">:</span> <span class="m">4px</span><span class="p">;</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">.75em</span><span class="p">;</span> <span class="nl">padding</span><span class="p">:</span> <span class="m">5px</span><span class="p">;</span> <span class="nl">z-index</span><span class="p">:</span> <span class="m">600</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span> <span class="m">160px</span><span class="p">;</span> <span class="nl">bottom</span><span class="p">:</span> <span class="m">.75em</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>Well, again, I’m not a designer and I haven’t broken any new ground here.</p> <p>That being said, from personal experience, I know it sometimes helps to see another example a specific use case.</p> <p>Now,</p> <p>….for a completely cheesy finish:</p> <p><strong>Hover over this:</strong></p> <div class="demo-thats-all-container"> <div class="demo-thats-all-folks"> That's All Folks </div> </div> <div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <button data-toggle="collapse" data-target="#toggle-thats-all"> Code for Thats All Folks </button> </h4> </div> <div id="toggle-thats-all" class="panel-collapse collapse"> <div class="panel-body"> <div class="language-html highlighter-rouge"><pre class="highlight"><code> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-container"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"demo-thats-all-folks"</span><span class="nt">&gt;</span> That's All Folks <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> </code></pre> </div> <div class="language-css highlighter-rouge"><pre class="highlight"><code> <span class="nc">.demo-thats-all-container</span><span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span><span class="nb">relative</span><span class="p">;</span> <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="nl">font-size</span><span class="p">:</span> <span class="m">1.5em</span><span class="p">;</span> <span class="nl">color</span><span class="p">:</span> <span class="no">maroon</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.demo-thats-all-folks</span><span class="p">{</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span> <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">525ms</span> <span class="n">ease</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.demo-thats-all-folks</span><span class="nd">:hover</span><span class="p">{</span> <span class="nl">font-family</span><span class="p">:</span> <span class="nb">cursive</span><span class="p">;</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">translateY</span><span class="p">(</span><span class="m">-5em</span><span class="p">)</span> <span class="n">rotate</span><span class="p">(</span><span class="m">360deg</span><span class="p">)</span> <span class="n">scale</span><span class="p">(</span><span class="m">4.0</span><span class="p">);</span> <span class="nl">background-color</span><span class="p">:</span> <span class="no">maroon</span><span class="p">;</span> <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span> <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">525ms</span> <span class="n">ease</span><span class="p">;</span> <span class="nl">z-index</span><span class="p">:</span> <span class="m">700</span><span class="p">;</span> <span class="nl">border</span><span class="p">:</span> <span class="nb">solid</span> <span class="m">2px</span> <span class="no">black</span><span class="p">;</span> <span class="nl">background</span><span class="p">:</span> <span class="no">maroon</span><span class="p">;</span> <span class="c">/* For browsers that do not support gradients */</span> <span class="nl">background</span><span class="p">:</span> <span class="n">-webkit-repeating-radial-gradient</span><span class="p">(</span><span class="nb">circle</span><span class="p">,</span> <span class="no">red</span><span class="p">,</span> <span class="no">maroon</span> <span class="m">10%</span><span class="p">,</span> <span class="no">black</span> <span class="m">15%</span><span class="p">);</span> <span class="c">/* For Opera 11.6 to 12.0 */</span> <span class="nl">background</span><span class="p">:</span> <span class="n">-o-repeating-radial-gradient</span><span class="p">(</span><span class="nb">circle</span><span class="p">,</span> <span class="no">red</span><span class="p">,</span> <span class="no">maroon</span> <span class="m">10%</span><span class="p">,</span> <span class="no">black</span> <span class="m">15%</span><span class="p">);</span> <span class="c">/* For Firefox 3.6 to 15 */</span> <span class="nl">background</span><span class="p">:</span> <span class="n">-moz-repeating-radial-gradient</span><span class="p">(</span><span class="nb">circle</span><span class="p">,</span> <span class="no">red</span><span class="p">,</span> <span class="no">maroon</span> <span class="m">10%</span><span class="p">,</span> <span class="no">black</span> <span class="m">15%</span><span class="p">);</span> <span class="c">/* Standard syntax */</span> <span class="nl">background</span><span class="p">:</span> <span class="n">repeating-radial-gradient</span><span class="p">(</span><span class="nb">circle</span><span class="p">,</span> <span class="no">red</span><span class="p">,</span> <span class="no">maroon</span> <span class="m">10%</span><span class="p">,</span> <span class="no">black</span> <span class="m">15%</span><span class="p">);</span> <span class="p">}</span> </code></pre> </div> </div> <div class="panel-footer">cheers!</div> </div> </div> </div> <!-- use a syntax like this NOTE spaces have been put in between { and % to allow these comments { % capture text-capture % } ```javascript function someFunction(x){ return x = 2X } ``` That was a double it function. { % endcapture % } { % include widgets/toggle-field.html button="See the Code" toggle-text=text-capture footer= "type your footer string" % } --> License And Directions 2017-02-14T00:00:00-08:00 http://tomnorian.com/license-and-directions <h4 id="for-alternative-access-i-include-the-read_memd-file-for-this-sites-jekyll-template-below">For alternative access, I include the READ_ME.md file for this site’s Jekyll template below:</h4> <hr /> <hr /> <hr /> <!--more--> <h2 id="cheap-and-easy-jekyll-blog-template-for-web-developers">Cheap and Easy Jekyll Blog Template for Web Developers</h2> <h3 id="usage">Usage</h3> <p>Once you have Jekyll fully installed clone the repository and delete my content in Posts, and the collection folders after you’ve used them as demos.</p> <pre><code>git clone https://github.com/Tom2277/tn-easy-weblog.io my-blog </code></pre> <h2 id="getting-started-with-jekyll-">Getting started with Jekyll ?</h2> <p>See my links in this post: <strong><a href="http://tomnorian.com">Jekyll Blogging for Web Developers</a></strong></p> <p>The post above discusses some of the choices I made as well as links to other posts about how some of the template features are implemented.</p> <p>You’ll also want to consult those external links for actual deployment.</p> <h3 id="global-variables">Global Variables</h3> <ul> <li>Go to the _global.yml file in the _data directory and substitute in your own information <ul> <li>Note that you’ll need to switch back and forth between the base URL of your local host and your production server address when you run the server locally.</li> </ul> </li> </ul> <h3 id="front-matter-conventions-for-this-template">Front-matter Conventions for this Template</h3> <ul> <li><strong>page-label:</strong> &lt; <em>optional page title that will appear in addition to the title of your post header</em> &gt; <ul> <li>for example Blog at the top of the blog role or Site-Index ? Attention Cat Owners for cat posts?</li> </ul> </li> <li><strong>post-title:</strong> &lt; <em>insert a title you want to give a post like “Wonder Cats”</em> &gt;</li> <li><strong>post-subtitle:</strong> &lt; insert a line like “including information on feeding”&gt;</li> <li><strong>lead-image:</strong> &lt; <em>image file name or URL within images folder i.e. my_photo.png or blog/my_phot.jpg</em> &gt; <ul> <li>This image will be displayed in post or collection item’s header and in menus*&gt;</li> </ul> </li> <li><strong>post.excerpt</strong> is standard Jekyll functionality (It does not need to be included in front matter.) <ul> <li>on this template, insert <strong>&lt;!–more–&gt;</strong> within your posts to set the break point.</li> </ul> </li> <li><strong>author:</strong> &lt; <em>type in name of author or creator(collection)</em> &gt; <ul> <li>optional: if left blank no author will appear</li> </ul> </li> <li><strong>subject-tags:</strong> &lt; <em>insert an array of tags on separate lines below with a ‘-‘ in front.</em>&gt; <ul> <li>‘Subject tags’ bypass the Jekyll tagging and category system. I chose this custom method to allow the same tags to work with both ‘posts’ and ‘collections’</li> </ul> </li> <li><strong>activity-tags</strong> &lt; <em>insert an array of tags on separate lines below with a ‘-‘ in front.</em>&gt; *</li> <li><strong>website-name:</strong> &lt; <em>external website-name under post image if desired</em>&gt;</li> <li><strong>website-url:</strong> &lt; <em>external website full URL if desired - will open in new tab</em> &gt;</li> </ul> <h3 id="markdown-info">Markdown info</h3> <ul> <li><strong>Kramdown</strong> This template uses the Kramdown flavor of mardown. Most standard markdown works</li> <li><strong>Code Blocks</strong> Use three back ticks followed by a lower case language name, on separate lines before and after your code. <ul> <li>this template uses the pygments gem an I’ve chosen the ‘monokai’ code highlighting scheme (with a few alterations).</li> <li>you can include a different color scheme by substituting it’s scss files in the appropriate folders</li> </ul> </li> <li><strong>See my blog for custom tags:</strong> external links, inline images, toggle code blocks, including markdown segments within HTML and more.</li> </ul> <h3 id="credits">Credits:</h3> <p>I initially started with the Bootstrap Blog template included with <strong><a href="https://scotch.io/tutorials/getting-started-with-jekyll-plus-a-free-bootstrap-3-starter-theme">this tutorial by Nicholas Cerminara at Scotch.io</a></strong>. There is little left of his code although his folder structure and a few css features, including pagination, still remain. Either way, thanks are due.</p> <p>The entire CSS layout structure is built using Twitter’s <strong><a href="http://getbootstrap.com/">Bootstrap</a></strong></p> <p>Most of all we need to thank the Jekyll community.</p> <p>You are welcome to reuse my code as per the following license. (as Twitter and N Cerminara used as well)</p> <h2 id="the-mit-license-mit">The MIT License (MIT)</h2> <p>Copyright (c) 2016-2017 Thomas Norian,</p> <p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p> <p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p> <p>THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p> Jekyll Blog For Web Developers 2017-02-01T00:00:00-08:00 http://tomnorian.com/jekyll-blog-for-web-developers <h3 id="why-a-blog-">Why a Blog ?</h3> <p>I’m using Jekyll to build a blog to share bits and pieces of my coding experiences. We all help each other out when we share approaches.</p> <h4 id="why-jekyll-">Why Jekyll ?</h4> <p>Jekyll is a tool that generates static HTML sites that have the rich features of blogs that use a CMS like Wordpress, Joomla, or Drupal.</p> <p><span class="tn-image-inline " style="width:30%"> <img src="/images/blog/jekyll-logo.png" alt="Try Jekyll Out" title="" width="100%" /> <label class="tn-image-inline-caption">Try out Jekyll</label> </span> You can deploy static HTML in a S3 bucket or using as simple web host. Many people use their free GitHub account (although there are some special circumstances for Github - but you can always push only the pre-compiled code).</p> <p>‘Cheap and Easy’ is good! You don’t need to spend time with server mechanics or pay that fee for a database that might cost you a night on the town every other month. <!--more--> Jekyll is written in ruby, but you really don’t need to use any ruby at all if you load a theme someone else has constructed. Use a text editor to write your content and fill in a few values for things like title, author and tags. You might want to learn something about Jekyll and “liquid”, a domain specific language, but you don’t need to to use the Template as it is.</p> <h4 id="sites-for-learning-jekyll">Sites for Learning Jekyll</h4> <p>I’m not going to reinvent the wheel. There are some great tutorials done by very experienced Jekyll users. To learn Jekyll and all it can do, visit:</p> <p><a class="markdown-external-link" target="_blank" href="https://jekyllrb.com/">JekyllRB, the primary Jekyll site </a>. with easy to read glossaries and more.</p> <p><a class="markdown-external-link" target="_blank" href="http://jekyll.tips/">JekyllTips JekyllCasts</a> is a really great beginner through intermediate site with both video and written tutorials, cheat sheets, and more.</p> <p><a class="markdown-external-link" target="_blank" href="https://scotch.io/tutorials/getting-started-with-jekyll-plus-a-free-bootstrap-3-starter-theme">Scotch.IO: Getting Started with Jekyll</a> I used this tutorial on my first Jekyll projects(although it might be getting dated). I got in a few habits from what I learned there.</p> <p>A Google search will find you others. Find one that’s right for you.</p> <h4 id="what-im-adding-with-this-post-a-template">What I’m adding with this post: a Template!</h4> <p>You are welcome to use and share this template that I’m using on this blog.</p> <p>Once you have Jekyll fully installed,(see the external tutorials above) you can install my template available here or using the following command:</p> <p>###NOT PUBLIC YET - (check back next week!)</p> <div class="language-bash highlighter-rouge"><pre class="highlight"><code> git clone https://github.com/Tom2277/jekyll-blog-template-private.git my-blog </code></pre> </div> <p>In other posts I will share code on how I created custom parts of the template:</p> <p><a href="/license-and-directions.html">License and Directions</a></p> <p><a href="/variables-in-jekyll-includes.html">Inline Photos</a></p> <p><a href="/toggle-code-display-jekyll.html">Toggle Sections</a></p>