Manuál:Konvence pro psaní kódu

This page is a translated version of the page Manual:Coding conventions and the translation is 99% complete.
Other languages:
English • ‎dansk • ‎español • ‎français • ‎polski • ‎português • ‎português do Brasil • ‎čeština • ‎русский • ‎العربية • ‎تۆرکجه • ‎සිංහල • ‎中文 • ‎日本語
shortcut: CC

Tato stránka popisuje konvence pro psaní kódu se kterým pracuje MediaWiki a její rozšíření, s nimiž se můžete setkat na webových stránkách projektů Wikimedie. Včetně konvence pro tvorbu jmen. Úpravám, které nebudou v souladu s touto konvencí, revidenti kódu dají v hodnocení -1; což lze automaticky brát jako výzvu k tomu, aby byl kód opraven tak, aby byl v souladu s touto konvencí a oprava byla aktualizována.

Tato stránka popisuje všeobecnou konvenci pro psaní kódu, která se týká veškerého kódu MediaWiki, bez ohledu na programovací jazyk. Pro další pokyny, které se týkají konkrétních komponent či typů souborů v MediaWiki, viz:

Na wikitech (platí alespoň pro operace / puppet):

Struktura kódu

Formátování

Odsazení

Řádky mohou být odsazeny znakem tabulátor (tab), pro každou úroveň zanoření. Pokud jde o velikost odsazení tabulátoru co do počtu mezer, tak většina vývojářů MediaWiki používá u svých editorů pro interpretaci tabulátoru 4 mezery, což je optimální pro čtení, ale řada systémů předpokládá, že má tabulátor o velikosti 8 mezer a někteří vývojáři zase pro změnu používají tabulátory o velikosti pouhé 2 mezery.

Uživatelé editoru vim si mohou velikost tabulátoru nastavit tak, že přidají do $HOME/.vimrc následující kód:

autocmd Filetype php setlocal ts=4 sw=4

řádky s nastavením pro CSS, HTML a JavaScript vypadají podobně.

Nicméně v případě Pythonu je podle PEP 8 lepší používat místo tabulátoru mezery.

Konce řádků

Všechny soubory by měly používat unixové konce řádků, t.j. jeden znak LF (line feed - zalomení řádku). Tedy žádnou kombinaci znaků CR (carriage return - návrat vozíku) + LF.

  • git v prostředí Windows (by default) převádí znaky CR+LF (které označují konce řádku v prostředí tohoto systému) na LF při ukládání změn (commit).

Všechny soubory by měly končit prázdným řádkem.

  • Protože je logické, aby všechny řádky končily stejně – znakem zalomení řádku.
  • Jednotné zakončení řádku usnadňuje také předávání dat v jiných než binárních formátech (např. formou rozdílových souborů generovaných přes diff).
  • Pokud se vyskytují v souborech různé typy konce řádku, tak nástroje pro příkazovou řádku, jako např. cat nebo wc nefungují tak, jak by měly.

Kódování

Všechny texty musí být v UTF-8 bez znaku BOM.

Nepoužívejte k editaci souborů Microsoft Notepad, protože ten do nich vždy nacpe BOM. BOM je speciální znak na začátku souboru, na kterém PHP přeruší další zpracování souboru, takže se do webového prohlížeče na straně klienta dostane pouze tento znak.

Stručně řečeno, ujistěte se, že váš editor podporuje UTF-8 bez BOM.

Mezery na konci řádku

Když používáte IDE, stisknutím kláves Domů a Konec (mimo jiné klávesové zkratky) obvykle ignorujete koncové mezery a místo toho přeskočíte na konec určeného kódu. V textových editorech jiných než IDE však stisknutí tlačítka End přeskočí na úplný konec řádku, což znamená, že vývojář musí použít backspace přes koncové mezery, aby se dostal na místo, kam chce skutečně psát.

Odstranění koncové mezery je ve většině textových editorů triviální. Vývojáři by neměli přidávat koncové mezery, zejména ne na řádcích, které obsahují jiný viditelný kód.

