No Title Found

AbstractNo Abstract Found

Cíle

Tento projekt má za cíl vytvořit webovou aplikaci, která uživatelům umožní nejen snadné sdílení vlastních prezentací, ale také jejich tvorbu. Jediným nástrojem tak uživatel prezentaci vytvoří a poté ji v rámci aplikace či jiných komunikačních kanálů, jako jsou sociální sítě, může šířit dál.

Protože na trhu již existují služby, které podobné možnosti nabízejí, chtěl jsem projekt posunout dál a využít výhod, které HTML prezentace poskytují. Tvorbu a prohlížení prezentací jsem proto více zaměřil na použití ve vzdělávacích institucích či školách a nebo odborných konferencích, kde je důležité v prezentacích podat důležité informace, tedy nejen hlavní body přednášky.

Aplikace bude poskytovat prostředky pro zjednodušení tohoto cíle. V prezentacích tak bude možné barevně zvýraznit kód programovacích jazyků či zobrazit matematické vzorce pomocí syntaxe LaTeX. Navíc bude možné do snímků vkládat kontrolní otázky, na které budou moci uživatelé odpovídat, a tak si ověřit své znalosti, případně lze přidat i doplňující text s odkazem na konkrétní snímek s odpovědí. Stejně tak je důležité, aby tyto prezentace byly použitelné i mimo přednášku a podaly významné informace i bez mluveného slova, například pro domácí přípravu nebo vlastní rozvoj.

Příležitosti

Od práce na tomto projektu si slibuji větší porozumění technologii HTML5 a JavaScriptu. Zajímavou příležitostí je i vyzkoušení si tvorby webových stránek, které nejsou jen dalším typickým informačním systémem. V tomto projektu lze najít spoustu problémů, ale také nové a zajímavé technologie, na kterých si vyzkouším vývoj moderních klientských aplikací.

Analýza

V této kapitole jsou představeny požadavky a vize vyvíjeného systému. Čtenář je uveden do problematiky HTML\nomenclatureHTMLHyperText Markup Language prezentací a s tím jsou představeny i knihovny, které zajišťují funkčnost těchto prezentací. Nakonec jsou stručně popsány podobné již existující systémy.

User stories

\label{chap:userstory}

Následující odstavce uvádí uživatelské role, které se při používání systému objevují. Každá role pak má nějaká práva či možnosti využití systému. Popis je zapsán pomocí techniky zvané user story používané v agilních metodikách vývoje softwaru.

Každý odstavec je uveden názvem uživatelské role, za níž následuje výčet možností, které systém dané roli dává.

Nepřihlášený uživatel bude mít možnost:

  1. 1.

    prohlížet veřejně dostupné prezentace, k tomu použije:

      [label*=0.]
    1. (a)

      vyhledávací formulář na webu,

    2. (b)

      adresu URL na stránku s prezentací, kterou dostane jiným komunikačním kanálem,

  2. 2.

    vyhledat prezentace vyhledávacím formulářem podle názvu nebo autora, aby mohl

      [label*=0.]
    1. (a)

      zhlédnout hledanou prezentaci,

    2. (b)

      číst komentáře pod prezentací,

    3. (c)

      zobrazit prezentace hledaného uživatele,

  3. 3.

    přihlásit se do systému pomocí přihlašovacího formuláře, aby získal oprávnění přihlášeného uživatele (viz níže),

  4. 4.

    registrovat se do systému pomocí registračního formuláře, aby se mohl přihlásit.

    Přihlášený uživatel bude mít kromě registrace a přihlášení stejné možnosti jako nepřihlášený uživatel. Navíc bude mít možnost:

    1. (a)

      vytvářet prezentace pomocí editoru prezentací, aby je poté mohl prohlížet a sdílet,

    2. (b)

      posílat komentáře k prezentacím, aby dal zpětnou vazbu autorovi prezentace či diskutoval s ostatními uživateli,

    3. (c)

      prohlížet veřejné a jemu sdílené prezentace,

    4. (d)

      vyhledat uživatele vyhledávacím formulářem podle uživatelského jména, aby mohl:

        [label*=0.]
      1. i.

        sledovat hledaného uživatele, aby byl upozorněn na jeho nové prezentace,

      2. ii.

        zrušit sledování hledaného uživatele,

    5. (e)

      vidět seznam jemu sdílených prezentací, aby si je mohl prohlédnout,

    6. (f)

      vidět seznam veřejných prezentací uživatelů, které sleduje, aby si je mohl prohlédnout,

    7. (g)

      změnit své heslo,

    8. (h)

      odhlásit se.

      Autor prezentace , tj. přihlášený uživatel, který vytvořil prezentaci, bude mít možnost:

      1. i.

        upravit prezentaci v editoru, aby ji o něco doplnil nebo opravil chyby,

      2. ii.

        smazat prezentaci, aby ji odstranil ze systému,

      3. iii.

        smazat jakýkoliv komentář k vlastní prezentaci, aby moderoval diskuzi,

      4. iv.

        sdílet prezentaci s ostatními uživateli systému, aby si ji mohli prohlédnout.

      Autor komentáře , tj. přihlášený uživatel, který napsal komentář, bude mít možnost smazat svůj komentář.

Nefunkční požadavky

Následující seznam uvádí nefunkční požadavky, tedy omezující podmínky, které systém musí dodržet. Podmínky vycházejí ze zadání tohoto projektu.

  1. 1.

    Systém bude přístupný přes webové rozhraní

  2. 2.

    Systém bude pro uživatele nezávislý na platformě

  3. 3.

    Systém bude využívat technologii HTML5

  4. 4.

    Pro prezentace bude systém využívat JavaScriptovou knihovnu

Doménový model

Z user stories vychází doménový model, který ukazuje celý systém jako provázané entity. Celý model je přehledně zobrazen na obrázku \ref{fig:domainModel} v jazyce UML. Popis jednotlivých entit a jejich vlastností následuje v odstavcích níže.

\label{fig:domainModel}Diagram doménového modelu

Uživatel

Uživatel představuje registrovaného uživatele systému. Registrovaný a přihlášený uživatel má výhody oproti nepřihlášenému (více na str. LABEL:chap:userstory).

Pro úspěšnou registraci nového uživatele do systému musí nepřihlášený uživatel zadat:

  • uživatelské jméno, pod kterým se bude prezentovat a přihlašovat. Stejné uživatelské jméno musí být v systému registrováno jenom jednou,

  • e-mail, který musí být v systému jedinečný,

  • heslo o minimální délce 4 znaků.

