# Styleguide

Pootle developers try to stick to some development standards that are gathered in this document.

## Python and documentation

For Python code and documentation Pootle follows the Translate Styleguide adding extra clarifications listed below.

- Python style conventions
- Documentation style conventions

### Pootle-specific Python guidelines

Pootle has specific conventions for Python coding style.

#### Imports

Like in Python import conventions in Translate styleguide, but imports should be grouped in the following order:

1. __future__ library imports
2. Python standard library imports
3. Third party libraries imports (Including Translate Toolkit ones)
4. Django imports
5. Django external apps imports
6. Other Pootle apps imports
7. Current package (or app) imports, using explicit relative imports (See PEP 328)

Check Python import conventions in Translate styleguide for other conventions that the imports must follow.

    from __future__ import absolute_import

    import re
    import sys.path as sys_path
    import time
    from datetime import timedelta
    from os import path

    from lxml.html import fromstring
    from translate.storage import versioncontrol

    from django.contrib.auth.models import User
    from django.db import models
    from django.db.models import Q
    from django.db.models.signals import post_save

    from profiles.views import edit_profile
    from tastypie import fields

    from pootle.core.decorators import permission_required
    from pootle_store.models import (FUZZY, TRANSLATED, UNTRANSLATED, Store,
                                     Unit, count_words)
    from pootle_translationproject.models import TranslationProject

    from .forms import GoalForm
    from .models import Tag

#### Order in models

Model’s inner classes and methods should keep the following order:

- Database fields
- Non database fields
- Default `objects` manager
- Custom manager attributes (i.e. other managers)
- `class Meta`
- `def natural_key()` (Because it is tightly related to model fields)
- Properties
- All `@cached_property` properties
- Any method decorated with `@classmethod`
- `def __unicode__()`
- `def __str__()`
- Any other method starting with `__` (for example `__init__()`)
- `def save()`
- `def delete()`
- `def get_absolute_url()`
- `def get_translate_url()`
- Any custom methods

#### Fields in models and forms

- If the field declaration fits in one line:
  - Put all the options on that line,
  - Don’t put a comma after the last option,
  - The parenthesis that closes the field declaration goes just after the last option.
- If the field declaration spans to several lines:
  - Each option goes on its own line (including the first one),
  - The options are indented 4 spaces,
  - The last option must have a comma after it,
  - The closing parenthesis in the field declaration goes on its own line, aligned with the first line in the field declaration.

    class SampleForm(forms.Form):
        # Field declaration that spans to several lines.
        language = forms.ChoiceField(
            label=_('Interface Language'),
            initial="",
            required=False,
            widget=forms.Select(attrs={
                'class': 'js-select2 select2-language',
            }),
            help_text=_('Default language for using on the user interface.'),
        )
        # One line field declaration.
        project = forms.ModelChoiceField(Project, required=True)

#### URL patterns

When writing the URL patterns:

- URL patterns can be grouped by putting a blank line between the groups.
- On each URL pattern:
  - Specify the URL pattern using the `url()` function, not a tuple.
  - Each parameter must go on its own line in all cases, indenting them one level to allow easily seeing the different URL patterns.
  - In URLs:
    - Use hyphens. Avoid underscores at all costs.
    - To split long URLs use implicit string continuation. Note that URLs are raw strings.
  - URL pattern names must be named like `pootle-{app}-{view}` (except in some cases, like URLs on pootle_app app):
    - `{app}` is the app name, which sometimes can be shortened, e.g. using tp to avoid the longish translationproject. If either a shortened app name or a full one is being used, the chosen app name must be used consistently across all the URL patterns for the app. The only exception to this are AJAX URL patterns which can use a different value for `{app}`, that must be consistently used among all the AJAX URL patterns in the app.
    - `{view}` is a unique string which might consist on several words, separated with hyphens, that might not match the name of the view that is handled by the URL pattern.

    urlpatterns = patterns('pootle_project.views',
        # Listing of all projects.
        url(r'^$',
            'projects_index'),

        # Whatever URLs.
        url(r'^incredibly-stupid/randomly-long-url-with-hyphens-that-is-split-'
            r'and-continued-on-next-line.html$',
            'whatever',
            name='pootle-project-whatever'),

        # Admin URLs.
        url(r'^(?P<project_code>[^/]*)/admin.html$',
            'project_admin'),
        url(r'^(?P<project_code>[^/]*)/permissions.html$',
            'project_admin_permissions',
            name='pootle-project-admin-permissions'),
    )

#### Settings naming

Pootle specific settings must be named like `POOTLE_*`, for example: `POOTLE_ENABLE_API`, `POOTLE_VCS_DIRECTORY` or `POOTLE_MARKUP_FILTER`

