CINXE.COM
Contributing to Turtl | Turtl
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Contributing to Turtl | Turtl</title> <meta name="description" content="The safe way to remember everything. Take all your important data with you."> <link rel="stylesheet" href="/css/main.css?v=10"> <link rel="canonical" href="https://turtlapp.com/contributing/"> <link rel="alternate" type="application/rss+xml" title="Turtl" href="https://turtlapp.com/feed.xml" /> <link rel="shortcut icon" href="/images/favicon.png" type="image/x-icon"> <link href="https://fonts.googleapis.com/css?family=Lato|Noto+Serif|Slabo+13px" rel="stylesheet"> <script src="/js/mootools-core-1.6.0.js"></script> <script src="/js/mootools-more-1.6.0.js"></script> <script src="/js/composer.js?v=10"></script> <script src="/js/bluebird.min.js?v=10"></script> <script src="/js/sexhr.js?v=10"></script> <script src="/js/uikit.min.js?v=10"></script> <script src="/js/uikit-icons.min.js?v=10"></script> <script src="/js/main.js?v=10"></script> <script src="/js/stripe.js?v=10"></script> <script src="/js/controller-sig.js?v=10"></script> <script>const stripe_pubkey = 'pk_live_61JSZue0As9lbGB2CZK0DSRU';</script> </head> <body class=""> <div class="main-nav-container"> <div class="uk-container"> <nav class="main" uk-navbar> <a class="uk-navbar-item uk-logo uk-margin-right" href="/"><img src="/images/logo.svg">Turtl<sup class="uk-margin-small-left uk-text-warning">beta</sup></a> <ul class="uk-navbar-nav uk-visible@s"> <li><a href="/download">Download</a></li> <li><a href="/premium">Premium</a></li> <li> <a href="#">About<span uk-icon="icon: triangle-down; ratio: 0.75"></span></a> <div class="uk-navbar-dropdown" uk-dropdown="offset: 0"> <ul class="uk-nav uk-navbar-dropdown-nav"> <li><a href="/docs">Documentation</a></li> <li><a href="/contributing">Contributing</a></li> <li><a href="/faq">FAQ</a></li> <li><a href="/features">Features</a></li> </ul> </div> </li> <li><a href="/contact">Contact</a></li> </ul> <div class="uk-navbar-right uk-visible@m"> <ul class="uk-navbar-nav"> <li><a title="Twitter" href="https://twitter.com/turtlapp" uk-icon="icon: twitter"></a></li> <li><a title="Turtl Community" href="https://community.turtlapp.com/" uk-icon="icon: users"></a></li> <li><a title="Github" href="https://github.com/turtl" uk-icon="icon: github"></a></li> </ul> </div> <div class="uk-navbar-right uk-hidden@s"> <a class="uk-navbar-item" href="#mobile-nav" uk-toggle><span uk-icon="icon: menu"></span></a> </div> <div id="mobile-nav" uk-offcanvas> <div class="uk-offcanvas-bar"> <a class="uk-offcanvas-close"><span uk-icon="icon: close"></span></a> <ul class="uk-nav"> <li><a href="/">Home</a></li> <li><a href="/download">Download</a></li> <li><a href="/premium">Premium</a></li> <li class="uk-parent"> About <ul class="uk-nav-sub"> <li><a href="/docs">Documentation</a></li> <li><a href="/contributing">Contributing</a></li> <li><a href="/faq">FAQ</a></li> <li><a href="/features">Features</a></li> </ul> </li> <li><a href="/contact">Contact</a></li> </ul> <ul class="uk-iconnav uk-flex-center uk-padding-small"> <li><a title="Twitter" href="https://twitter.com/turtlapp" uk-icon="icon: twitter; ratio: 1.5"></a></li> <li><a title="Turtl Community" href="https://community.turtlapp.com/" uk-icon="icon: users; ratio: 1.5"></a></li> <li><a title="Github" href="https://github.com/turtl" uk-icon="icon: github; ratio: 1.5"></a></li> </ul> </div> </div> </nav> </div> </div> <div id="container" class="uk-offcanvas-content"> <div class="uk-section"> <div class="uk-container uk-container-small"> <div class="documentation"> <h1 class="no_toc" id="contributing-to-the-turtl-project">Contributing to the Turtl project</h1> <div class="toc uk-card uk-card-default uk-card-body uk-align-right@s uk-width-1-3@s"> <ul id="markdown-toc"> <li><a href="#sign-the-contributor-license-agreement" id="markdown-toc-sign-the-contributor-license-agreement">Sign the Contributor License Agreement</a></li> <li><a href="#help-us-code" id="markdown-toc-help-us-code">Help us code</a></li> <li><a href="#translations" id="markdown-toc-translations">Translations</a></li> <li><a href="#project-coding-conventions" id="markdown-toc-project-coding-conventions">Project coding conventions</a> <ul> <li><a href="#javascript" id="markdown-toc-javascript">Javascript</a></li> <li><a href="#rust" id="markdown-toc-rust">Rust</a></li> </ul> </li> <li><a href="#questions" id="markdown-toc-questions">Questions</a></li> </ul> </div> <p>Thanks for your interest in helping build Turtl! Turtl is an open-source project owned and operated by <a href="https://lyonbros.com">Lyon Bros LLC</a>.</p> <h2 id="sign-the-contributor-license-agreement">Sign the Contributor License Agreement</h2> <p>In order for us to accept your contributions to the Turtl project, you need to read and agree to the Contributor License Agreement. You can find the agreements here:</p> <ul> <li><a href="/contributing/icla">Individual Contributor License Agreement</a><br /> For individuals wanting to contribute</li> <li><a href="/contributing/ecla">Entity Contributor License Agreement</a><br /> If you are contributing code as a member of a company, organization, or other entity, have someone from your organization who makes legal decisions sign this form.</li> </ul> <h2 id="help-us-code">Help us code</h2> <p>Our central <a href="https://github.com/turtl/tracker/issues">Github issue tracker</a> covers all of the Turtl projects.</p> <p>We have marked <a href="https://github.com/turtl/tracker/issues?q=is%3Aissue+is%3Aopen+milestone%3A%2A+label%3Astatus%3Ahelp-wanted"><strong>a list of items in our issue tracker you can help with</strong></a>!</p> <p>This includes all items with the <code class="language-plaintext highlighter-rouge">help-wanted</code> tag that are a part of one of our milestones. There are some issues that are very core to the app and require intimate knowledge of its inner workings, and these are generally not marked with <code class="language-plaintext highlighter-rouge">help-wanted</code>.</p> <p>Please ask before working on issues that do not have a milestone as these are generally meant to track ideas that haven’t been fully realized or “maybe” features that we want to consider but haven’t decided to include yet.</p> <p>Once again, <em>if you work on issues that are not part of a milestone, chances are your PR will be rejected</em>. When in doubt, pull issues off the <a href="https://github.com/turtl/tracker/issues?q=is%3Aissue+is%3Aopen+milestone%3A%2A+label%3Astatus%3Ahelp-wanted">help wanted list</a>!</p> <h2 id="translations">Translations</h2> <p>Would you like to translate Turtl to your language? Thanks for helping out! We love being multi-lingual.</p> <p>First, check if someone has already started translating in your language by looking through the <a href="https://github.com/turtl/js/tree/master/locales">existing translations</a>.</p> <p>If there’s one for your language/locale already, feel free to make any updates to the file and submit a pull request.</p> <p>If you language/locale isn’t there, copy the <a href="https://github.com/turtl/js/blob/master/locales/locale.js.template">latest language template file</a> to a new file with the format <code class="language-plaintext highlighter-rouge"><language code>_<locale code>.js</code> (if your language doesn’t have a specific locale code, just use the language code again). For example, a Spanish translation in the Mexican locale would be <code class="language-plaintext highlighter-rouge">es_mx.js</code>.</p> <p>Now just fill in what you can and submit a pull request on Github! Keep in mind that translations are significant contributions, and therefor you must <a href="#sign-the-contributor-license-agreement">sign the CLA</a> before new translations can be accepted.</p> <h2 id="project-coding-conventions">Project coding conventions</h2> <p>Please review the programming conventions used for Turtl’s various projects before you spend time writing code.</p> <h3 id="javascript">Javascript</h3> <p>These conventions apply to the following projects:</p> <ul> <li><a href="https://github.com/turtl/js">js</a></li> <li><a href="https://github.com/turtl/android">android</a></li> <li><a href="https://github.com/turtl/desktop">desktop</a></li> <li><a href="https://github.com/turtl/browser-extension">browser-extension</a></li> </ul> <p>Let’s go over the basics. Note that some of these rules are more loosely enforced than others. If you make a significant contribution that works beautifully but you used <code class="language-plaintext highlighter-rouge">camelCasing</code> it’s probably not going to be a big deal.</p> <ul> <li> <p><strong>Localized string literals</strong>: Turtl is a multi-lingual application, and uses user-submitted translations. We build the localization template by parsing our own UI code. What this means is that we specifically look for <code class="language-plaintext highlighter-rouge">i18next.t("Delete")</code> in javascript and <code class="language-plaintext highlighter-rouge">{{t "Delete"}}</code> in our templates, and we add the string “Delete” to the translation template.</p> <p>This means that you cannot put the string literals into variables! For instance:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// good</span> <span class="kd">var</span> <span class="nx">title</span> <span class="o">=</span> <span class="nx">i18next</span><span class="p">.</span><span class="nx">t</span><span class="p">(</span><span class="dl">'</span><span class="s1">Edit note</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// good</span> <span class="kd">var</span> <span class="nx">title</span> <span class="o">=</span> <span class="nx">action</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">add</span><span class="dl">'</span> <span class="p">?</span> <span class="nx">i18next</span><span class="p">.</span><span class="nx">t</span><span class="p">(</span><span class="dl">'</span><span class="s1">Add note</span><span class="dl">'</span><span class="p">)</span> <span class="p">:</span> <span class="nx">i18next</span><span class="p">.</span><span class="nx">t</span><span class="p">(</span><span class="dl">'</span><span class="s1">Edit note</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// bad! we won't be able to parse this</span> <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Edit note</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">title</span> <span class="o">=</span> <span class="nx">i18next</span><span class="p">.</span><span class="nx">t</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span> <span class="c1">// bad! we won't be able to parse this</span> <span class="kd">var</span> <span class="nx">title</span> <span class="o">=</span> <span class="nx">i18next</span><span class="p">.</span><span class="nx">t</span><span class="p">(</span><span class="nx">action</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">add</span><span class="dl">'</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">Add note</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Edit note</span><span class="dl">'</span><span class="p">);</span> </code></pre></div> </div> <p>In other words, when calling <code class="language-plaintext highlighter-rouge">i18next.t()</code> in javascript or <code class="language-plaintext highlighter-rouge">{{t ...}}</code> in handlebars, <em>please only use literal strings</em>!</p> </li> <li> <p><strong>Whitespace</strong>: Please use readable whitespace.</p> <p>Examples:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// fine</span> <span class="kd">function</span> <span class="nx">test</span><span class="p">(</span><span class="nx">arg1</span><span class="p">,</span> <span class="nx">arg2</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> <span class="c1">// fine (dropped braces are OK)</span> <span class="k">if</span><span class="p">(</span><span class="nx">condition</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> <span class="c1">// one-line functions are also fine</span> <span class="kd">var</span> <span class="nx">cb</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span> <span class="c1">// nope. please use readable whitespace</span> <span class="kd">function</span> <span class="nx">test</span><span class="p">(</span><span class="nx">arg1</span><span class="p">,</span><span class="nx">arg2</span><span class="p">){</span> <span class="p">}</span> <span class="c1">// nope. use whitespace!</span> <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span><span class="nx">val1</span><span class="p">,</span> <span class="na">key</span><span class="p">:</span><span class="nx">val2</span><span class="p">,</span> <span class="p">};</span> </code></pre></div> </div> </li> <li> <p><strong>Variable declarations</strong>: <code class="language-plaintext highlighter-rouge">var</code>-per-declaration is the preferred method, but if this is against your normal style, that’s ok. One thing that will not be tolerated is leading commas.</p> <p>Examples:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// good</span> <span class="kd">var</span> <span class="nx">my_data</span> <span class="o">=</span> <span class="nx">get_some_data</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="nx">send_some_data</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> <span class="c1">// if you must.</span> <span class="kd">var</span> <span class="nx">my_data</span> <span class="o">=</span> <span class="nx">get_some_data</span><span class="p">(),</span> <span class="nx">success</span> <span class="o">=</span> <span class="nx">send_some_data</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> <span class="c1">// Not allowed (leading commas, ugh)</span> <span class="kd">var</span> <span class="nx">my_data</span> <span class="o">=</span> <span class="nx">get_some_data</span><span class="p">()</span> <span class="p">,</span> <span class="nx">success</span> <span class="o">=</span> <span class="nx">send_some_data</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> </code></pre></div> </div> </li> <li> <p><strong>Trailing commas</strong>: Either leave them at the end of the line on the last item or take the trailing comma off. Do <em>NOT</em> put the comma before the item.</p> <p>Examples:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// good (trailing comma on last item is great A+++)</span> <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">andrew</span><span class="dl">'</span><span class="p">,</span> <span class="na">hates</span><span class="p">:</span> <span class="dl">'</span><span class="s1">leading commas</span><span class="dl">'</span><span class="p">,</span> <span class="na">seriously</span><span class="p">:</span> <span class="dl">'</span><span class="s1">do not do it</span><span class="dl">'</span><span class="p">,</span> <span class="p">};</span> <span class="c1">// good (no trailing comma on last item also fine)</span> <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">slappy</span><span class="dl">'</span><span class="p">,</span> <span class="na">friends</span><span class="p">:</span> <span class="mi">0</span> <span class="p">};</span> <span class="c1">// NO. never.</span> <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">andrew</span><span class="dl">'</span> <span class="p">,</span> <span class="na">hates</span><span class="p">:</span> <span class="dl">'</span><span class="s1">leading commas</span><span class="dl">'</span> <span class="p">,</span> <span class="na">seriously</span><span class="p">:</span> <span class="dl">'</span><span class="s1">your code will be roundly rejected</span><span class="dl">'</span> <span class="p">};</span> </code></pre></div> </div> </li> <li> <p><strong>Underscores</strong>: <code class="language-plaintext highlighter-rouge">use_underscores</code> instead of <code class="language-plaintext highlighter-rouge">camelCasing</code>. The exception is when defining top-level classes, which use <code class="language-plaintext highlighter-rouge">CapitalCamelCasing</code>.</p> <p>Example:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// good</span> <span class="kd">var</span> <span class="nx">user_settings</span> <span class="o">=</span> <span class="p">(</span><span class="k">new</span> <span class="nx">User</span><span class="p">()).</span><span class="nx">get_settings</span><span class="p">();</span> <span class="c1">// good (defining a top-level class)</span> <span class="kd">const</span> <span class="nx">User</span> <span class="o">=</span> <span class="nx">Composer</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({...});</span> <span class="c1">// nope</span> <span class="kd">var</span> <span class="nx">userSettings</span> <span class="o">=</span> <span class="p">...;</span> <span class="c1">// nope</span> <span class="kd">function</span> <span class="nx">getAllNotes</span><span class="p">()</span> <span class="p">...</span> </code></pre></div> </div> </li> </ul> <h4 id="third-party-libraries">Third-party libraries</h4> <p>Turtl strives to use <em>as little third-party code as possible</em> in its front-end clients. The reason for this is that each library that <em>is</em> included has to be vetted for possible security leaks.</p> <p>For this reason, if you do feel a third-party library would suit the project, please note this in your pull request. Put your third-party libraries directly into the source tree and version them. If the third-party library makes any kind of AJAX calls, form posts, writes any scripts to <head>, or makes any other outbound connection, there is a very good chance your changes will not be merged.</p> <p>Dependency management tools like bower/npm/etc are not to be used or included in the javascript-based projects. Note that we do use npm to power some aspects of the build system (lessc, handlebars, postcss, etc) but under no cirumcstances does it download code to be included in the app itself.</p> <p>Please note that third-party libraries included in Turtl cannot be licensed copyleft (eg, GPLv3). This prevents us from relicensing Turtl, for instance if we want to release an app in the Apple iOS store. MIT/BSD licenses are strongly favored, but others will be considered on a case-by-case basis.</p> <p>Please make sure any third-party code you include contains the license it uses in its source file(s).</p> <h3 id="rust">Rust</h3> <p>Our Rust code follows the standard Rust conventions, but I’ll list some of the bigger ones here:</p> <ul> <li> <p><strong>Indent with two spaces</strong>: Please follow this. All of our code uses two-space indendation and if you use tabs or four spaces or anything else, you will be asked to re-tab.</p> </li> <li> <p><strong>Use underscores</strong>: No camelCase. This is a hard rule.</p> <p>Examples:</p> <div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">// good</span> <span class="k">fn</span> <span class="nf">get_data</span><span class="p">()</span> <span class="k">-></span> <span class="nb">u32</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">}</span> <span class="c">// bad</span> <span class="k">fn</span> <span class="nf">thisIsNotJava</span><span class="p">(</span><span class="n">orCSharp</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-></span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span> </code></pre></div> </div> </li> </ul> <h2 id="questions">Questions</h2> <p>If you have questions on any of the above, or run into a situtation that isn’t covered, please <a href="/contact">reach out to us</a>!</p> </div> </div> </div> </div> <footer class="uk-section uk-section-small uk-section-secondary"> <div class="uk-container"> <div class="uk-flex uk-flex-middle uk-flex-between@m uk-flex-wrap"> <div class="uk-width-1-3@s uk-text-center uk-padding uk-text-left@s"> <p>Copyright © <a href="https://lyonbros.com/">Lyon Bros LLC</a></p> <small> Homepage photo credits: <ul> <li><a target="_blank" href="https://unsplash.com/photos/aV5xrpB0bwQ">Soragrit Wongsa</a></li> <li><a target="_blank" href="https://www.pexels.com/photo/tortoise-on-rock-914794/">Jose Aragones</a></li> <li><a target="_blank" href="https://www.pexels.com/photo/working-in-a-group-6224/">Kaboompics.com</a></li> </ul> </small> </div> <div class="uk-flex uk-flex-left uk-flex-space-between uk-flex-wrap uk-width-1-3@s"> <ul class="uk-nav uk-nav-default uk-width-1-2"> <li><a href="/download">Downloads</a></li> <li><a href="/premium">Premium</a></li> <li><a href="/docs">Documentation</a></li> <li><a href="/contributing">Contributing</a></li> </ul> <ul class="uk-nav uk-nav-default uk-width-1-2"> <li><a href="/contact">Contact</a></li> <li><a href="/privacy">Privacy</a></li> <li><a href="/terms">Terms</a></li> <!--<li><a href="http://turtlapp.tumblr.com/">Blog</a></li>--> </ul> </div> <ul class="uk-iconnav uk-flex-center uk-width-1-3@s uk-padding"> <li><a title="Twitter" href="https://twitter.com/turtlapp" uk-icon="icon: twitter; ratio: 1.5"></a></li> <li><a title="Turtl Community" href="https://community.turtlapp.com/" uk-icon="icon: users; ratio: 1.5"></a></li> <li><a title="Github" href="https://github.com/turtl" uk-icon="icon: github; ratio: 1.5"></a></li> </ul> </div> </div> </footer> <!-- Piwik --> <script type="text/javascript"> var _paq = _paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="//killtheradiostats.nfshost.com/"; _paq.push(['setTrackerUrl', u+'piwik.php']); _paq.push(['setSiteId', '12']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); })(); </script> <noscript><p><img src="//killtheradiostats.nfshost.com/piwik.php?idsite=12&rec=1" style="border:0;" alt="" /></p></noscript> <!-- End Piwik Code --> <!--<script src="https://widget.battleforthenet.com/widget.js" async></script>--> </body> </html>