Uživatelé se mohou navzájem tzv. sledovat. Uživatel je tak snadněji upozorněn na nové prezentace od sledovaných autorů.

Prezentace

Tato entita představuje jednu prezentaci, kterou uživatel pomocí systému vytvořil, tedy je jejím autorem. Má tyto povinné vlastnosti:

  • název, pod kterým se daná prezentace bude zobrazovat ve výpisech,

  • slug – zjednodušený název (malá písmena anglické abecedy, čísla a pomlčky), pod kterým bude prezentace dostupná přes adresu URL. Pro daného autora je jedinečný, tj. kombinace uživatelského jména a slugu je unikátní,

  • obsah, jenž představuje složitější objekt textů jednotlivých snímků a různých nastavení prezentace.

Při vytvoření je prezentace ve stavu nepublikováno. Stav se změní na publikováno při publikaci prezentace v editoru. Pak je prezentace viditelná ostatním uživatelům v systému.

Prezentace může být sdílena konkrétním uživatelům systému.

Koncept

Koncept je obsah prezentace (popis snímků, nastavení), který nebyl zatím publikován. Je viditelný pouze v editoru pro autora prezentace. Při publikaci změn prezentace se obsah konceptu překopíruje do obsahu vlastní entity prezentace, změny jsou pak viditelné i ostatními uživateli.

Komentář

Komentář je uživatelem napsaná poznámka k dané prezentaci. Komentář může vkládat každý přihlášený uživatel. Povinné vlastnosti jsou:

  • text komentáře – obsah zprávy,

  • datum a čas, kdy byl komentář vložen.

Komentář se váže k jedné prezentaci a jednomu uživateli – autorovi komentáře.

Co je HTML prezentace?

Prezentace založené na HTML jsou z pohledu kódu běžná webová HTML stránka. K popisu obsahu snímků se používají sémantické značky běžně používané v HTML (např. nadpisy, odstavce, obrázky). Pro úpravu grafické podoby se pak používá CSS\nomenclatureCSSCascading Style Sheets. S použitím technologie HTML5 lze pak využít i nových možností CSS3, například animace přechodů. K oživení takovéto stránky a vytvoření dojmu prezentace včetně interakce s uživatelem pro přechod mezi snímky se používá JavaScript. To vše a další vylepšující funkce jsou zajištěny mnoha existujícími JavaScriptovými knihovnami.

Každá z existujících knihoven používá rozdílná pravidla pro konfiguraci prezentace či jednotlivých snímků. Následující výpis ukazuje zdrojový kód jednoduché HTML prezentace při použití knihovny deck.js.

Výpis 1: Výpis
[caption=Ukázka zdrojového kódu HTML prezentace (deck.js),captionpos=b]
<body class="deck-container">
  <section class="slide">
    <h1>Moje prezentace</h1>
  </section>
  <section class="slide">
    <h2>Nadpis snímku</h2>
    <p>Osnova:</p>
    <ul>
      <li>Bod 1</li>
      <li>Bod 2</li>
      <li>Bod 3</li>
    </ul>
  </section>
</body>

Zobrazení právě jednoho snímku, přecházení mezi snímky a držení stavu prezentace pak obstarává knihovna samotná. Na autorovi prezentace je pak napsat obsah snímků a dodržet konvence požadované knihovnou.

Výběr JavaScriptové knihovny

Knihoven pro zobrazení prezentací založených na technologii (X)HTML byla vytvořena celá řada (citation not found: htmlslideshowweb). Většina z nich je ovšem už zastaralá, nefunkční nebo neodpovídající požadovaným kvalitám, například použitelností (uživatelské či implementační) nebo zastaralým vzhledem. Následující seznam uvádí několik zdařilých knihoven, které se objevily po uvedení podpory HTML5 v prohlížečích.

  • reveal.js

  • impress.js

  • Google I/O HTML5 slide template

  • deck.js

Následující odstavce stručně popisují každou z uvedených knihoven. Nakonec je uvedeno jaká knihovna byla vybrána pro tento projekt a proč.

Reveal.js

\label{chap:revealjs}

Reveal.js (citation not found: revealjs) je vizuálně pěkná knihovna, která kromě posunu snímků horizontálně podporuje také vnořené snímky, na které se lze dostat posunem dolů. Má několik zajímavých rozšíření, např. podpora syntaxe MarkDown pro psaní obsahu a barevné zvýraznění kódu programovacích jazyků pomocí knihovny highlight.js. V novém okně prohlížeče pak poskytuje zobrazení prezentace pro přednášejícího, který ukazuje aktuální a následující snímek včetně poznámek.

Impress.js

Impress.js (citation not found: impressjs) se zaměřuje na vizuální jedinečnost prezentace. Dosahuje toho složitými transformacemi přechodů mezi snímky. Ty jsou rozložené v prostoru a to nejen ve 2D, ale i ve 3D. Snímky tak lze mít v různých velikostech, pozicích a orientacích a při přechodu mezi nimi se pohled působivě otáčí a přesouvá.

Nevýhoda této knihovny je právě v tomto jednoúčelově pojatém zobrazení. Pro tento projekt je tak knihovna až moc složitá, hlavně kvůli určení pozic snímků a definici transformací, a pro informativní prezentace se příliš nehodí, neboť přechody mezi snímky spíše vyrušují.

Google I/O HTML5 slide template

Šablonu snímků od Googlu (citation not found: googletemplate) používají při svých prezentacích vývojáři na konferencích Google I/O. Knihovna je proto v dobré kvalitě a velmi dobře uzpůsobená pro přednášející. Obsahuje tzv. prezentační mód podobný tomu v reveal.js. Poskytuje také zvýraznění kódu programovacích jazyků a to včetně možnosti zdůraznit jen určitou část kódu, které se přednášející chce věnovat podrobněji.

Knihovna ovšem nenabízí žádnou dokumentaci, a tak snižuje možnost pro další rozšíření. Dále má prezentace pevnou velikost, na menších displejích či oknech jsou tak snímky oříznuté. Nevýhodou je také o něco složitější konfigurace.

Deck.js

Knihovna deck.js (citation not found: deckjs) je v základu o něco jednodušší než knihovny výše uvedené, ale podporuje všechny základní funkce. Je napsaná s pomocí knihovny jQuery (citation not found: jQuery) a je velmi dobře zdokumentovaná a rozšiřitelná. Existuje pro ni řada pluginů, například již zmíněný prezentační mód či podpora MarkDown syntaxe pro popis snímků.