Některé nástroje to usnadňují:

  • nano: GNU nano 3.2;
  • Komodo Edit : v nabídce Možnosti uložení z nabídky „Úpravy> Předvolby“ povolte „Vymazat koncové mezery a značky EOL“ (Clean trailing whitespace and EOL markers) a „Pouze vyčistit změněné řádky“ (Only clean changed lines);
  • Kate: koncové mezery můžete vidět povolením možnosti „Zvýraznit koncové mezery“. Tuto možnost najdete v části „Nastavení > Konfigurovat Kate > Vzhled“. Můžete také zadat Kate, aby vyčistila koncové mezery při uložení v „Nastavení > Konfigurovat Kate> Otevřít nebo Uložit“.
  • vim: různé pluginy pro automatické čištění;
  • Sublime Text: TrailingSpaces plugin.

Klíčová slova

Nepoužívejte závorky s klíčovými slovy (jako např. require_once, require), pokud to není nezbytně nutné.

Odsazování a zarovnání

Obecný styl

Styl odsazení MediaWiki je podobný tzv. „One True Brace Style“. Zarážky jsou umístěny na stejném řádku jako začátek funkce, podmínka, smyčka atd. Jinak nebo jinde je umístěn na stejném řádku jako předchozí zavírací zarážka.

function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
    if ( $ts === null ) {
        return null;
    } else {
        return wfTimestamp( $outputtype, $ts );
    }
}

Víceřádkové příkazy se zapisují tak, že druhý a následující řádky jsou odsazeny o jednu úroveň navíc:

Použijte odsazení a konce řádků ke zvýraznění logické struktury vašeho kódu. Výrazy, které se vnořují do více úrovní závorek nebo podobných struktur, mohou začít novou úroveň odsazením s každou úrovní vnoření:

$wgAutopromote = [
    'autoconfirmed' => [ '&',
        [ APCOND_EDITCOUNT, &$wgAutoConfirmCount ],
        [ APCOND_AGE, &$wgAutoConfirmAge ],
    ],
];

V příkazech pro přepínání odsazení v závorkách a mezi případy:

switch ( $word ) {
    case 'lorem':
    case 'ipsum':
        $bar = 2;
        break;
    case 'dolor':
        $bar = 3;
        break;
    default:
        $bar = 0;
        break;
}

Vertikální zarovnání

Vyvarujte se vertikálního zarovnání pomocí tabulátorů. Má tendenci vytvářet rozdíly, které je obtížné interpretovat. Šířka povolená pro levý sloupec musí být neustále zvyšována, jakmile se přidává více položek.

Většina nástrojů, které umí generovat rozdílové soubory nabízí volbu, která umožňuje ignorovat změny v počtu mezer.
Git: git diff -w

Pokud potřebujete, použijte pro vertikální zarovnání položek raději mezery, než tabulátory. Zarovnání jako u tohoto příkladu:

$namespaceNames = [
    NS_MEDIA            => 'Media',
    NS_SPECIAL          => 'Special',
    NS_MAIN             => '',
];

Dosáhnete toho takto (mezery jsou vykresleny jako tečky):

$namespaceNames·=·[
 →  NS_MEDIA············=>·'Media',
 →  NS_SPECIAL··········=>·'Special',
 →  NS_MAIN·············=>·'',
];

(Pokud používáte doplněk tabular vim add-on, zadáním :Tabularize /= zarovnáte znaky '='.)

Zalomení řádků

Řádky by měly být zalomeny mezi 80 a 100 sloupcem. Z tohoto pravidla existují vzácné výjimky. Ale funkce, kterým se předává hodně parametrů, mezi ně rozhodně nepatří.

Operátor který je rozdělen na dva řádky byste měli umisťovat pokud možno konzistentně (pokaždé buď na konci řádku, nebo naopak pokaždé na začátku řádku). I když některé jazyky pro to mohou mít svá vlastní, specifická pravidla.

return strtolower( $val ) === 'on'
    || strtolower( $val ) === 'true'
    || strtolower( $val ) === 'yes'
    || preg_match( '/^\s*[+-]?0*[1-9]/', $val );
