<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Version Dos Blog]]></title><description><![CDATA[Welcome to our space! Here we post thoughts, stories and ideas, share news, experience and knowledge. You're welcome to write, comment and contribute.]]></description><link>https://blog.versiondos.com/</link><image><url>http://blog.versiondos.com/favicon.png</url><title>Version Dos Blog</title><link>https://blog.versiondos.com/</link></image><generator>Ghost 3.2</generator><lastBuildDate>Fri, 13 Feb 2026 05:10:29 GMT</lastBuildDate><atom:link href="https://blog.versiondos.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Organize your Javascript Code in Rails]]></title><description><![CDATA[These days you have way too many options, tools, gems, transpilers, compilers, modules and frameworks to make javascript work with your Rails application. I wanted a simple and useful way to keep my code clean and organized.]]></description><link>https://blog.versiondos.com/organize-your-javascript-in-rails/</link><guid isPermaLink="false">5e825d1d5a87c100011a2600</guid><category><![CDATA[Rails]]></category><category><![CDATA[Javascript]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Practices]]></category><category><![CDATA[OOP]]></category><category><![CDATA[OOD]]></category><category><![CDATA[Revealing Module Pattern]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[AJAX]]></category><category><![CDATA[MVC]]></category><dc:creator><![CDATA[Federico Schiefelbein]]></dc:creator><pubDate>Mon, 30 Mar 2020 21:01:14 GMT</pubDate><media:content url="http://blog.versiondos.com/content/images/2020/03/blog2.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.versiondos.com/content/images/2020/03/blog2.jpg" alt="Organize your Javascript Code in Rails"><p>These days you have way too many options, tools, gems, transpilers, compilers, modules and frameworks to make javascript work with your Rails application. I wanted a simple and useful way to keep my code clean and organized.</p><p>I use several concepts which I will be explaining in the following sections. I hope you will find it helpful for your projects.</p><p>First of all, some heads-ups, I still use Sprockets and the Assets Pipeline, I believe we will all be using Webpack in the near future but so far, my experience with it brought me more pain than gain.</p><p>I've dropped jQuery and embraced ES2015, Sprockets didn't play nice with ES2015 Modules so I keep on using the Revealing Module Pattern, which works pretty well for me.</p><p>In summary,</p><ul><li>No jQuery</li><li>No Webpack</li><li>Plain ECMAScript</li><li>Sprockets-Asset Pipeline</li><li>No ES Module syntaxes</li><li>No ES classes</li></ul><p>And these are the topics I tend to cover in the next posts</p><ol><li>Namespacing</li><li>Revealing Module Pattern</li><li>Mutation Observer</li><li>Fetch</li><li>HTML &amp; M10n</li><li>AJAX</li><li>Form submission</li></ol><p>I've created these modules to be used in a Rails application but they can also be uses in a plain HTML/JS page.</p><hr><h1 id="-1-namespacing">[1] Namespacing</h1><p>One of the issues you may have if you are not careful writing JavaScript is polluting the global space. As your app becomes bigger you may start suffering name collisions in your code.</p><p>In order to keep my code clean, I use namespaces and directories structure,</p><pre><code class="language-.">└─ myApp/
   └── assets/
       ├── javascripts/
       │  ├── myApp/
       │  │   ├── controllers/
       │  │   ├── core/
       │  │   └── dom/
       │  ├── myApp.init.js
       │  └── myApp.js
       └── application.js
</code></pre><p>Where myApp is the name of the Rails application. Inside /assets/javascripts/ you can use any name, I usually use the same application name. So far, I use three main directories <strong><strong>controllers</strong></strong>, <strong><strong>core</strong></strong> and <strong><strong>dom</strong></strong>, I will explain later how I use them.</p><p>Finally I use two initialization files <strong><strong>myApp.js</strong></strong> and <strong><strong>myApp.init.js</strong></strong>.</p><p>The application.js file is the standard sprockets manifesto file.</p><h4 id="the-root-file-myapp-js">The Root File - myApp.js</h4><p>The only responsibility of this file is to set all the namespaces. The convention is one namespace per directory.</p><pre><code class="language-javascript">window.myApp = {};  
window.myApp.Core = {};  
window.myApp.DOM = {};  
window.myApp.Controllers = {};  `  
</code></pre><h4 id="the-manifest-application-js">The Manifest - application.js</h4><p>As said before, this is the standard Sprockets manifesto file. We don't have anything yet to include from within the directories, only the root files. <strong><strong>myApp.init</strong></strong> file will be explained in the next section, <strong><strong>Revealing Module Pattern</strong></strong>.</p><p>It is worth mentioning that the first required file is <strong><strong>vendor.js</strong></strong>. This is a manifest file I add in a <strong><strong>vendor</strong></strong> directory at the Rails app root. I find very usefull to keep all 3rd party scripts separated.</p><pre><code class="language-javascript">//= require vendor
//= require myApp/myApp
//= require myApp/myApp.init
//= require myApp/dom/...
//= require myApp/core/...
//= require myApp/controllers/...
</code></pre><p>If you are including the 3rd party scripts in this fashion, remember to add the path to the Assets paths in your <strong><strong>assets.rb</strong></strong> file</p><pre><code class="language-ruby">Rails.application.config.assets.paths &lt;&lt; Rails.root.join("vendor", "assets")  
</code></pre><hr><h1 id="-2-revealing-module-pattern">[2] Revealing Module Pattern</h1><p>I won't be explaining this pattern here. You can find all you need to know at <a href="https://toddmotto.com/mastering-the-module-pattern/">Todd Motto's blog - Mastering The Module Pattern</a>.</p><p>In the scaffolding below, <strong><strong>myApp</strong></strong> is the name of your application (or the name of your choice) and <strong><strong>myNS</strong></strong> is the namespace where you want your module to be, don't forget to create the directory in the file tree and create the namespace in the root file. <br>I called the module with <strong><strong>window.myApp</strong></strong> so I have all the functionality available without polluting the global space.</p><pre><code class="language-javascript">window.myApp.myNS.myModule = ((myApp) =&gt; {  
  const settings = {
    settingName: settingValue
  };

  const actionName = () =&gt; {
    // do something
  };

  return {
    settings, publicActionName: actionName
  };
})(window.myApp);
</code></pre><p>If you need to use JQuery you can include jQuery as a parameter in the module and have its functionality available within the module. It would go like this,</p><p><code>window.myApp.myModule = ((myApp, $) =&gt; {   })(window.myApp, window.jQuery);</code></p><p>I always add a <strong><strong>settings</strong></strong> hash at the beginning of every module, I find it useful for configuring the module behaviour. Then come the actions, this is where the stuff is done.</p><p>Finally, the return section of the pattern, where the private is made public. You may want to change the name, if you wish to keep the same name just write it once, <strong><strong>privateName: privateName</strong></strong> is not necessary.</p><h2 id="initialization-file-myapp-init-js">Initialization file - myApp.init.js</h2><p>The initialization file allows you to run any required process before anything else.</p><p>Again, <strong><strong>myApp</strong></strong> is the current namespace and <strong><strong>Init</strong></strong> is the module name. The initialization file is one of the simplest modules. On its more basic form, it has only one goal, to kick off the <strong><strong>Observer</strong></strong>. This nice guy will enable us to do very useful stuff but, we will talk about it in the next section. Needless to say, I've added a method to be executed at the action <strong><strong>start</strong></strong> for illustrative purporses. Notice I kept the <strong><strong>_welcomeMessage</strong></strong> method private, it won't be available for the rest of the modules.</p><p>As mentioned before, this is your opportunity to add any action you wish to execute before anything else. This is the first piece of code to be executed and the only one I run by myself. The rest of the code will be triggered by events, this is not a limitation of the framework, you can run any module code at any time.</p><p>The last three lines of code is where I execute the <code>start();</code> action.</p><pre><code class="language-javascript">window.myApp.Init = ((myApp) =&gt; {  
  const settings = {
    message: "Starting myApp..."
  };

  const _welcomeMessage = (msg) =&gt; {
    console.log(msg);
  };

  const start = () =&gt; {
    _welcomeMessage(settings.message);
    myApp.Core.Observer.start();
  };

  return {
    start, settings
  };
})(window.myApp);

(function(myApp) {
  myApp.Init.start();
}(window.myApp));
</code></pre><hr><h1 id="-3-mutation-observer">[3] Mutation Observer</h1><p>As with the Revealing Module Pattern, I won't be explaining the Observer itself, but how to use it. You can find very good information at the <a href="https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver">Mozilla Developer Network - MutationObserver</a>.</p><p>The observer allows to watch any changes in the DOM tree and I use it to create Event Listeners.</p><h2 id="observer-js">Observer.js</h2><p>The Observer is part of the <strong><strong>Core</strong></strong> namespace. As every file, it follows the revealing module pattern.</p><p>Below the complete code of the module. I will go step by step.</p><pre><code class="language-javascript">window.myApp.Core.Observer = ((myApp) =&gt; {  
  const settings = {
    selector: 'controller',
    triggerSeparator: '-&gt;',
    controllerSeparator: '#',
    renderCustomEvent: 'render'
  };

  const start = (selector = settings.selector) =&gt; {
    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    const target = document;
    const config = { childList: true, subtree: true };
    const observer = new MutationObserver((mutations) =&gt; {
      let traversedNodes = new Array();
      for (let currentMutation = 0; currentMutation &lt; mutations.length; currentMutation++) {
        if (mutations[currentMutation].type === 'childList' &amp;&amp; mutations[currentMutation].addedNodes.length) {
          for (let currentAddedNode = 0; currentAddedNode &lt; mutations[currentMutation].addedNodes.length; currentAddedNode++) {
            if (mutations[currentMutation].addedNodes[currentAddedNode].nodeType === 1) {
              let traversedNodeFlag = false;
              for (let currentTraversedNode = 0; currentTraversedNode &lt; traversedNodes.length; currentTraversedNode++) {
                if (traversedNodes[currentTraversedNode] === mutations[currentMutation].addedNodes[currentAddedNode].parentNode) {
                  traversedNodeFlag = true;
                  break;
                }
              }
              traversedNodes.push(mutations[currentMutation].addedNodes[currentAddedNode]);
              if (traversedNodeFlag !== true) {
                let behavioralNodeList = mutations[currentMutation].addedNodes[currentAddedNode].querySelectorAll(`[data-${selector}]`);
                for (let currentBehavioralNode = 0; currentBehavioralNode &lt; behavioralNodeList.length; currentBehavioralNode++) {
                  let behaviors = behavioralNodeList[currentBehavioralNode].dataset[settings.selector].trim().split(/\s+/);
                  for (let currentBehavior = 0; currentBehavior &lt; behaviors.length; currentBehavior++) {
                    let trigger = behaviors[currentBehavior].substring(0, behaviors[currentBehavior].lastIndexOf(settings.triggerSeparator)); // trigger-&gt;controller#action
                    let controller = behaviors[currentBehavior].substring(trigger.length + 2, behaviors[currentBehavior].lastIndexOf(settings.controllerSeparator));
                    let action = behaviors[currentBehavior].substring(trigger.length + controller.length + 3);
                    if (window.myApp.Controllers[controller] === undefined) throw new Error(`Controller 'window.myApp.Controllers.${controller}' is not defined`);
                    if (window.myApp.Controllers[controller][action] === undefined) throw new Error(`Action 'window.myApp.Controllers.${controller}.${action}' is not defined`);
                    behavioralNodeList[currentBehavioralNode].addEventListener(trigger, window.myApp.Controllers[controller][action], false);
                    if (trigger == settings.renderCustomEvent) behavioralNodeList[currentBehavioralNode].dispatchEvent(new CustomEvent(settings.renderCustomEvent));
                  }
                }
              }
            }
          }
        }
      }
    });
    observer.observe(target, config);
  };

  return {
    settings,
    start
  };
})(window.myApp);
</code></pre><p>It is a bit lengthy but it is actually very simple. <br>As every module, it has its settings hash which allows to customize a few options.</p><p>The module has only one action, <strong><strong>start(<em>selector</em>)</strong></strong> which is the one we call from the <strong><strong>initialization file</strong></strong>. This is how it starts. The <strong><strong>selector</strong></strong> parameter will be used to identify which DOM elements are candidates for event binding.</p><pre><code class="language-javascript">const start = (selector = settings.selector)  
</code></pre><p>The next lines are for setting up the Mutation Observer object.</p><p>First, I setup the right interface according to the browser the visitor is using. The <strong><strong>target</strong></strong> is the DOM node the Observer will be observing, in this case, I want to observe the whole document. At last, I set what kind of changes I want to observe. The observer allows to observer attributes and even content changes. I only need to observe changes in the DOM tree, the default values are already false, but I'd rather be explicit.</p><pre><code class="language-javascript">  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  const target = document;
  const config = { childList: true, subtree: true, characterData: false, attributes: false };
</code></pre><p>Next, the observer is created. It uses a callback function with a parameter called <strong><strong>mutations</strong></strong> which registers the observed mutations. It follows an ugly bunch of nested loop-ifs, it traverses all the mutations in <strong><strong>mutations</strong></strong>, if the mutation is of the type <strong><strong>childlist</strong></strong> and the addedNodes is not empty, it means that a new node was created in the DOM tree. So I loop through all the added nodes. Then, I check the <strong><strong>nodeType</strong></strong> of the current added node is an ELEMENT<em>NODE and avoid anything else (TEXT, CDATA, DOCUMENT</em>TYPE, etc).</p><p>If the parentNode of the current node has already been examined, I skip the current node since it was already examined as a child node. This way I avoid duplicating event listeners on the same elements. <br>I push the value of the new traversed node to an array so it is considered in the next loop run.</p><p>If the node has not been traversed before, I examined it looking for <strong><strong>[data-${selector}]</strong></strong>, this means if I keep the default setting, I look for elements with [data-controller] data attribute from the current node down to all its children nodes. That's why I can avoid this step when traversing the children.</p><pre><code class="language-javascript">const observer = new MutationObserver((mutations) =&gt; {  
  let traversedNodes = new Array();
  for (let currentMutation = 0; currentMutation &lt; mutations.length; currentMutation++) {
    if (mutations[currentMutation].type === 'childList' &amp;&amp; mutations[currentMutation].addedNodes.length) {
      for (let currentAddedNode = 0; currentAddedNode &lt; mutations[currentMutation].addedNodes.length; currentAddedNode++) {
        if (mutations[currentMutation].addedNodes[currentAddedNode].nodeType === Node.ELEMENT_NODE) {
          let traversedNodeFlag = false;
          for (let currentTraversedNode = 0; currentTraversedNode &lt; traversedNodes.length; currentTraversedNode++) {
            if (traversedNodes[currentTraversedNode] === mutations[currentMutation].addedNodes[currentAddedNode].parentNode) {
              traversedNodeFlag = true;
              break;
            }
          }
          traversedNodes.push(mutations[currentMutation].addedNodes[currentAddedNode]);
</code></pre><p>The next lines are pretty simple, I loop over the Node List from the <em>querySelectorAll</em>, then I split, trim and substring the attribute value. By default, set in <em>settings</em>, the naming convention is <strong><strong>triggerName-&gt;controllerName#actionName</strong></strong>, if the controller or action is not defined, it throws an error, if it is all OK, an event listener is added.</p><p>Finally, if the event is <em>renderCustomEvent</em>, the event is dispatch immediately after adding the listener. This allows to run your action after the DOM element is rendered.</p><pre><code class="language-javascript">if (traversedNodeFlag !== true) {  
  let behavioralNodeList = mutations[currentMutation].addedNodes[currentAddedNode].querySelectorAll(`[data-${selector}]`);
  for (let currentBehavioralNode = 0; currentBehavioralNode &lt; behavioralNodeList.length; currentBehavioralNode++) {
    let behaviors = behavioralNodeList[currentBehavioralNode].dataset[settings.selector].trim().split(/\s+/);
    for (let currentBehavior = 0; currentBehavior &lt; behaviors.length; currentBehavior++) {
      let trigger = behaviors[currentBehavior].substring(0, behaviors[currentBehavior].lastIndexOf(settings.triggerSeparator));
      let controller = behaviors[currentBehavior].substring(trigger.length + 2, behaviors[currentBehavior].lastIndexOf(settings.controllerSeparator));
      let action = behaviors[currentBehavior].substring(trigger.length + controller.length + 3);
      if (window.myApp.Controllers[controller] === undefined) throw new Error(`Controller 'window.myApp.Controllers.${controller}' is not defined`);
      if (window.myApp.Controllers[controller][action] === undefined) throw new Error(`Action 'window.myApp.Controllers.${controller}.${action}' is not defined`);
      behavioralNodeList[currentBehavioralNode].addEventListener(trigger, window.myApp.Controllers[controller][action], false);
      if (trigger == settings.renderCustomEvent) behavioralNodeList[currentBehavioralNode].dispatchEvent(new CustomEvent(settings.renderCustomEvent));
    }
  }
}
</code></pre><p>The module finishes with its return section, making public the action start and it settings.</p><pre><code class="language-javascript">return {  
  settings,
  start
};
</code></pre><hr><h1 id="-4-fetch">[4] Fetch</h1><p>Another <strong><strong>Core</strong></strong> module is the one which handles all AJAX calls. Since the development of <em>Promises</em>, <em>Async/Await</em> and <em>Fetch</em>, javascript provides very simple tools to create our own AJAX calls without the usage of any library.</p><p>As I did with the <strong><strong>Observer</strong></strong>, I show the whole module and then go into details.</p><pre><code class="language-javascript">window.myApp.Core.Ajax = ((myApp) =&gt; {  
  const settings ={
    method: 'GET',
    body: null,
    options: {
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'include',
      headers: {"Accept": "application/json"},
      redirect: 'follow',
      referrer: 'about:client'
    },
    callbacks: {
      runBeforeSend: (event) =&gt; {
        // code to run always before the call
      },
      runOnFailure: (failure) =&gt; {
        console.log("myApp.Core.Ajax failed Fetch.", failure);
      },
      runOnError: (response) =&gt; {
        console.log('myApp AJAX Response Error: ', response);
      },
      runOnSuccess: (response) =&gt; {
        console.log('myApp AJAX Response Success: ', response);
      },
      runOnComplete: (event) =&gt; {
        // code to run always after the call
      }
    }
  };

  const fetch = async ({url, event, callbacks = settings.callbacks,
  method = settings.method, body = settings.body, options = settings.options}) =&gt; {
    let init = {
      method: method,
      body: body,
      mode: options.mode,
      cache: options.cache,
      credentials: options.credentials,
      headers: options.headers,
      redirect: options.redirect,
      referrer: options.referrer
    };
    event.preventDefault();
    callbacks.runBeforeSend(event);
    try {
      let response = await window.fetch(url, init);
      let data = await response.json();
      response.data = data;
      response.ok ? callbacks.runOnSuccess(response) : callbacks.runOnError(response);
    }
    catch (failure) {
      callbacks.runOnFailure(failure);
    }
    callbacks.runOnComplete(event);
  };

  return {
    settings, fetch
  };
})(window.myApp);
</code></pre><p>Again the now standard revealing module pattern is used. The settings hash includes values to be used by the <strong><strong>fetch</strong></strong> action which uses the ES <em>fetch api</em>. I've set 'GET' as the default method, null for body, and a series of options wich allow to work with json. You can review the options at MDN.</p><pre><code class="language-javascript">const settings ={  
  method: 'GET',
  body: null,
  options: {
    mode: 'cors',
    cache: 'no-cache',
    credentials: 'include',
    headers: {"Accept": "application/json"},
    redirect: 'follow',
    referrer: 'about:client'
  },
  ...
};
</code></pre><p>The next setting defines the callback. You have 5 stages to run your callbacks.</p><ol><li><strong><strong><em>runBeforeSend</em></strong></strong> <br>This callback will be run before executing the <em>fetch api</em> call.</li><li><strong><strong><em>runOnFailure</em></strong></strong> <br>This callback will in case of failure. Most of the time, network or server problems. The <em>fetch api</em> call cannot be successfully completed.</li><li><strong><strong><em>runOnError</em></strong></strong> <br>The main difference with <em>runOnFailure</em> is that the call is completed but the response is not OK. This means the response HTTP code is not in the 200s.</li><li><strong><strong><em>runOnSuccess</em></strong></strong> <br>The call has been completed successfully. The response HTTP code is in the 200s.</li><li><strong><strong><em>runOnComplete</em></strong></strong> <br>This is always executed after the call.</li></ol><pre><code class="language-javascript">callbacks: {  
  runBeforeSend: (event) =&gt; {
    // code to run always before the call
  },
  runOnFailure: (failure) =&gt; {
    console.log("myApp.Core.Ajax failed Fetch.", failure);
  },
  runOnError: (response) =&gt; {
    console.log('myApp AJAX Response Error: ', response);
  },
  runOnSuccess: (response) =&gt; {
    console.log('myApp AJAX Response Success: ', response);
  },
  runOnComplete: (event) =&gt; {
    // code to run always after the call
  }
}
</code></pre><p>Finally, the <strong><strong>fetch</strong></strong> action. This action is an asynchronous function with 6 parameters. I use named parameters when the functions has more than 3. It can get too verbose but it saves me time when reusing a function after a long time and it also avoids misplacing arguments.</p><p>I set the init hash used by the <em>fetch api</em>, for further details on this options, please review MDN.</p><p>I prevent the execution of the default for the <strong><strong>event</strong></strong> and execute the callback <strong><strong>runBeforeSend</strong></strong>. <br>Within the try block I catch any exception thrown by fetch and execute the <strong><strong>runOnFailure</strong></strong>callback.</p><p>I call <strong><strong>await window.fetch</strong></strong> with the defined url and init. Await allows to wait for <strong><strong>fetch</strong></strong> to return a promise. This promise is converted to json to extract the data. <br>If the <strong><strong>response</strong></strong> HTTP code is in the 200s (<em>response.ok?</em>), <strong><strong>runOnSuccess</strong></strong> is executed, otherwise I execute <strong><strong>runOnError</strong></strong>.</p><p>Once the try block is completed, <strong><strong>runOnComplete</strong></strong> is executed.</p><pre><code class="language-javascript">const fetch = async ({url, event, callbacks = settings.callbacks,  
  method = settings.method, body = settings.body, options = settings.options}) =&gt; {
    let init = {
      method: method,
      body: body,
      mode: options.mode,
      cache: options.cache,
      credentials: options.credentials,
      headers: options.headers,
      redirect: options.redirect,
      referrer: options.referrer
    };
    event.preventDefault();
    callbacks.runBeforeSend(event);
    try {
      let response = await window.fetch(url, init);
      let data = await response.json();
      response.data = data;
      response.ok ? callbacks.runOnSuccess(response) : callbacks.runOnError(response);
    }
    catch (failure) {
      callbacks.runOnFailure(failure);
    }
    callbacks.runOnComplete(event);
  };
</code></pre><p>The <em>return</em> section of the module includes <strong><strong>settings</strong></strong> and <strong><strong>fetch</strong></strong> action.</p><p>The usage of the action <strong><strong>Core.Ajax.fecth</strong></strong> is really simple and will be shown in the next chapters.</p><hr><h1 id="-5-html-m10n">[5] HTML &amp; M10n</h1><p>A few comments about how I organize my html code.</p><p>First, I use HAML in my Rails applications, I find it much more readable and quicker to write than HTML and, they are equivalent.</p><p>Based on the Atomic Design Methodology, I used a much simpler approach. All my html files are consisted of one of two types, <em>Containers</em> and <em>Block</em>. They all have an id with a prefix, <em>c-</em> and <em>b-</em>, respectively.</p><p>Any container and block can include others containers and blocks, there are no restrictions on that. The only simple rule I follow is that you can only change the contents of a <em>container</em> while <em>blocks</em> are replaced as a whole.</p><p>This is how it looks like,</p><pre><code class="language-html">&lt;div id="c-document"&gt;  
  &lt;div id="c-header"&gt;
    &lt;div id="b-title"&gt;
      Welcome
     &lt;/div&gt;
    &lt;div id="b-subtitle"&gt;
      Containers and Blocks
     &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id="c-body"&gt;
    &lt;div id="b-content"&gt;
      Lorem Ipsum Dolor Sit Amet Lorem Ipsum Dolor Sit Amet
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id="c-footer"&gt;
    Thanks for reading
   &lt;/div&gt;
&lt;/div&gt;  
</code></pre><p>In Rails every container and block is actually a partial which are updated asynchronously.</p><h1 id="m10n-and-how-to-update-your-content">M10n and how to update your content</h1><p>I created a new module within the DOM namespace. I called it M10n (Manipulation) and in its basic form it only includes two actions <strong><strong>updateContainer</strong></strong> and <strong><strong>replaceBlock</strong></strong>.</p><p>The code is really simple, I use the settings to remove the prefixes from the id and change the innerHTML for containers and outerHTML for blocks. If the prefix is missing/wrong, I throw an exception.</p><pre><code class="language-javascript">window.myApp.DOM.M10n = ((myApp) =&gt; {  
  const settings = {
    containerPrefix:'c-',
    blockPrefix: 'b-'
  };

  const updateContainer = (id, contentHTML) =&gt; {
    if (id.substring(0, settings.containerPrefix.length) === settings.containerPrefix) {
      document.getElementById(id).innerHTML = contentHTML;
    }
    else {
      throw `Error: Container ID must begin with '${settings.containerPrefix}'`;
    }
  };

  const replaceBlock = (id, newBlockHTML) =&gt; {
    if (id.substring(0,settings.blockPrefix.length) === settings.blockPrefix) {
      document.getElementById(id).outerHTML = newBlockHTML;
    }
    else {
      throw `Error: Block ID must begin with '${settings.blockPrefix}'`;
    }
  };

  return {
    settings, updateContainer, replaceBlock
  };
})(window.myApp);
</code></pre><hr><h1 id="-6-ajax">[6] AJAX</h1><p>I have been explaining different modules in the previous posts and now it is time to show how I use all this functionality on a Rails app. The example is extremely simple, the user clicks on a button and a HTML container is updated.</p><h3 id="main-html">main.html</h3><p>This file is the template. You can set a Rails Controller Action to render it as <em>root</em> in your <em>routes.rb</em> file. <br>The <strong><strong>button</strong></strong> has a data-controller attribute, <strong><strong>click-&gt;Sample#changeContainer</strong></strong>. It means, the <strong><strong>Observer</strong></strong> will add a listener to this element for the event <em>click</em> which will execute the Action <em>changeContainer</em> of the <em>Sample</em> Controller.</p><pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;  
&lt;html&gt;  
  &lt;head&gt;
    &lt;title&gt;
      Javascript in Ruby on Rails
    &lt;/title&gt;
    &lt;%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' =&gt; true %&gt;
    &lt;%= javascript_include_tag 'application', 'data-turbolinks-track' =&gt; true %&gt;
    &lt;%= csrf_meta_tags %&gt;
    &lt;body&gt;
      &lt;div id="c-root"&gt;
        &lt;div id="c-top"&gt;
          &lt;button data-controller="click-&gt;Sample#changeContainer"&gt;
            Button
          &lt;/button&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div id="c-bottom"&gt;
        &lt;div id="c-output"&gt;
          This is the Output container
          No output yet.
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/body&gt;
  &lt;/head&gt;
&lt;/html&gt;  
</code></pre><h3 id="_b-output-html">_b-output.html</h3><p>This is the partial we are going to render from the RoR Controller to update de template.</p><pre><code>&lt;div id="b-output"&gt;  
  Content has been modified.
&lt;/div&gt;  
</code></pre><h3 id="sample-js">sample.js</h3><p>This is the javascript Controller. It has one Action, <strong><strong>changeController</strong></strong>. I use the url '/show' which needs to be added to the Rails routes.rb file to redirect the call to the proper Rails Controller#Action. <br>It takes the default callbacks and modifies the <strong><strong>runOnSuccess</strong></strong> so it can update the container with the <strong><strong>html_content</strong></strong> generated by the Rails Controller. Then, I call the <strong><strong>fetch</strong></strong> action from the <strong><strong>Core.Ajax</strong></strong> module.</p><pre><code class="language-javascript">window.myApp.Controllers.Sample = ((myApp) =&gt; {  
 const changeContainer = (event) =&gt; {
    let url = '/show'; 
    let callbacks = myApp.Core.Ajax.settings.callbacks;
    callbacks.runOnSuccess = (response) =&gt; {
      Jrm.DOM.M10n.updateContainer('c-output', response.data.html_content);
    };
    myApp.Core.Ajax.fetch({url: url, event: event, callbacks:callbacks});
  };

 return {
    changeContainer
 };
})(window.myApp);
</code></pre><h3 id="sample_controller-rb">sample_controller.rb</h3><p>The Rails Controller has a <strong><strong>show</strong></strong> action. [Side note: I always try to keep the Rails Controllers with only REST actions: index, show, new, create, edit, update, destroy. If I need a different action, it always means that a new controller is required]</p><p>The <strong><strong>show</strong></strong> action just renders the partial in json format and sets the HTTP code as 200 (:accepted). This json is the response the fetch method will get and use to update the container contents.</p><pre><code class="language-ruby">class SampleController &lt; ApplicationController  
  def show
    respond_to do |format|
      format.json do
        render(
          json: {
            html_content: render_to_string(
              formats: [:html],
              partial: 'b-output',
              layout: false,
              locals: {}
            )
          },
          status: :accepted
        )
      end
    end
  end
end  
</code></pre><p>I haven't included the manifesto root and initialization files, these files are required to make all this work.</p><hr><h1 id="-7-forms">[7] Forms</h1><p>In the previous section, I showed you how I handle AJAX requests with a simple example. The example was a Get request to update the contents of a DIV. In this last section I will show how I process forms submissions with AJAX.</p><h2 id="core-form">Core.Form</h2><p>The <strong><strong>Core.Form</strong></strong> module includes only one action, <strong><strong><em>submit</em></strong></strong>. Its code is pretty simple. It has one condition, the DOM element (buttons most of the times) that launches the event must be within the form.</p><p>The <strong><strong>Core.Form.submit</strong></strong> action uses the <strong><strong>Core.Ajax.fetch</strong></strong> action define in the previous posts. The only difference is how I set the parameters for <em>fetch</em>.</p><p>URL, method and body, are set from the <em>form</em> which is identified from the event's <em>currentTarget</em>. This is why the <em>currentTarget</em> has to be within the form. It is possible to change this and identify the form with other mechanisms but I find this way very userful.</p><pre><code class="language-javascript">window.myApp.Core.Form = ((myApp) =&gt; {  
  const settings ={
  };

  const submit = (event, callbacks) =&gt; {
    let form = event.currentTarget.form;
    let url = form.attributes.action.value;
    let method = form.attributes.method.value;
    let body = new FormData(form);
    myApp.Core.Ajax.fetch({url: url, event: event, callbacks: callbacks, method: method, body: body});
  };

  return {
    settings, submit
  };
})(window.Jrm);
</code></pre><p>The controller calling this action should setup the callbacks and pass them over to <strong><strong>Core.Form.submit</strong></strong>.</p><hr><h1 id="conclusions">Conclusions</h1><p>All these basic patterns and modules gives you the foundations to start creating on top of it all your <em>Controllers</em> to manage and manipulate your Rails templates. As you start using them, you will be able to identify and add more base functionality to the core modules and keep your controllers DRY.</p><p>You will be increasing the separation of your JS code from your templates codes and keep them logically organized in <em>Controller</em> and <em>Actions</em>.</p><p>I hope you find this approach helpful for your next initiatives.</p><p>Feel free to share your comments or questions.</p>]]></content:encoded></item><item><title><![CDATA[AI & Machine Learning in Ruby on Rails]]></title><description><![CDATA[The last couple of weeks I been trying to understand the basic concepts of Classification, Clustering and Image Recognition but somehow all the sources immediately redirected me to Python and R.]]></description><link>https://blog.versiondos.com/machine-learning-ruby-on-rails/</link><guid isPermaLink="false">5e825ab65a87c100011a25f2</guid><category><![CDATA[Machine Learning]]></category><category><![CDATA[Rails]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Ariel Presa]]></dc:creator><pubDate>Thu, 05 Mar 2020 20:48:00 GMT</pubDate><media:content url="http://blog.versiondos.com/content/images/2020/03/Machine-Learning-hero-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.versiondos.com/content/images/2020/03/Machine-Learning-hero-1.jpg" alt="AI & Machine Learning in Ruby on Rails"><p>The last couple of weeks I been trying to understand the basic concepts of <strong><strong>Classification, Clustering and Image Recognition</strong></strong> but somehow all the sources immediately redirected me to Python and R; however I was wondering why there are almost zero references for Ruby or Rails in Artificial Intelligence and Machine Learning.</p><h6 id="where-i-can-find-">Where I can find...</h6><p>After searching and refining for a while, I encountered this this excellent blog: <a href="https://www.practicalai.io/">practicalai.io</a><br>It seems it isn't being updated for a while, but it has some good articles to dig into Machine Learning and it is well explained.</p><h6 id="setting-a-good-example">Setting a Good Example</h6><p>I did the examples of <a href="https://www.practicalai.io/teaching-ai-play-simple-game-using-q-learning/">Q-learning</a> and <a href="https://www.practicalai.io/unsupervised-learning-using-k-means-clustering-in-ruby/">clustering</a> and it was really mind-blowing. I recommend those because they are easy and fun.</p><p>Currently I'm playing with <a href="https://medium.com/@Arafat./introducing-tensorflow-ruby-api-e77a477ff16e">Tensorflow</a> for Ruby (here in <a href="https://github.com/somaticio/tensorflow.rb">Github</a>) and training my models with <a href="http://www.image-net.org/">ImageNet</a> in which you can download links of ~15 million photos in a snap. When you are trying to do Machine Learning, getting a lot of reliable data is as equal important as writing good code.</p><h6 id="last-recomendation">Last Recomendation</h6><p>Check out this video: <a href="https://www.youtube.com/watch?v=8G709hKkthY">Is It Food?</a> from the 2017 RailsConf, which explains a case in which the app has to recognize photos and reject the ones that are not food. I always love when something theoretical and abstract as Machine Learning can be applied in a simple and understandable way.</p><p>After playing for a while I think Ruby is more than capable to handle Artificial Intelligence, first of all I shifted my focus more into doing than understanding every little detail. There are a bunch of mathematical gibberish in between something doable and something perfect and as days go by, I becoming more practical about this stuff, sandboxing good already proven libraries to accomplish my goals.</p><p>More thoughts and code on this are coming soon!</p>]]></content:encoded></item><item><title><![CDATA[What About BPM?]]></title><description><![CDATA[<p>For years we had been bugged about <strong><strong>BPM</strong></strong> and process modeling, what the heck is process modeling?</p><p>According to <a href="https://en.wikipedia.org/wiki/Business_process_modeling">Wikipedia</a> definition:</p><p>Business Process Modeling is the activity of representing processes of an enterprise, so that the current process may be analyzed or improved. <em>BPM</em> is typically performed by business analysts,</p>]]></description><link>https://blog.versiondos.com/about-bpm/</link><guid isPermaLink="false">5e8259795a87c100011a25d6</guid><category><![CDATA[BPM]]></category><category><![CDATA[Processes]]></category><category><![CDATA[Tasks]]></category><category><![CDATA[Camunda]]></category><category><![CDATA[JBPM]]></category><dc:creator><![CDATA[Ariel Presa]]></dc:creator><pubDate>Fri, 07 Feb 2020 20:00:00 GMT</pubDate><media:content url="http://blog.versiondos.com/content/images/2020/03/1-VQ-NrhkmkWRPNfJxCgOIRQ.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.versiondos.com/content/images/2020/03/1-VQ-NrhkmkWRPNfJxCgOIRQ.jpeg" alt="What About BPM?"><p>For years we had been bugged about <strong><strong>BPM</strong></strong> and process modeling, what the heck is process modeling?</p><p>According to <a href="https://en.wikipedia.org/wiki/Business_process_modeling">Wikipedia</a> definition:</p><p>Business Process Modeling is the activity of representing processes of an enterprise, so that the current process may be analyzed or improved. <em>BPM</em> is typically performed by business analysts, who provide expertise in the modeling discipline; by subject matter experts, who have specialized knowledge of the processes being modeled; or more commonly by a team comprising both.</p><p>First of all, <em>a process</em> is a consecutive chain of enumerable <em>tasks</em>. When we say <em>task</em>, we mean any repeatable unit of work, which has a beginning and an end.</p><p>These <em>tasks</em> are connected in defined sequences and may contain business logic such as <em>rules</em> that defines the task outcome or result.</p><h6 id="the-monolithic-approach">The Monolithic Approach</h6><p>Programming paradigms aim to problem solving, hence when a programmer tackle one problem, his mind is set to write code in order to solve all possible scenarios with that domain in mind. What if the problem changes in the future, or the scenarios multiply in time?</p><p>The natural response is doing constant maintenance of the written programs and multiply/refactor the lines of code to solve all new possible scenarios. That's what we call the <a href="https://en.wikipedia.org/wiki/Monolithic_application">Monolithic Approach</a>: one problem at the time, one program at the time.</p><p>Consider this new "mobile app world" for an instant; Say you have to wake up early, then you have the <em>Alarm</em> app! Now say you like to cook and want all recipes in one place, then you have the <em>Notes</em> app, and so on, ad infinitum ad nauseam.</p><p>Now imagine applying this approach in a thousand-people company, settled in several countries with operations around the planet. That's madness and simply a poor strategy.</p><h6 id="enter-the-power-of-the-process">Enter the Power of the Process</h6><p>Processes are designed to communicate and connect monolithic software between each other, applying horizontal rules beyond the programs' domain. Processes are meant to interconnect limitless black boxes, managing their input and output, recording time stamps between each other's execution and signaling them in predefined states.</p><p>One of the most popular notations for process modeling is <a href="http://bpmn.org/">BPMN2</a>, defined as follows:</p><p>The Business Process Modeling Notation (BPMN) is a graphical notation that depicts the steps in a business process. <em>BPMN</em> depicts the end to end flow of a business process. The notation has been specifically designed to coordinate the sequence of processes and the messages that flow between different process participants in a related set of activities.</p><p>To give you a more precise idea about it, let me show you what a sample <strong><strong>Process</strong></strong> looks like:</p><figure class="kg-card kg-image-card"><img src="http://blog.versiondos.com/content/images/2020/04/4Vgx6vj.png" class="kg-image" alt="What About BPM?"></figure><p><br></p><h6 id="what-can-you-do-with-a-process">What Can You Do With a Process?</h6><p>You can do a lot of things, for instance:</p><ul><li>Connect Legacy Apps</li><li>Call Services (REST, WebServices, etc.)</li><li>Process Batch</li><li>Control Flows and Human Tasks</li><li>Compute SLAs for Tasks and Processes</li><li>Create Digital Trail for Tasks</li><li>Standardize UI between multiple Apps</li><li>Execute Rules (logical, decision tables, etc.)</li><li>...</li></ul><p>This list could be as long as your imagination. Basically you can do it all. Every activity is a sequence of tasks which can be described as a process.</p><h6 id="it-s-a-commercial-world">It's a Commercial World</h6><p>There are several world class BPM managers; I'm going to mention the most relevant (according to me): <a href="http://www-03.ibm.com/software/products/en/business-process-manager-family">IBM BPM</a> inherited from <em>Lombardi</em>, the <a href="http://www.oracle.com/us/technologies/bpm/bpm-suite-066443.html">Oracle BPM</a> and the <a href="https://www.redhat.com/en/technologies/jboss-middleware/bpm">Red Hat BPM Suite</a>.</p><p>These solutions are in the $80K to $350K price range, far from being a petty cash investment and all are hard to configure and expensive. Here is where Red Hat stands out. They released their solution under an open source license via the <a href="http://www.kiegroup.org/">KIE group</a>, so you can download the <a href="https://developers.redhat.com/products/bpmsuite/overview/">developer version</a> and write your own code to customize it. You can also access their <em>Github</em> repo <a href="https://github.com/droolsjbpm/jbpm">here</a>.</p><p>One more for the road: you can create a cloud virtual machine with the <strong><strong>BPM Suite</strong></strong> in <a href="https://developers.openshift.com/jboss-xpaas/business-process-management-suite.html">Red Hat OpenShift</a> to try it for free.</p><p></p><p><em>2020 UPDATE: These days we have the new kid on the block, the german company <a href="https://www.camunda.com">Camunda</a>, which offers the best BPM Engine of the market! We recommend you to try it out, it is free and offers a very good REST Api as well.</em></p>]]></content:encoded></item><item><title><![CDATA[How to Update Rails Views via AJAX]]></title><description><![CDATA[Alternative way to update Ruby on Rails views via AJAX]]></description><link>https://blog.versiondos.com/rails-views-via-ajax/</link><guid isPermaLink="false">5e82448d5a87c100011a257a</guid><category><![CDATA[Rails]]></category><category><![CDATA[Javascript]]></category><category><![CDATA[AJAX]]></category><dc:creator><![CDATA[Ariel Presa]]></dc:creator><pubDate>Sat, 01 Feb 2020 16:00:00 GMT</pubDate><media:content url="http://blog.versiondos.com/content/images/2020/03/rails-3309912_1920_1_5.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.versiondos.com/content/images/2020/03/rails-3309912_1920_1_5.jpg" alt="How to Update Rails Views via AJAX"><p>If you still feel a little frustrated like me, circling around AJAX and Rails views, I think you might like this.</p><h4 id="some-use-cases">Some Use Cases</h4><p>I faced this problem when I had to tackle these scenarios:</p><ul><li>Wizards partial saving</li><li>Pure HTML Table editing/refresh</li><li>Messaging/Notification refresh</li><li>Infinite Scrolling</li></ul><p>Let me dive into the first case; saving each step of a wizard gets a little bit complicated if you have to refresh the whole page every time you hit <em>Continue</em>. That is a known bad practice and to do it the right way, you might consider these strategies:</p><ol><li>Keep all the data in memory and send it to the server when you finish the Wizard</li><li>Do partial step-by-step validation and saving</li></ol><p>The second option handles the errors better and is more intuitive for the user. Personally, I think that's the way all the Wizards should be designed. </p><h4 id="let-s-spice-up-the-example-">Let's Spice Up The Example:</h4><p>Consider that you have to present the Wizard for the first time as a rendered (empty) HTML, directly from your controller action:</p><pre><code class="language-ruby">def new_wizard  
  @step_one = StepOne.new
  render 'new_wizard_view'
end  
</code></pre><p>You're loading the empty Wizard for the first time and it looks somewhat like this: </p><figure class="kg-card kg-image-card"><img src="https://blog.beatcoding.com/content/images/2016/10/ScreenHunter_13-Oct.-04-18.28.jpg" class="kg-image" alt="How to Update Rails Views via AJAX"></figure><p>What happens when you hit <em>Continue</em>?</p><ol><li>The button calls a JavaScript function that executes an AJAX call:</li></ol><pre><code class="language-javascript">function saveFirstStep(form){  
  $.ajax{
    url: '/save/first/step',
    method: 'POST', // This also could be PUT or PATCH
    dataType: 'JSON',
    data: { step_one: { val_1: form.input_1.val(), ...} },
    ...
  }
}
</code></pre><ol><li>The save Action is triggered in the Rails server:</li></ol><pre><code class="language-ruby">def save_first_step  
  # Use a before_action to filter params and skip this line
  @step_one = StepOne.new(params[:step_one])

  respond_to do |format| 
    if @step_one.save
      format.js { render 'second_step' }
    else
      format.js { render 'first_step' }
    end
  end
end  
</code></pre><ol><li>The JS view <code>first_step.js</code> will look roughly like this:</li></ol><pre><code class="language-javascript">$('#first_step_container').html("&lt;%= escape_javascript(render 'first_step_partial') %&gt;");
</code></pre><ol><li>Finally, to make it work you have to have a second partial ERB view <code>first_step_partial.html.erb</code> with all the HTML and model's errors from validations:</li></ol><pre><code class="language-ruby">&lt;div class="form-group"&gt;  
  &lt;div class="row"&gt;
    &lt;div class="col-md-offset-1 col-md-3"&gt;
      &lt;%= f.input :id, :as =&gt; :hidden %&gt;
      &lt;%= f.input :icon, :collection =&gt; survey_icons %&gt;
      &lt;%= f.input :title %&gt;
      &lt;!-- the rest of the form goes on --&gt;
      ...
</code></pre><p>The rendered result will look like this:</p><figure class="kg-card kg-image-card"><img src="https://blog.beatcoding.com/content/images/2016/10/Screen-Shot-2016-10-15-at-6.45.03-PM.png" class="kg-image" alt="How to Update Rails Views via AJAX"></figure><h4 id="time-for-plan-b-">Time for Plan B:</h4><p>I personally <strong><strong>don't like</strong></strong> having two different views (JS + ERB partial) per step because when you have a +3 steps Wizard, there will be too many views and it becomes a big problem for future maintenance.</p><p>Also, if you work with multiple models in the same Wizard, it becomes messy to store all the views in the directory hierarchy.</p><p>Instead of using the JS <code>first_step.js</code> view, you can attempt to return a JSON object from your action:</p><pre><code class="language-ruby">respond_to do |format|  
  if @step_one.save
    format.json { render :json =&gt; { 
      # Returns an empty object without errors
      :html =&gt; {} },
      # Returns the status to AJAX
      :status =&gt; :ok }
  else
    format.json { render :json =&gt; { 
      # Renders the ERB partial to a string
      :html =&gt; render_to_string(
        :template =&gt; 'first_step_partial.html.erb', # The ERB partial
        :formats =&gt; :html,                   # The string format
        :layout =&gt; false,                    # Skip the application layout
        :locals =&gt; {:step_one =&gt; @step_one}) # Pass the model object with errors
      },
      # Returns the status to AJAX
      :status =&gt; :unprocessable_entity) }
  end
end  
</code></pre><p>And re-write your AJAX call like this:</p><pre><code class="language-javascript">function saveFirstStep(form){  
  $.ajax{
    url: '/save/first/step',
    method: 'POST', // This also could be PUT or PATCH
    dataType: 'JSON',
    data: { step_one: { val_1: form.input_1.val(), ...} },

    success: function(response){
      // Moves to the next step
      $('#wizard').move_next;
    },

    error: function(jqXHR, textStatus, errorThrown){
      // Rewrites the DOM object with the updated first step
      $('#first_step_container').html(jqXHR.responseJSON.html);
    }
    ...
  }
}
</code></pre><p>With this workaround you certainly get rid of all the JS intermediate views and also keep all your HTML error handling in the ERBs. If you are fond of SimpleForm (or a similar gem), this solution helps handling DOM classes to show all input errors in the form. <br></p><h6 id="final-note-and-coding-disclaimer-">Final Note and Coding Disclaimer:</h6><p>This solution is a <strong><strong>hack</strong></strong>, and it is not considered the best way to handle AJAX calls in Rails, but is neat and it WORKS like a charm. If you know what you're doing, it's completely SAFE to use it.</p>]]></content:encoded></item><item><title><![CDATA[Our Brief Rules...]]></title><description><![CDATA[Blog rules for Version Dos]]></description><link>https://blog.versiondos.com/our-brief-rules/</link><guid isPermaLink="false">5e8241b15a87c100011a255c</guid><category><![CDATA[V2]]></category><category><![CDATA[Rules]]></category><dc:creator><![CDATA[Version Dos Admin]]></dc:creator><pubDate>Wed, 01 Jan 2020 16:00:00 GMT</pubDate><media:content url="http://blog.versiondos.com/content/images/2020/03/mind-the-gap-sep19.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.versiondos.com/content/images/2020/03/mind-the-gap-sep19.jpg" alt="Our Brief Rules..."><p>Before you start posting or writing comments you have to consider this blog's etiquette.</p><h6 id="main-guidelines-">Main Guidelines:</h6><ul><li>Honesty comes first</li><li>Always be kind and respect other's opinions</li><li>Be aware of copyright laws</li><li>Be mindful about spam</li><li>Avoid being an over-sensitive reader</li></ul><h6 id="we-encourage-you-to-">We encourage you to:</h6><ul><li>Be yourself</li><li>Post from your own wisdom and/or experience</li><li>Double check your links and references</li><li>Always consider writing to a greater audience</li><li>Respect confidentiality and/or privacy</li><li>Less is more</li></ul><p>Also keep it casual and direct. If you are unsure about something, please feel free to contact the moderators via <a href="mailto:blog@versiondos.com">blog@versiondos.com</a></p>]]></content:encoded></item></channel></rss>