Zhodnocení

Všechny výše uvedené knihovny umí v základu to samé, a to zobrazovat jednotlivé snímky a přecházet mezi nimi. Pro účely tohoto projektu byla vybrána knihovna deck.js, která neposkytuje tolik doplňkových možností, ale líbí se mi její celkový vzhled, jednoduchost a integrace s jQuery. Lze také využít existujících rozšíření nebo vytvořit vlastní. Knihovna reveal.js ovšem urazila během práce na tomto projektu velký kus cesty a v současné době je asi nejvíce rozšířenou a používanou knihovnou pro HTML prezentace. O knihovně již byla také napsána výuková kniha (citation not found: howtobook).

Vize

Následující odstavce popisují mojí vizi systému. Text je rozdělen do sekcí, jenž představují samostatné logické celky systému.

Webové rozhraní

Pro uživatele slouží web jako prostředník pro sdílení prezentací – ať už v rámci systému mezi jeho uživateli nebo posíláním URL odkazů na prezentace v emailech, příspěvcích na sociálních sítích jako Facebook nebo Twitter a dalších. V principu se tak podobá službám jako jsou YouTube, SlideShare nebo GitHub, které se zaměřují na vystavení vlastní tvorby (videí, prezentací, kódu) a její sdílení.

Sdílení prostřednictvím webové aplikace je dvojího typu. Uživatelé mohou sledovat jiné uživatele a o aktivitách těchto sledovaných uživatelů, například publikace nové prezentace, budou snadněji upozorněni. Druhý typ je pak sdílení opačným směrem – od autora prezentace jednotlivým uživatelům aplikace. Uživatele si autor vybere podle uživatelského jména či e-mailu.

Důležitá je také zpětná vazba od uživatelů prohlížející si prezentace. Řešením je možnost přidávat komentáře k jednotlivým prezentacím.

Editor

Důležitou částí tohoto projektu je editor pro úpravy prezentace. Protože je obsah prezentace tvořen pomocí HTML, nabízí se několik možností, jak editaci pojmout, a to:

  1. 1.

    psaním samotného HTML kódu,

  2. 2.

    využitím editoru typu What You See Is What You Get (WYSIWYG)\nomenclatureWYSIWYGWhat You See Is What You Get,

  3. 3.

    využitím jednoduchého textového značkovacího jazyka (lightweight markup language).

Psaní samotného HTML kódu bylo vyloučeno bez většího váhání. HTML není nijak úsporný značkovací jazyk a pro uživatele, kteří neznají HTML, by byl překážkou. Na druhou stranu ale poskytuje největší možnou kontrolu nad podobou a funkčností prezentace. Kdyby ovšem editor měl být založen pouze na psaní HTML kódu, nebyl by vůbec potřeba – pro většinu uživatelů by pak bylo výhodnější použít nástroje, na které jsou zvyklí, a pak pouze nahrát hotovou prezentaci na web.

Editor WYSIWYG je koncept dobře známý z desktopových aplikací. Jedná se o přímou úpravu obsahu a uživatel nepřichází do styku se zdrojovým kódem. Jeho největší výhodou je pak jednoduchost pro uživatele, kteří výsledek svých úprav vidí okamžitě. Ve webovém prostředí se používá pro jednoduché vytváření stránek, například v CMS systémech. Nevýhodou je, že neexistuje standard, který by byl dodržován všemi prohlížeči. Poskytuje také menší kontrolu nad výsledným kódem.

Vybrána byla nakonec poslední možnost – jednoduchý textový značkovací jazyk, jímž se bude popisovat obsah snímku. Zdrojový text psaný v tomto jazyce se následně převádí do kódu HTML. Více je popsáno v kapitole \ref{chap:realizace} LABEL:chap:realizace na str. LABEL:chap:realizace.

Prohlížení prezentace

Zajímavou vlastností, která se liší od ostatních webových služeb pro prohlížení prezentací, byla možnost poskytnout větší interaktivitu s uživatelem. Vzhledem k tomu, že je prezentace běžná HTML stránka, lze využít možností webových technologií pro vytvoření nových vlastností prezentace.

Jednou z nich je možnost odpovídat na otázky a kontrolovat správné odpovědi přímo v prezentaci. Uživatelé si pak mohou ověřit, co se z prezentace dozvěděli. Navíc je možné zobrazit doplňkový text při správné či špatné odpovědi. Ten pak může obsahovat nejen vysvětlení správné odpovědi, ale třeba i odkaz na snímek týkající se dané otázky.

Rešerše existujících řešení

\label{chap:existujiciSystemy}

Během analýzy byly také vyhledány a vyzkoušeny již existující služby, jejichž funkčnost se nejvíce podobá zadání tohoto projektu. Následující odstavce popisují jejich funkce a rozdíly.

SlideShare

SlideShare (citation not found: slideshare) je velmi známá webová služba pro sdílení prezentací. Obsahuje podobné mechanismy sdílení a zpětné vazby a umožňuje prezentace umisťovat na jiné stránky (tzv. embedded prezentace). Prezentace jsou ovšem velmi statické – bez animací a bez větší interaktivity s uživatelem. Některé prezentace jsou jen obrázkové, nejde tedy označit text ani následovat odkaz. Největší nevýhodou je, že prezentace nelze přímo tvořit. Lze je pouze nahrávat ve formátech PDF, PPT a dalších z lokálního úložiště. Jakákoliv změna v prezentaci se tak musí nahrát znovu.

Prezi

Prezi (citation not found: prezi) se na rozdíl od ostatních daleko více zaměřuje na grafickou stránku a zakládá si na kreativitě uživatelů a vyjádření jejich idejí pomocí celkového vzhledu prezentace. Prezentace se značně liší od běžných prezentací, které známe například z Microsoft PowerPoint. Jejich použití se hodí hlavně pro vyjádření nějaké myšlenky či vize, méně se hodí pro podání důležitých informací. Velmi dobrou vlastností je živé sdílení, tj. procházení prezentací se synchronizuje mezi více online uživateli. Pro zobrazení prezentace používá technologii Flash.

Rvl.io