$foo->dobar(
    Xml::fieldset( wfMessage( 'importinterwiki' )->text() ) .
        Xml::openElement( 'form', [ 'method' => 'post', 'action' => $action, 'id' => 'mw-import-interwiki-form' ] ) .
        wfMessage( 'import-interwiki-text' )->parse() .
        Xml::hidden( 'action', 'submit' ) .
        Xml::hidden( 'source', 'interwiki' ) .
        Xml::hidden( 'editToken', $wgUser->editToken() ),
    'secondArgument'
);

Operátor metody by vždycky měl být umístěn na začátku dalšího řádku.

$this->getMockBuilder( Message::class )->setMethods( [ 'fetchMessage' ] )
    ->disableOriginalConstructor()
    ->getMock();

Pokud pokračujete v příkazech „if“, přepnutí na složené závorky Allman-style jasně stanoví oddělení mezi podmínkou a tělem:

if ( $.inArray( mw.config.get( 'wgNamespaceNumber' ), whitelistedNamespaces ) !== -1 &&
    mw.config.get( 'wgArticleId' ) > 0 &&
    ( mw.config.get( 'wgAction' ) == 'view' || mw.config.get( 'wgAction' ) == 'purge' ) &&
    mw.util.getParamValue( 'redirect' ) !== 'no' &&
    mw.util.getParamValue( 'printable' ) !== 'yes'
) {
    ..
}

Názory se liší v rozsahu odsazení, které by mělo být použito pro podmíněnou část. Použití množství odsazení odlišného od toho, které používá tělo, objasňuje, že podmíněná část není tělem, ale toto není všeobecně podporováno.

Pokračování podmíněných a velmi dlouhých výrazů bývá ošklivé, ať už je děláte jakýmkoli způsobem. Proto je někdy nejlepší je rozdělit pomocí dočasných proměnných.

Závorky diktují strukturu

I když se vám to může zdát efektivnější, vyvarujte se u podmínek a funkcí psaní jednořádkových "bloků" kódu. Zhoršuje to přehlednost kódu. Důležité příkazy se tím dostávají na pozice, kde je lze při čtení kódu snadno přehlédnout. Uvědomte si, že cílem není získat naňahňaný minimalistický kód. Při psaní kódu byste měli především brát ohled na to, abyste v maximální míře usnadnili čtení kódu, tak aby mu porozuměli i ostatní vývojáři.

// No:
if ( $done ) return;

// No:
if ( $done ) { return; }

// Yes:
if ( $done ) {
    return;
}

Tím se zabrání běžné logické chybě, která je zvláště rozšířená, když vývojář používá textový editor, který nemá funkci „inteligentního odsazení“. K chybě dochází, když je jednořádkový blok později rozšířen na dva řádky:

if ( $done )
    return;

Později změněno na:

if ( $done )
    $this->cleanup();
    return;

To má potenciál vytvářet jemné chyby.

emacs styl

V emacs pomocí php-mode.el od nXHTML mode, můžete nastavit menší režim MediaWiki v souboru .emacs:

(defconst mw-style
  '((indent-tabs-mode . t)
    (tab-width . 4)
    (c-basic-offset . 4)
    (c-offsets-alist . ((case-label . +)
                        (arglist-cont-nonempty . +)
                        (arglist-close . 0)
                        (cpp-macro . (lambda(x) (cdr x)))
                        (comment-intro . 0)))
    (c-hanging-braces-alist
        (defun-open after)
        (block-open after)
        (defun-close))))

(c-add-style "MediaWiki" mw-style)

(define-minor-mode mah/mw-mode
  "tweak style for mediawiki"
  nil " MW" nil
  (delete-trailing-whitespace)
  (tabify (point-min) (point-max))
  (subword-mode 1)) ;; If this gives an error, try (c-subword-mode 1)), which is the earlier name for it