### Pootle-specific markup

For documenting several things, Pootle defines custom Sphinx roles.

- Settings:

      .. setting:: PODIRECTORY

  To link to a setting, use `:setting:`PODIRECTORY``.

- Icons:

      Some reference to |icon:some-icon| in the text.

  This allows you to easily add inline images of icons used in Pootle. The icons are all files from `pootle/static/images/sprite`. If you were referring to an icon `icon-edit.png` then you would use the syntax `|icon:icon-edit|`. The icon reference is always prefixed by `icon:` and the name of the icon is used without the extension.

  E.g. `|icon:icon-google-translate|` will insert this icon.

## JavaScript

There are no “official” coding style guidelines for JavaScript, so based on several recommendations (1, 2, 3) we try to stick to our preferences.

Indenting
  - We currently use 2-space indentation. Don’t use tabs.
  - Avoid lines longer than 80 characters. When a statement will not fit on a single line, it may be necessary to break it. Place the break after an operator, ideally after a comma.
Whitespace
  - If a function literal is anonymous, there should be one space between the word `function` and the `(` (left parenthesis).
  - In function calls, don’t use any space before the `(` (left parenthesis).
  - Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.
  - Each `;` (semicolon) in the control part of a `for` statement should be followed with a space.
  - Whitespace should follow every `,` (comma).
Naming

  - Variable and function names should always start by a lowercase letter and consequent words should be CamelCased. Never use underscores.

  - If a variable holds a jQuery object, prefix it by a dollar sign `$`. For example:

        var $fields = $('.js-search-fields');

Selectors
  - Prefix selectors that deal with JavaScript with `js-`. This way it’s clear the separation between class selectors that deal with presentation (CSS) and functionality (JavaScript).
  - Use the same naming criterion as with CSS selector names, ie, lowercase and consequent words separated by dashes.
Control statements

  Control statements such as `if`, `for`, or `switch` should follow these rules:

  - The enclosed statements should be indented.
  - The `{` (left curly brace) should be at the end of the line that begins the compound statement.
  - The `}` (right curly brace) should begin a line and be indented to align with the beginning of the line containing the matching `{` (left curly brace).
  - Braces should be used around all statements, even single statements, when they are part of a control structure, such as an `if` or `for` statement. This makes it easier to add statements without accidentally introducing bugs.
  - Should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.
String
  - A string literal should be wrapped in single quotes.
  - `join` should be used to concatenate pieces instead of `+` because it is usually faster to put the pieces into an array and join them.
Number
  - `radix` should be specified in the `parseInt` function to eliminate reader confusion and to guarantee predictable behavior.
Examples

  - `if` statements

        if (condition) {
          statements
        }

        if (condition) {
          statements
        } else {
          statements
        }

        if (condition) {
          statements
        } else if (condition) {
          statements
        } else {
          statements
        }

  - `for` statements

        for (initialization; condition; update) {
          statements;
        }

        for (variable in object) {
          if (condition) {
            statements
          }
        }

  - `switch` statements

        switch (condition) {
          case 1:
            statements
            break;

          case 2:
            statements
            break;

          default:
            statements
        }

## HTML

Indenting
  - Indent using 2 spaces. Don’t use tabs.
  - Although it’s desirable to avoid lines longer than 80 characters, most of the time the templating library doesn’t easily allow this. So try not to extend too much the line length.
Template naming
  - If a template name consists on several words they must be joined using underscores (never hyphens), e.g. my_precious_template.html
  - If a template is being used in AJAX views, even if it is also used for including it on other templates, its name must start with `xhr_`, e.g. xhr_tag_form.html.
  - If a template is intended to be included by other templates, and it is not going to be used directly, start its name with an underscore, e.g. _included_template.html.

## CSS

Indenting
  - Indent using 4 spaces. Don’t use tabs.
  - Put selectors and braces on their own lines.
  - Right-align the CSS browser-prefixed properties.

  Good:

      .foo-bar,
      .foo-bar:hover
      {
          background-color: #eee;
          -webkit-box-shadow: 0 1px 4px #d9d9d9;
             -moz-box-shadow: 0 1px 4px #d9d9d9;
                  box-shadow: 0 1px 4px #d9d9d9;
      }

  Bad:

      .foo-bar, .foo-bar:hover {
        background-color: #eee;
        -webkit-box-shadow: 0 1px 4px #d9d9d9;
        -moz-box-shadow: 0 1px 4px #d9d9d9;
        box-shadow: 0 1px 4px #d9d9d9;
      }

Naming
  - Selectors should all be in lowercase and consequent words should be separated using dashes. As an example, rather use `.tm-results` and not `.TM_results`.