Rvl.io (citation not found: rvlio) je služba od autora knihovny reveal.js popsané na str. LABEL:chap:revealjs, kterou také používá pro zobrazení prezentací. Služba umožňuje sdílení i tvorbu prezentací přímo na webu. Sdílení je založeno na předávání adresy URL, poskytuje ale také vkládání prezentace do jiných stránek, podobně jako SlideShare. Pro úpravu prezentací využívá WYSIWYG editor, který ale poskytuje jen nezbytné minimum funkcí. Tato služba je velmi mladá a uvedena byla měsíc po započetí práce na tomto projektu. V době psaní této práce byla stále ve fázi beta testování.

Shrnutí

Rvl.io jako jediný z vybraných systémů používá pro zobrazení prezentací HTML. Také poskytuje možnost tvorby prezentace a její sdílení, nejvíce se tak podobá zadání tohoto projektu. Neposkytuje ovšem žádnou přidanou hodnotu, která by se dala ve webovém prostředí využít. SlideShare staví do popředí hlavně sdílení prezentací a má proto bohaté mechanismy. Služba Prezi, i když velmi vydařená a propracovaná služba, naopak míří zcela na jinou cílovou skupinu.

Návrh

V následujícím textu je čtenář seznámen s detailním návrhem systému, použitými technologiemi a knihovnami.

Serverová část

Webový back-end jsem se rozhodl napsat v programovacím jazyce PHP s použitím českého webového aplikačního frameworku Nette (citation not found: nette). Pro uchování dat byla použita databáze MySQL (citation not found: mysql).

Nette Framework

Nette Framework je aplikační framework, který usnadňuje řešení mnoho problémů v oblasti webového vývoje v PHP. Implementuje návrhový vzor Model-View-Presenter (MVP)\nomenclatureMVPModel-View-Presenter rozdělující aplikaci na logické vrstvy (viz níže). Běh aplikace je řízen událostmi, tedy využívá událostmi řízené programování. Dále obsahuje komponentový model zaměřený na znovupoužitelnost.

MVP

Návrhový vzor Model-View-Presenter řeší problém oddělení datové vrstvy, řízení událostí (např. od uživatele) a vykreslení daných dat (citation not found: mvp). Následuje popis jednotlivých vrstev a jejich společné interakce.

  • Model – poskytuje rozhraní pro data určená k zobrazení

  • View (pohled) – vykresluje data modelu a směruje uživatelské příkazy presenteru

  • Presenter – prostředník mezi modelem a pohledem. Získává data z modelu a upravuje je pro zobrazení v pohledu. Řeší události vyvolané uživatelem.

Architektura aplikační logiky

Nette Framework ovšem neposkytuje žádné vlastní řešení modelové vrstvy a nechává tak programátorovi volné ruce na využití jiných knihoven nebo vlastních řešení zaměřujících se na obchodní a datovou logiku. Do presenteru je pak možné tyto služby předat pomocí návrhového vzoru Dependency injection (citation not found: di).

Pro tento projekt byla využita databázová vrstva Nette\Database, která poskytuje jednoduché rozhraní pro získávání dat z databáze. Komunikace s databází pak byla zabalena do repositářů, jenž poskytují metody pro navrácení jednotlivých entit a tvorbu a mazání záznamů. V případech, kdy je logika složitější a repositáře tuto funkčnost nemohou vykonat, je přidána další vrstva – fasáda.

Lepší představu o průběhu chodu aplikace při uživatelském požadavku získáte z obrázku \ref{fig:logika}. Všechny komponenty serverové části pak přehledně zobrazuje diagram balíčků \ref{fig:balicky}.

\label{fig:logika}Ukázka průchodu aplikace

\label{fig:balicky}Diagram balíčků

Klientská část

Na klientské prostředí jsou přenášeny výstupy v podobě HTML stránek. Pro jejich oživení a zlepšení uživatelské použitelnosti (např. klientské validace formulářů) se používá JavaScript. Vlastní kód byl však napsán v CoffeeScriptu (citation not found: coffee) – transkompilátoru, který se kompiluje do běžného JavaScriptu.

Dále byla použita JavaScriptová knihovna jQuery (citation not found: jQuery), která usnadňuje práci s HTML dokumentem a sjednocuje implementační rozdíly mezi prohlížeči.

Pro vzhled a grafické uživatelské rozhraní byl použit framework Bootstrap (citation not found: bootstrap), který velmi usnadnil prototypování uživatelského rozhraní aplikace bez nutnosti tvořit vzhled a ladit ho pro každý prohlížeč zvlášť. Dále poskytuje jednoduché metody pro tvorbu nabídek či zobrazení dialogových oken. Výhodou je i to, že Bootstrap poskytuje responsivní design a tak by se web měl chovat a zobrazovat korektně i na mobilních zařízeních.

Editor

Editoru prezentací byl přikládán větší význam, neboť bez této komponenty by systém nemohl realizovat myšlenku tohoto projektu. Značně se také liší od ostatních obyčejných webových stránek, jelikož se jedná z větší části o ryze klientskou jednostránkovou miniaplikaci.

Právě proto používá editor pár technologií navíc. Jako nejdůležitější se ukázalo použití JavaScriptového MVC\nomenclatureMVCModel-View-Controller frameworku AngularJS (citation not found: angular). Jeho hlavní předností je dvoucestné provázání dat mezi pohledem (view) a modelem na straně klienta. Každá změna v modelu se pak automaticky propaguje do pohledu a naopak. Snižuje se tak množství kódu, který otrocky nastavuje nebo zobrazuje data při každé změně.

Pro popis obsahu snímku, jak bylo zmíněno v analýze, se používá jednoduchý textový značkovací jazyk, který převádí text do HTML. Pro převod tohoto textu je použita PHP knihovna Texy! (citation not found: texy), která implementuje vlastní stejnojmenný značkovací jazyk. Výhodou této knihovny je snadná rozšiřitelnost a také typografické úpravy výsledného textu. Více o výběru knihovny se dozvíte v následující kapitole.

Součástí editoru je také panel nástrojů, který doplňuje textový vstup pro popis snímku. Uživateli ulehčí práci s psaním zdrojového textu, například možností vložit značky pro tučné písmo, kurzívu a další. Pro panel nástrojů byla použita knihovna Texyla (citation not found: texyla).

Realizace klientské části

\label{chap:realizace}

V této kapitole se dozvíte o průběhu realizace klientské části aplikace, tj. editoru prezentací a zobrazení prezentací, co vedlo k rozhodnutím o podobě projektu a jaké problémy vyvstaly a jak byly řešeny.

This block failed to display. Double-click this text to correct any errors. Your changes are saved.

Rozložení editoru