;; Add other sniffers as needed
(defun mah/sniff-php-style (filename)
  "Given a filename, provide a cons cell of
   (style-name . function)
where style-name is the style to use and function
sets the minor-mode"
  (cond ((string-match "/\\(mw[^/]*\\|mediawiki\\)/"
                       filename)
         (cons "MediaWiki" 'mah/mw-mode))
        (t
         (cons "cc-mode" (lambda (n) t)))))

(add-hook 'php-mode-hook (lambda () (let ((ans (when (buffer-file-name)
                                                 (mah/sniff-php-style (buffer-file-name)))))
                                      (c-set-style (car ans))
                                      (funcall (cdr ans) 1))))

Výše uvedená funkce mah/sniff-php-style zkontroluje vaši cestu, když je vyvolán php-mode, aby zjistil, zda obsahuje „mw“ nebo „mediawiki“ a nastaví vyrovnávací paměť pro použití menšího režimu mw-mode pro úpravu zdroje MediaWiki. Že se vyrovnávací paměť mw-mode používá poznáte, protože v řádku režimu uvidíte něco jako „PHP MW“ nebo „PHP / lw MW“.

Manipulace s údaji

Vytváření adres URL

Nikdy nevytvářejte adresy URL ručně s řetězcovým zřetězením nebo podobným způsobem. Pro požadavky zadané vaším kódem vždy používejte plný formát URL (zejména POST a požadavky na pozadí).

V PHP můžete použít příslušnou metodu Linker nebo Title , magické slovo fullurl ve wikitextu, mw.util.getUrl() metoda v JavaScriptu a podobné metody v jiných jazycích. You'll avoid issues with unexpected short URL configuration and more.

Pojmenování souboru

Soubory, které obsahují kód na straně serveru, by měly být pojmenovány v UpperCamelCase. Toto je také naše konvence pojmenování pro rozšíření. [1] Pojmenujte soubor po nejdůležitější třídě. Většina souborů bude obsahovat pouze jednu třídu nebo základní třídu a řadu potomků. Například Title.php obsahuje pouze třídu Title; WebRequest.php obsahuje třídu WebRequest a také její potomky FauxRequest a DerivativeRequest.

Přístupové soubory

Pojmenujte soubory „přístupového bodu“, například SQL, a vstupní body PHP, například index.php a foobar.sql v lowercase. Skripty pro údržbu jsou obvykle v lowerCamelCase i když se to poněkud liší. Soubory určené pro správce webu, jako jsou readmes, licence a changelogs, jsou obvykle v UPPERCASE.

Nikdy nezahrnujte mezery do názvů souborů nebo adresářů a nikdy nepoužívejte znaky jiné než ASCII. U titulů s malými písmeny jsou spojovníky upřednostňovány před podtržítky.

JS, CSS a mediální soubory

U souborů JavaScript, CSS a mediálních souborů (obvykle načtených pomocí ResourceLoader) by se pojmenování souborů mělo shodovat s pojmenováním modulů. Například:

  • Modul mediawiki.foo může obsahovat soubory resources/src/mediawiki.foo/bar.js a resources/src/mediawiki.foo/baz.css
  • modul mediawiki.Title obsahuje soubor resources/src/mediawiki.Title.js

Názvy modulů zaregistrovaných pomocí rozšíření by měly následovat název jako ext.myExtension, například:

  • extensions/FooBar/resources/ext.fooBar/init.js

Díky tomu je snadné najít soubory, i když modul rozdělíte na menší soubory, abyste je mohli pohodlně upravovat, a pak je spojíte do jednoho modulu.

Dokumentace

Dílčí stránky specifické pro jazyk mají více informací o přesné syntaxi kódových komentářů v souborech, např. komentáře v PHP pro doxygen. Použití přesné syntaxe nám umožňuje generovat dokumentaci ze zdrojového kódu na adrese http://doc.wikimedia.org.

Některé prvky MediaWiki jsou dokumentovány v základní složce /docs folder. Pokud například přidáte nový háček, měli byste aktualizovat /docs/hooks.txt s názvem háčku, popisem toho, co háček dělá a parametry používanými háčkem.

Textové soubory

Vývojáři mohou uchovávat soubory dokumentace v Gitu vedle kódu. Může to být užitečné pro podrobnou dokumentaci architektury rozšíření, návrhu databáze atd., kterou byste měli aktualizovat s každým kódem, který změní chování. Stránky na mediawiki.org, které se týkají dokumentace v Gitu, by na ni měly odkazovat pomocí {{git file}}.

