Návod:Pravidla pro psaní kódu

This page is a translated version of the page Manual:Coding conventions and the translation is 100% complete.

Tato stránka popisuje pravidla 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ě pravidel pro tvorbu pojmenování. Úpravám, které nebudou v souladu s těmito pravidly, kontroloři 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 těmito pravidly a oprava byla aktualizována.

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

Na wikitech (platí alespoň pro provozní nebo hrané):

Struktura kódu

Formáty souboru

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í. Řada systémů ale předpokládá, že má tabulátor velikost 8 mezer. 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. pouze 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 přidá 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ů (Home) a Konec (End) (mimo jiné klávesové zkratky) obvykle nevšímáte si koncových mezer 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čí kurzorem 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ů jednoduché. 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 (Save Options) uložení z nabídky "Úpravy> Předvolby" (Edit > Preferences) 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" (Highlight trailing spaces). Tuto možnost najdete v části "Nastavení > Konfigurovat Kate > Vzhled" (Settings > Configure Kate > Appearance). Můžete také zadat Kate, aby vyčistila koncové mezery při uložení v "Nastavení > Konfigurovat Kate> Otevřít nebo Uložit" (Settings > Configure Kate > Open/Save).
  • vim: různé pluginy pro automatické čištění;
  • Sublime Text: TrailingSpaces plugin.

Klíčová slova

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

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. rozhodovací znaky (else nebo elseif) jsou umístěny 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 ],
    ],
];

Vertikální zarovnání

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

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. Použijte 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 jednotně (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í jiného odsazení odlišného od toho, jaké používá tělo, objasňuje, že podmíněná část není tělem. Toto ale 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, kdy 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á, pokud 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 (textový editor) 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, pokud 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 používá vyrovnávací paměť mw-mode 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() metodu v JavaScriptu a podobné metody v jiných jazycích. Vyhnete se nejen problémům s neočekávanou krátkou konfigurací URL ale i dalším.

Pojmenování souboru

Soubory, které obsahují kód na straně serveru, by měly být pojmenovány v UpperCamelCase (první písmeno každého slova je ve složeném slově velké). 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 (každé slovo ve složeném slově je psáno velkými písmeny, s výjimkou prvního slova). 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 (napsané velkými písmeny).

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 (nachází hned vedle pravého Shiftu. Na jeho klávese jsou celkem čtyři znaky: náš spojovník (-), podtržítko (_), otazník (?) a lomeno (/)) upřednostňovány před podtržítky.

JS, CSS a mediální soubory

V případě JavaScriptu by CSS a další soubory frontend (obvykle načtené prostřednictvím ResourceLoader) měly být umístěny v adresáři pojmenovaném podle modulu, ve kterém jsou registrovány. Například. modul mediawiki.foo může obsahovat soubory mediawiki.foo/Bar.js a mediawiki.foo/baz.css.

Jména souborů JavaScript, které definují třídy, by měla přesně odpovídat názvu třídy, kterou definují. Třída TitleWidget by měla být v souboru pojmenovaném jako TitleWidget.js nebo s koncovkou. To umožňuje rychlou navigaci v textových editorech tím, že přejdete k souborům pojmenovaným podle názvu vybrané třídy (například "Goto Anything [P]" (Přejít na cokoli) v Sublime nebo "Find File [P]" (Najít soubor) v Atomu).

Velké projekty mohou mít třídy v souladu s názvy, které by se překrývaly nebo byly nejednoznačné bez nějakého dalšího způsobu organizace souborů. Obecně k tomu přistupujeme pomocí podadresářů, jako je ext.foo/bar/TitleWidget.js (pro soubory balíčků), nebo delší názvy tříd a souborů jako mw.foo.bar.TitleWidget v ext.foo/bar.TitleWidget.js.

Balíčky modulů registrované příponami by měly mít názvy jako ext.MyExtension, například extensions/MyExtension/resources/ext.myExtension/index.js.

Díky tomu je snadné začít pracovat na modulu v textovém editoru přímým vyhledáním souborů zdrojového kódu pouze z veřejného názvu modulu (T193826).

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ých pravidel pro jazyk nám umožňuje vytvářet dokumentaci ze zdrojového kódu na adrese https://doc.wikimedia.org.

Koncepty, subsystémy a datové toky na vysoké úrovni by měly být dokumentovány ve složce /docs.

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ě všech zpráv o opravených chybách) 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.38 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ěleno do tří sekcí:

  • Změny konfigurace (Configuration changes) je místo, kde můžete uvést změny do odsouhlaseného výchozího chování, zpětně nevhodnýchch změn nebo jiných věcí, které potřebují 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í tomu 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. Nové položky doplňujte 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 v kódu použít "celé" klíče zpráv, než abyste je stavěli průběžně za chodu. Usnadňuje to jejich vyhledávání v kódové základně. Následující příklad ukazuje, jak hledání templatesused-section nenajde použití tohoto klíče, 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 průběžně, vložte komentář se všemi možnými celými zprávami pro ostatní:

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

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

Preferované hláskování

Stejně tak jako je důležité mít shodný pravopis v uživatelském rozhraní a v kódové základně, je nutné mít shodné 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 duplikaci kódu na rozšíření nebo jinde v jádru a jeho místním úpravám.

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 (provádění změn v softwarovém systému takovým způsobem, že nemají vliv na vnější chování kódu, ale vylepšují jeho vnitřní strukturu s minimálním rizikem vnášení chyb) 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ů. Kód MediaWiki PHP je důvěryhodným zdrojem pro uživatelské rozhraní, může vydávat libovolné HTML. Analyzátor převádí uživatelem generovaný wikitext do HTML. Jedná se o nedůvěryhodný zdroj. Složitý HTML vytvořený uživateli prostřednictvím wikitextu se často nachází v jmenném prostoru "Template" (šablona). HTML vytvořené analyzátorem podléhá před výstupem ošetření.

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 a data-mw-... – atribut vyhrazený pro vnitřní použití jádrem, zobrazeními 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