Dalším úkolem bylo navrhnout prostředí editoru. Rozložení bylo provedeno v podobném stylu jako u známých nástrojů pro tvorbu prezentací Microsoft PowerPoint a OpenOffice Impress, tedy obrazovka byla rozdělena na sloupec náhledů všech snímků po levé straně obrazovky a na editaci právě upravovaného snímku vpravo.

Protože se ale pro popis obsahu snímku používá značkovací jazyk namísto WYSIWYG editoru, bylo uživatelsky příjemnější přidat také náhled výsledného snímku po převodu zdrojového textu do HTML. Tímto se obrazovka rozdělila ještě na vstupní textové pole pro zdrojový text a velký náhled právě upravovaného snímku. Textové pole má navíc panel nástrojů, který umožňuje vkládat značky (například nadpis, nebo kurzívu) pomocí tlačítek.

\label{fig:editorLayout}Ukázka editoru (vlevo náhledy všech snímků, uprostřed pole zdrojového textu, vpravo velký náhled upravovaného snímku)

Chování editoru

V následujícím textu je popsáno, jak editor prezentace funguje.

Při načtení stránky editoru se obsah prezentace převede na JavaScriptový objekt, který uchovává informace o jednotlivých snímcích. Součástí těchto dat je zdrojový text obsahu snímku a také jeho HTML podoba po konverzi. HTML kód každého snímku se pak vloží do panelu s malými náhledy. Malý náhled snímku je pomocí CSS pravidel zmenšen, jinak by byl obsah stejně velký jako v normálním zobrazení prezentace.

Po kliknutí na malý náhled se objeví v textovém poli pro úpravu snímku zdrojový text snímku a ve velkém náhledu vpravo se objeví kompletní snímek s inicializovanou knihovnou deck.js, tj. včetně funkční interakce.

Při změně zdrojového textu snímku se celý obsah automaticky posílá na server, kde se text pomocí knihovny Texy! převádí na HTML kód. Výsledný HTML kód snímku se následně vrací v odpovědi. Poté se aktualizují oba náhledy snímku, malý i velký. Aby se ale na server neposílala každá úprava snímku (např. po stisku každého písmene), a tak nevhodně nezatěžovala server i klientskou aplikaci, byla implementovaná čekací doba 1 sekundy. Pokud po poslední změně snímku uplyne tato doba, během které nebyla provedena žádná další úprava, pošle se požadavek na převod zdrojového textu na server.

Úprava knihovny Texy!

Následující odstavce popisují rozšíření jednoduchého značkovacího jazyka Texy!. Bylo totiž nutné vymyslet a implementovat novou syntaxi pro interaktivní odpovídání na kvizové otázky během prezentace a další novinky. Dále jsem se pokusil upravit syntaxi značkovacího jazyka Texy! pro lepší kompatibilitu s více rozšířeným a známým jazykem MarkDown.

MarkDown syntaxe

Jak už bylo vysvětleno v předchozích kapitolách, pro popis snímků byla použita knihovna Texy!, která implementuje vlastní jazyk stejného jména. Tento jazyk je ovšem široce používaný pouze v českých a slovenských zemích. Celosvětově ho zastiňuje mnohem více rozšířený značkovací jazyk MarkDown. Oba jazyky jsou si v lecčem podobné, avšak najdou se i velké rozdíly. Proto jsem se rozhodl knihovnu Texy! upravit a některé části přizpůsobit syntaxi jazyku MarkDown.

Jeden z nejvíce patrných rozdílů byl v syntaxi nadpisů. Porovnejte rozdíly mezi výpisy \ref{lst:nadpisy1}\ref{lst:nadpisy2}.

Výpis 1: Výpis
[caption=Ukázka nadpisů v~Texy!,label={lst:nadpisy1},captionpos=b]
### Nadpis 1. úrovně
## Nadpis 2. úrovně
# Nadpis 3. úrovně
nebo alternativně
Nadpis 1. úrovně
################
Nadpis 2. úrovně
****************
Nadpis 3. úrovně
================
Výpis 2: Výpis
[caption=Ukázka nadpisů v~Mark\-Down,label={lst:nadpisy2},captionpos=b]
# Nadpis 1. úrovně
## Nadpis 2. úrovně
### Nadpis 3. úrovně
nebo alternativně
Nadpis 1. úrovně
================
Nadpis 2. úrovně
----------------

Jak je vidět, logika syntaxí značek u varianty před nadpisem je u obou jazyků přesně opačná. Proto byla syntaxe upravena, aby byla ekvivalentní s jazykem MarkDown. Změna pak byla otestována pomocí jednotkových testů.

Protože sjednocení syntaxí nebylo prioritou tohoto projektu, nezaměřoval jsem se více na další zvýšení kompatibility.

Nová syntaxe

Dále bylo nutné rozšířit knihovnu Texy! a implementovat vlastní pravidla konverze textu do HTML. Rozšíření se týkalo možnosti uživatele odpovídat na otázky během prohlížení prezentace a dále vytvoření osnovy prezentace s odkazy na snímky.

Syntaxe odpovědí

Pro vytvoření kvizových otázek bylo potřeba vymyslet a implementovat syntaxi na vložení zaškrtávacího pole, které uživatel při prohlížení prezentace může zaškrtnout jako správnou odpověď na otázku položenou na snímku. Správných odpovědí může být více. Po delší úvaze bylo rozhodnuto, že na jednom snímku lze mít pouze jednu otázku. Nejenže by se více otázek na snímek nevešlo, ale zjednodušila se tak i složitost syntaxe, která by na tento případ musela brát ohled. Stejně tak odpadla potřeba manuálně vkládat potvrzovací tlačítko pro kontrolu zaškrtnutých odpovědí. Tlačítko se při překladu vkládá na konec snímku automaticky, pokud je na snímku použita syntaxe pro vložení zaškrtávacích políček. Ukázku syntaxe můžete vidět ve výpisu \ref{lst:odpovedi} a snímek po převodu do HTML na obrázku \ref{fig:odpovedi}.

Výpis 3: Výpis
[caption={Ukázka zdrojového textu snímku s~otázkou a~odpovědmi},label={lst:odpovedi},captionpos=b]
## Otázka č. 1
Co je cílem scopingu?
[+] získat požadavky od zákazníka
[-] vytvořit rozpočet a plán projektu

\label{fig:odpovedi}Ukázka snímku s otázkou a odpověďmi

Pro vyhodnocení správnosti zaškrtnutých odpovědí musí uživatel stisknout tlačítko pro kontrolu. Případné chybné odpovědi mají za následek přiřazení CSS třídy ke špatně zaškrtnutým políčkům.