(Možnost převést text ze souborů Git na stránky wiki je sledována v phab:T91626.)

Mnoho stránek technické dokumentace na stránkách mediawiki.org dokumentuje vývoj kódu MediaWiki v mnoha vydáních. Popište změny v dokumentu nebo uveďte, že popisuje pouze poslední kódovou základnu v „master“.

Formáty textových souborů

.wiki
Pokud je váš textový soubor wikitext, zadejte příponu .wiki. GitHub umí analyzovat podmnožinu wikitextu, takže foo.wiki soubory zrcadlené na GitHubu budou zobrazovat určité formátování (rozšíření .mediawiki také funguje, ale je delší) . Například docs/lua.wiki rozšíření Wikibase v GitHub.
.md
Doxygen podporuje formátování Markdown, takže můžete do souborů .md vkládat lehce formátovanou dokumentaci. Diffusion a GitHub také podporují soubory .md. Název vysvětlujícího souboru pro adresář nebo projekt README.md. Aplikace Diffusion a GitHub zobrazí tento soubor při prohlížení tohoto adresáře nebo projektu (např. RESTbase doc/development/, v Diffusion a na GitHub).
bez přípony a .txt
Doxygen je standardně analyzuje jako soubory jazyka C (!!, sledované v task T106116). Toho můžete využít tak, že soubor napodobuje komentář C a poté do souboru přidáte doxygenové směrnice. Například includes/filebackend/README vygeneruje Návrh backendového souboru v doxygenu a začíná:
/*!
\ingroup FileBackend
\page file_backend_design File backend design

Some notes on the FileBackend architecture.
...
Special:Version/Credits předpokládá, že AUTHORS a CREDITS (bez přípony) jsou soubory wikitext.

Záhlaví zdrojových souborů

Aby bylo možné vyhovět většině licencí, měli byste mít v horní části každého zdrojového souboru něco podobného následujícímu (specifické pro aplikace GPLv2 PHP).

<?php
/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 * 
 * @file
 */

Licence

Licence se obecně označují celým svým jménem nebo zkratkou podle SPDX standard. Viz také Návod: $wgExtensionCredits#license.

Poznámky k vydání