Samotná zaškrtávací políčka nejsou zobrazena jako HTML vstupní pole <input> proto, aby se daly lépe vzhledově upravit pomocí CSS stylů.

Syntaxe doplňkových textů

Důležitou součástí požadovaného kvizového systému byla také možnost vkládat doplňkový text. Autor prezentace tak může uvést bližší informace k odpovědím na danou otázku nebo odkázat na jiný snímek prezentace či dokonce na jiný web.

Tento text se rozděluje na dva typy: pro správně a nesprávně zaškrtnuté odpovědi. Tento doplňkový text se dynamicky objeví až po kliknutí na potvrzovací tlačítko, přitom text pro správně zaškrtnuté odpovědi se zobrazí při zaškrtnutí pouze správných odpovědí, u textu pro špatné odpovědi přesně naopak.

Pro vložení takového bloku textu byla použita podobná syntaxe jako pro ostatní účelové bloky textu v syntaxi Texy! (např. blok kódu). Použití syntaxe pro oba doplňkové texty vidíte ve výpisu \ref{lst:texts}.

Výpis 1: Výpis
[caption={Syntaxe doplňkových textů},label={lst:texts},captionpos=b]
/--correct
Tento text se zobrazí při **správné** odpovědi.
\--
/--incorrect
Tento text se zobrazí při **špatné** odpovědi.
\--

Syntaxe pro vložení osnovy

V mnoha prezentacích se můžeme setkat s více tématy nebo podtématy, o kterých prezentace pojednává. Proto editor prezentace poskytuje možnost rozdělit prezentaci na logické celky. U každého snímku tak lze specifikovat až tři úrovně sekcí, do kterých snímek logicky patří. Toho pak bylo využito pro další vlastnost převodu zdrojového textu do HTML – generování osnovy (obsahu) prezentace s odkazy na snímky, které tyto sekce specifikují. Syntaxe je pak jednoduchá, stačí uvést {table of contents} . Při převodu je pak tato direktiva nahrazena HTML seznamem sekcí a případných podsekcí s odkazy vedoucími na dané snímky.

Rozšíření prezentační knihovny

Protože tento nástroj byl zaměřen na použití ve vzdělávacích institucích, bylo dobrou myšlenkou rozšířit možnosti prezentační knihovny o další pomocné funkce. Rozhodl jsem se proto implementovat funkci zvýraznění syntaxe bloků programovacích jazyků, která se určitě bude hodit prezentujícím vývojářům, a dále zobrazení matematických vzorců ve formátu LaTeX, které bude možné použít například v prezentacích z oboru matematiky.

Zvýraznění syntaxe programovacích jazyků

Pro zobrazení kódu používá knihovna Texy! blokovou syntaxi jakou můžete vidět ve výpisu \ref{lst:code}. Po převodu tohoto textu do HTML se uvedený kus kódu obalí do sebe vnořených sémantických HTML značek &lt;pre&gt;&lt;code&gt; . Toho je pak využito při zvýraznění syntaxe, jež je zajištěno pomocí knihovny highlight.js (citation not found: highlight), která automaticky tyto bloky kódu za použití detekce jazyka zvýrazní. Knihovna podporuje více než 50 jazyků.

Výpis 1: Výpis
[caption={Ukázka blokové syntaxe pro výpis kódu},label={lst:code},captionpos=b]
/--code
SELECT * FROM `presentations` where `id` = 1;
\--

Matematické vzorce

Další přidanou hodnotou do prohlížení prezentací bylo zavedení zobrazení matematických vzorců a rovnic. Není totiž nijak uživatelsky příjemné tyto vzorce vytvářet jako obrázky a vkládat je pak do prezentace. Pro implementaci této vlastnosti byla použita JavaScriptová knihovna MathJax (citation not found: mathjax), která automaticky vyhledává zdrojový text ve formátu LaTeX (citation not found: latex) ve specifické syntaxi a následně je vysází pomocí HTML, CSS a webových fontů. Není tedy potřeba žádných dalších technologií třetích stran, jako například Flash, a zároveň se nejedná o obrázky. Vzorce si tak zachovávají všechny vlastnosti okolního textu, jako jsou barva či velikost.

Podmínkou pro vyhledání a zobrazení vzorců je ohraničení zdrojového textu vzorců oddělovači. Ty jsou dvojího druhu, protože knihovna podporuje zobrazení jak blokových vzorců, tak tzv. inline vzorců, které mohou být součástí odstavce textu. Oddělovače pro inline vzorce jsou $()$ , pro blokové vzorce pak $$$$ . Ukázku použití této syntaxe spolu se vzorovým zdrojovým textem několika rovnic vidíte ve výpisu \ref{lst:rovnice}, výsledný snímek s vysázenými matematickými rovnicemi vidíte na obrázku \ref{fig:rovnice}.

Výpis 2: Výpis
[caption={Ukázka syntaxe matematických vzorců},label={lst:rovnice},captionpos=b]
## Rovnice
$$
\begin{aligned}
\dot{x} & = \sigma(y-x) \\
\dot{y} & = \rho x - y - xz \\
\dot{z} & = -\beta z~+ xy
\end{aligned}
$$

\label{fig:rovnice}Ukázka snímku s matematickými rovnicemi

Nasazení

V této kapitole jsou shrnuty požadavky na nasazení aplikace a dále je vylíčen průběh nasazení projektu na produkční server.

Požadavky

Pro chod systému je nutný spuštěný webový server, na kterém běží PHP. Dále je pak potřeba MySQL databáze. Komponenty a jejich verze, na kterých byl projekt vyvíjen, jsou uvedeny níže.

  • Apache 2.2

  • PHP 5.3

  • MySQL 5.5

Pro zaručení správného chodu aplikace je také dobré ověřit, zda-li server splňuje požadavky samotného Nette Frameworku. K tomu lze využít PHP skript jménem Requirements Checker, jenž je frameworkem poskytován. Více o skriptu, jeho instalaci a spuštění naleznete v dokumentaci Nette Frameworku (citation not found: checker).

Realizace nasazení

Pro nasazení na produkční prostředí jsem se nejdříve rozhodl využít cloudového systému PHP Fog. Pro malý počet aplikací a malý rozsah poskytoval své služby zdarma. V placených řešení bylo pak největší výhodou možnost škálování instancí aplikace či operační paměti nebo velké množství rozšíření, např. analytické nástroje či optimalizační nástroje pro databázi. Server uchovával aplikaci jako Git repositář a tak pro nahrání nové verze aplikace stačil příkaz git push .

V listopadu 2012 bylo ovšem oznámeno ukončení služby PHP Fog a postupné odpojování bezplatných aplikací v průběhu prosince 2012. Jako náhrada byla doporučena podobná služba AppFog (citation not found: appfog) od stejné společnosti. (citation not found: phpfogdiscont)

AppFog, podobně jako PHP Fog, je cloudová služba poskytující Platform as a Service (PaaS)\nomenclaturePaaSPlatform as a Service, tedy výpočetní platformu a k tomu funkční řešení operačního systému, webového serveru, databáze a dalších. Aplikaci tak stačí pouze nasadit a spustit. AppFog na rozdíl od PHP Fogu podporuje kromě jazyka PHP i další, např. Node, Ruby či Javu. Změněn byl i způsob nahrávání aplikace, z Git repositáře se přešlo na vlastní konzolový nástroj, který dále nabízí i komplexní správu nasazených aplikací.

Nevýhodou této služby je v současné době neexistující persistentní úložiště souborů, to znamená, že každá změna provedená na souborech na serveru, např. uložení obrázků nahraných uživateli aplikace, bude při nahrání nové verze aplikace nenávratně ztracena (databází se to ovšem netýká). Tento problém měl být vyřešen ve stejné době jako ukončení provozu PHP Fogu, avšak ani v době dokončování psaní této práce nebyla situace vyřešena. Pro vložení obrázků do prezentací si tak uživatelé prozatím musí vystačit s jinými službami pro sdílení obrázků. Samotný editor ale nabízí vložení souborů ze služby Dropbox pomocí prohlížeče Dropbox Chooser (citation not found: dropboxchooser).

Deployment

Projekt byl průběžně vyvíjen na lokálním serveru a při větším počtu změn byl aktualizován produkční server. Pro řešení závislostí použitých PHP knihoven jsem přidal balíčkovací systém Composer, který kromě závislostí obstará i stažení a aktualizaci těchto knihoven. Knihovny tak nejsou součástí projektu a při nasazení je potřeba je příkazem install do aplikace stáhnout a nainstalovat. Více se dočtete v dokumentaci Composeru (citation not found: composer).

Další významnou součástí aktualizace systému byla migrace databáze při její změně. K tomu byla použita knihovna Phinx, kterou jsem upravil, aby používala konfigurační soubor Nette Frameworku. Při změně schématu databáze je pak nutné příkazem vytvořit PHP soubor ve složce migrate , který obsahuje metodu pro provedení změny v databázi a také metodu pro navrácení do původního stavu. Při aktualizaci projektu je pak nutné provést příkaz migrate , který dosud neprovedené změny databáze provede. Více informací najdete v dokumentaci knihovny Phinx (citation not found: phinx).

Testování

Testování je důležitou součástí vývoje každého softwarového systému. Jedná se o takové zkoušení systému, které nalezne nejen chyby (tzv. bugy) v softwaru, ale ověřuje také, zda-li vyhovuje zadaným požadavkům. Před několika lety, často se s tím ale můžeme setkat i dnes, se testování provádělo ručně. Zvláště v jazyce PHP se často při každé změně ručně obnovuje stránka v prohlížeči a následně se kontrolují výstupy.

V současné době se software nejčastěji testuje pomocí automatických nástrojů. To znamená, že testy definované nějakým scénářem jsou spouštěny všechny najednou a výsledkem jsou zprávy, zda všechny testy úspěšně prošly. Pokud některé testy neprošly, snadno zjistíme příčinu. Při každé změně softwaru tak můžeme rychle zjistit, zda-li systém vyhovuje požadavkům a zda neobsahuje chyby. Protože máme možnost spouštět všechny testy, můžeme mít (větší) jistotu, že změna nerozbila jiné části systému, které na první pohled se změnou nesouvisí.

Test Driven Development

Test Driven Development (TDD)\nomenclatureTDDTest Driven Development (citation not found: tdd) neboli vývoj řízený testy je metodika vývoje softwaru, kde se test píše dříve než kód, který má daný test ověřit. Použití této metodiky má několik výhod – test je psán bez znalosti vnitřní implementace ověřovaného kódu a je tak pro programátora těžší být ovlivněn vlastní implementací. Vedlejším efektem je pak i lepší návrh aplikace. Protože v testech se snažíme psát co nejméně kódu, programátor se pak snaží testovaný kód mít co nejjednodušší pro nastavení a inicializaci, což prospívá i jednoduchosti samotné implementace.

Tento projekt je prvním, kdy jsem se snažil používat metodiku TDD. Ne vždy se to však povedlo, neboť jsem byl zvyklý na opačný postup. Nejvíce jsem jej využil při úpravě a implementaci nových syntaxí v knihovně Texy!, kdy jsem si pro požadované výstupy knihovny napsal test předem a poté dané změny syntaxe implementoval. Dále pak bylo TDD použito při refaktorování back-endu aplikace.

Metodika TDD se velmi dobře aplikuje a při vývoji mi pomáhala, avšak zvyklost byla často silnější. V dalších projektech se budu snažit ji používat důkladněji.

Jednotkové testy

Jednotkové nebo také unit testy jsou testy, které ověřují správnost jedné malé části softwaru, tzv. jednotky. Typicky jsou to metody nebo třídy. Jejich úkolem je zjistit správnost funkčnosti této jednotky nehledě na vliv ostatních jednotek, např. ostatních tříd či metod nebo úplně jiných systémů.

V tomto projektu byly unit testy psány hlavně při úpravě syntaxe knihovny Texy!. Bylo nutné, aby nové prvky syntaxe nebyly v konfliktu s již existujícími, což však bylo znemožněno neexistujícími testy v samotné knihovně Texy!. Testy tak sloužily jen na ověření výstupu nové či upravené syntaxe.

Protože jsou výstupy testů syntaxe často dlouhé a ve zdrojovém souboru by byly nepřehledné, byly jak vstupy tak očekávané výstupy jednotlivých testů přesunuty do textových souborů. Vstupní soubory se pak dávkově nahrávaly do testu a výstup se kontroloval oproti souborům s očekávanými výstupy.

Unit testy byly napsány s pomocí PHP frameworku pro jednotkové testování PHPUnit (citation not found: phpunit).

Integrační testy