Musíte dokumentovat všechny významné změny (včetně all fixed bug reports) do základního softwaru, který by mohl ovlivnit uživatele wiki, správce serverů, autory rozšíření v RELEASE-NOTES-N.NN. RELEASE-NOTES-1.35 se vyvíjí. Při každém vydání přesuneme předchozí poznámky k vydání do souboru HISTORY a začneme znovu. RELEASE-NOTES-N.NN je obecně rozdělena do tří sekcí:

  • Změny konfigurace (Configuration changes) je místo, kde můžete dát změny do akceptovaného výchozího chování, zpětně nekompatibilních změn nebo jiných věcí, které potřebuje správce serveru, aby se na ně podíval, a rozhodnul zda "je tato změna pro moji wiki vhodná?". Pokuste se zahrnout stručné vysvětlení toho, jak lze předchozí funkci v případě potřeby obnovit.
  • Opravy chyb (Bug fixes) je místo, kde lze zaznamenat změny, které opravují chování, které je považováno za problematické nebo nežádoucí. Často se jedná o problémy hlášené v Phabricator, ale nemusí to nutně být.
  • Nové funkce (New features') dává na vědomí přidání nových funkcí.

Mohou existovat další oddíly pro konkrétní komponenty (např. Action API) nebo pro různé změny, které nespadají do jedné z výše uvedených kategorií.

Ve všech případech, pokud vaše změna je odpovědí na jeden nebo více problémů hlášených v programu Phabricator, uveďte ID úlohy na začátek záznamu. Doplnit nové položky v chronologickém pořadí na konci oddílu.

Systémové zprávy

Při vytváření nové systémové zprávy, pokud je to možné, použijte pomlčky (-) místo CamelCase nebo snake_case. Například some-new-message je správné jméno, zatímco someNewMessage a some_new_message jsou špatně.

Pokud se zpráva použije jako štítek, který může mít dvojtečku (:) na konci, dvojtečku netiskněte. Místo toho vložte dvojtečku do textu zprávy. Některé jazyky (např. Francouzština, které nejdříve potřebují mezeru) musí zpracovat dvojtečky jiným způsobem, což je nemožné, pokud je dvojtečka pevně zakódována. Totéž platí pro několik dalších typů interpunkce.

Zkuste použít kódy zpráv „celé“ v kódu, spíše než je stavět za chodu; protože to usnadňuje jejich vyhledávání v kódové základně. Následující příklad například ukazuje, jak hledání templatesused-section nenajde toto použití klíče zpráv, pokud není použit jako celek.

// No:
return wfMessage( 'templatesused-' . ( $section ? 'section' : 'page' ) );

// Yes:
$msgKey = $section ? 'templatesused-section' : 'templatesused-page';
return wfMessage( $msgKey );

Pokud máte pocit, že musíte vytvářet zprávy za chodu, vložte komentář se všemi možnými celými zprávami v okolí:

// Messages that can be used here:
// * myextension-connection-success
// * myextension-connection-warning
// * myextension-connection-error
$text = wfMessage( 'myextension-connection-' . $status )->parse();

Další konvence o vytváření, používání, dokumentování a údržbě klíčů zpráv viz Lokalizace.

Preferované hláskování

Stejně tak důležité je mít konzistentní pravopis v uživatelském rozhraní a v kódové základně. Stejně jako mít konzistentní uživatelské rozhraní. Podle dlouhé historie je 'americká angličtina' preferovaným hláskováním pro zprávy, komentáře a dokumentaci v anglickém jazyce.

Zkratky v klávesách pro zprávy

ph
zástupný symbol (text ve vstupních polích)
tip
popis textu
tog-xx
přepínání možností v uživatelských předvolbách

Interpunkce

Chybové zprávy bez názvu jsou považovány za věty a měly by obsahovat interpunkci.

Vylepšení jádra

Pokud potřebujete nějakou další funkcionalitu z jádrové komponenty MediaWiki (třída PHP, modul JS atd.), Nebo pokud potřebujete funkci, která dělá něco podobného, ale mírně odlišného, upřednostňujte vylepšení základní komponenty. Vyhněte se duplikování kódu na příponu nebo jinde v jádru a tam jej neupravujte.

Refactoring

Kód refaktoru při provádění změn: nedovolte, aby se kód při každé změně zhoršoval.

Pokud je však refaktoring velký, použijte samostatné potvrzení. Viz také Pokyny pro architekturu (pracovní verze).

HTML

MediaWiki HTTP odešle výstup HTML, který lze vygenerovat jedním ze dvou zdrojů. PHP kód MediaWiki je důvěryhodným zdrojem uživatelského rozhraní. Může vydávat libovolný HTML. Analyzátor převádí wikitext generovaný uživatelem do HTML. Jedná se o nedůvěryhodný zdroj. Složité HTML vytvořené uživateli pomocí wikitextu se často nachází v oboru názvů „Template“. HTML vytvořené analyzátorem je před výstupem vyčištěno.

Většinu datových atributů mohou uživatelé používat ve wikitextu a šablonách. Následující předpony však byly omezeny a ve wikitextu nejsou povoleny. To umožňuje klientskému kódu JavaScript určit, zda prvek DOM pochází z důvěryhodného zdroje:

  • data-ooui - Tento atribut je přítomen v HTML generovaném widgety OOUI.
  • data-parsoid – rezervovaný atribut pro interní použití společností Parsoid.
  • data-mw and data-mw-... – vyhrazený atribut pro vnitřní použití jádrem, vzhledy a rozšířeními MediaWiki. data-mw data-mw je také používán Parsoidem.

Při výběru prvků v JavaScriptu lze určit klíč nebo hodnotu atributu, aby bylo zajištěno, že budou brány v úvahu pouze prvky DOM ze zamýšleného důvěryhodného zdroje. Příklad: Only trigger 'wikipage.diff' hook for official diffs.

Poznámky

Externí odkazy