Integrační testy ověřují komunikaci mezi více jednotkami, testovaný kód je oproti jednotkovým testům již závislý i na ostatních třídách, komponentách, systémech nebo dokonce platformě či hardwaru.

Tímto způsobem byla v projektu testovaná modelová vrstva aplikace, tedy entity, repositáře a fasády. Testované třídy používají funkční MySQL databázi, která obsahuje testovací data. Při každém jednotlivém testu se databáze smaže a vytvoří znovu podle SQL souboru obsahující definice tabulek a data ve výchozím stavu. Je tak vyřešena jakákoliv nekonzistence mezi jednotlivými testy a není potřeba po každém testu ručně navracet databázi do výchozího stavu. Stejně jako u jednotkových testů byl použit framework PHPUnit. Ukázky integračních testů naleznete ve výpisu \ref{lst:integrationtest} v příloze \ref{chap:ukazkykodu}.

Tabulka \ref{testtable} ukazuje počet napsaných a spuštěných testů, jejich úspěšnost a pokrytí kódu. Pokrytí ukazuje podíl kódu aplikace, jenž byl testy vykonán.

\label{testtable}Přehled o testech
Počet testů 57
Počet úspěšných testů 57
Pokrytí kódu 52 %

Selenium testy

Pro testování uživatelského rozhraní byl použit systém Selenium (citation not found: selenium). Jeho hlavním úkolem je automatizace webových prohlížečů, nejčastěji se ale používá právě jako testovací nástroj.

Selenium poskytuje rozhraní pro komunikaci s různými prohlížeči různých verzí. Testy se skládají ze scénářů, tedy předem definovaných kroků prohlížeče (např. kliknutí na odkaz nebo vyplnění formulářového pole) a díky komunikačnímu rozhraní lze také z prohlížeče získávat informace (např. zda-li se na stránce objevuje nějaké slovní spojení). Tyto scénáře můžou být interaktivně vytvořeny pomocí Selenium IDE (pouze pro prohlížeč Firefox) a pak je lze opakovaně spouštět. Další možností je použít Selenium Remote Control (RC), který dokáže prohlížeč spustit a vykonat scénáře definované v některém z podporovaných programovacích jazyků.

Ovladač pro Remote Control jazyk PHP podporuje a zmíněný testovací framework PHPUnit poskytuje rozšíření implementující klient-server protokol pro komunikaci s RC. Navíc také nabízí specializované metody pro testování. Ve výpisu \ref{lst:seleniumtest} v příloze \ref{chap:ukazkykodu} se můžete podívat, jak takový test vypadá.

Zátěžové testy

Zátěžové testy prověřují chování aplikace pod narůstajícím počtem požadavků. Je tak snadné zjistit, zda-li je aplikace dostatečně rychlá a zda-li ustojí větší počet aktivních uživatelů. Pro otestování tohoto projektu nasazeném na AppFog jsem se rozhodl využít webový nástroj Load Impact (citation not found: loadimpact), jenž zdarma poskytuje zátěžové testy s maximálně 50 souběžnými virtuálními uživateli.

Zdarma ale služba nenabízí výběr místa odkud požadavky přicházejí. To se pak podepsalo na delší odezvě serveru, neboť požadavky většinou nepřicházely z Evropy, kde se aplikační server nachází. Zvyšující se zátěž ale nepředstavovala pro aplikaci větší problém a i při plném vytížení, jenž LoadImpact poskytuje, byla doba načtení konstantní.

Pro testování byly vybrány dvě stránky, které představují pro aplikaci velkou režii a to jak na straně PHP tak i na straně databáze. Občas se vyskytly mírné fluktuace, které jsou nejspíš vinou bezplatného účtu služby AppFog, neboť u následujícího vyššího zatížení se tyto výkyvy neprojevily. Grafy výsledků obou testů najdete v příloze \ref{chap:loadtest}.

Zhodnocení a budoucí vývoj

Práce na tomto projektu byla velmi zajímavá. Vyzkoušel jsem si řadu nových technologií, zejména mě zaujal AngularJS, který určitě budu dále sledovat a předpokládám, že ho využiji i budoucnu. Kromě AngularJS jsem si poprvé vyzkoušel i migrace databází v PHP a i když to není tak automatické jako třeba v Ruby on Rails, pracuje se s knihovnou velmi dobře.

Výbornou zkušeností bylo také nasazení projektu na cloudové PaaS systémy. Tyto služby jsou nejen jednoduché na použití, ale poskytují široké možnosti správy a škálování aplikací. Platforma PHP ovšem není připravena na více instancí aplikace a je proto nutné s řešením počítat již při vývoji aplikace. Placená řešení cloudových systémů ovšem mnohanásobně převyšují výhody vlastního serveru nebo běžných webhostingových služeb.

S projektem jsem celkově spokojený, i když jsem zprvu čekal mnohem rychlejší vývoj, některé doplňkové funkce, tzv. nice-to-have, tak kvůli nedostatku času či kvůli řešení jiných problémů nebyly implementovány. Problémy nastaly u prezentační knihovny a vzhledu prezentace, které zpomalovaly vývoj. Dále by bylo dobré zapracovat na zlepšení uživatelské přívětivosti a mobilní verzi.

Při práci na projektu jsem ale zjistil, že se v době responzivních designů a dalších novinek v CSS3 začínám ztrácet a řešení vzhledu webů a User experience (UX)\nomenclatureUXUser experience nestíhám sledovat. Proto bych se v dalších projektech více zaměřil na vývoji back-endu aplikací a přenechal tyto problémy zkušenějším webovým designerům.

Jsem rád, že jsem použil Nette Framework, který dobře znám a tak jsem neměl tolik problémů při vývoji serverové části. Ze začátku jsem se ovšem rozhodoval, jestli si nevyzkoušet nějakou jinou technologii, například dnes populární Ruby on Rails nebo Node.js. Při výběru jsem bral v úvahu hlavně malé zkušenosti s těmito technologiemi a obával jsem se možných problémů a mnohem pomalejšího vývoje při jejich řešení. Na druhou stranu jsem se ochudil o možnost si technologie vyzkoušet a zjistit pro a proti. Při práci na tomto projektu jsem zjistil, že PHP má jednu nevýhodu, a to v nedokonalém ekosystému. Naproti tomu Ruby on Rails dokáže pár příkazy stáhnout, nainstalovat a nakonfigurovat potřebné knihovny, kterých je navíc velké množství.

This block failed to display. Double-click this text to correct any errors. Your changes are saved.

[Someone else is editing this]

You are editing this file