Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Spustili jsme Trop blog

16.22 - 17. prosince 2009 | Gryphoon

Už je tomu tak, každá správná sociální služba se má šířit všema kanálama a dnes přibyl další.

Dneska najdete Trop skoro všude:

Původně jsem chtěl blog nasadit na některý z existujících redakčních systémů. Výbíral jsem z Wordpressu, Oxite, AtomSite a nakonec nevybral ani jeden. :) Instalovat na server další databázový stroj (MySQL) jen kvůli blogu mi přišlo zbytečné – Wordpress padl. Oxite se zdá být zajímavým, protože na něm jsou postaveny prezentační weby Microsoftích konferencí a navíc je to napsaný v ASP.NET MVC (stejně jako Trop). Bohužel je to celé dost nepoužitelné a navíc chybí podpora pro správu uživatelů. Což je velký problém, kterým trpí i jinak zajímavě vypadající AtomSite.

Velké ostřílené distribuce jako SubText, BlogEngine.net nebo dasBlog se mi už zkoušet nechtělo a sáhl jsem po tom s čím dokážu dělat snadno a rychle. Ano, po stařičkém Gryphoonovi, který pohání i tento blog. Chtělo to jen pár drobných úprav a frontend, který byl jen a pouze na tomto blogu, už je nasaditelný i na jiné domény než rarouš.net. :) Možná ho o prázdninách dám nějak do kupky a vydám bastl hybrid Gryphoon 1.90. :)

Stay tuned.

Téměř nový rarouš.weblog

10.42 - 23. června 2008 | Moje práce

Poslední týden jsem trávil úpravami tohoto blogu. Měl jsem už nějaký nástřel grafiky už několik dní před tím, dokonce rozběhaný na úvodní straně blogu. :) Jenže abych to mohl posunout dál i do článků, musel jsem šáhnout do šablon blogu. Jenže prezentační vrstva, byla napsaná tak nepoužitelně a každá změna vyžadovala dost práce.

Měl jsem před sebou dvě možnosti. Nechat to být a počkat až napíšu nový systém, nebo upravit stávající. Jenže čekat sám na sebe, až něco napíšu, to bych se taky nemusel dočkat… ;) Nakonec jsem napsal zbrusu novou prezentační vrstvu nad starým systémem.

Rozhodl jsem se pokračovat v započatém stylu, který jsem zvolil pro svoji homepage, tedy návrhový vzor MVP pro prezentační část a Repository pro datovou. Využil a trochu rozšířil některé entity modelu o další vlastnosti a přidal některé nové. Pro výpis článků a komentářů na stránce jsem napsal serverové prvky založené na Generickém repeateru. Pak jsem se dostal k formuláři pro přidávání komentářů. Aktuální WebForms implementace se mi moc nelíbila a tak jsem se rozhodl oprášit NForms a povolat je do služby.

Musel jsem odladit několik bugů, protože tohle bylo poprvé, co jsem je použil. :) Ale nakonec se z toho vyklubal celkem použitelný a elegantní kus softwaru. Proč elegantní? Líbí se mi definování validačních pravidel (sice zatím pouze serverových), znovupoužitelnost kódu apod.

NForms v akci

Když jsem vymýšlel, jak vlastně budu nově komentáře zpracovávat, rozhodl jsem se pro handler, který bude obsluhovat požadavky na akce a zavolá správnou třídu, která má požadavek zpracovat – v tomto případě ukládač komentářů. (Tento model jsem zvolil protože, každá třída by měla dělat pouze jednu věc, proto komentáře nezpracovává ta samá, co prezentuje články.) Jenže teď jsem stál před problémem, že budu muset definovat ten samý formulář na dvou místech. Naštěstí u NForms to není třeba.

Podědil jsem novou třídu CommentForm z formuláře NForms. V ní jsem nadefinoval, jaká políčka a s jakými pravidly se mají vytvořit. Kód vypadá nějak tak:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using Rarous.NForms;
using Rarous.NForms.Validation;

namespace Rarous.Net.Components {
  public class CommentsForm : Form {
    public const string ArticleUrl = "comment_article_url";
    public const string ArticleId = "comment_article_id";
    public const string Validity = "comment_validity";
    public const string Text = "comment_text";
    public const string UserName = "comment_user_name";
    public const string UserEmail = "comment_user_email";
    public const string UserWeb = "comment_user_web";
    public const string UserAnswer = "comment_user_answer";
    public const string Submit = "comment_submit";

    public CommentsForm()
      :this(null) {
    }

    public CommentsForm(NameValueCollection data)
      : this(data, null) {
    }

    public CommentsForm(NameValueCollection data, List<string> messages)
      : base(data, messages) {
      CreateForm();
      BindData();
    }

    private void CreateForm() {
      AddHidden(ArticleUrl);
      AddHidden(ArticleId);
      AddHidden(Validity);

      AddTextArea(Text, "Text komentáře:", 10, 55).
        Required("Text příspěvku je povinný.");
      AddText(UserName, "Jméno:").
        Required("Jméno je povinné.");
      AddText(UserEmail, "E-mail:").
        SetEmptyValue("@");
      AddText(UserWeb, "Web:").
        SetEmptyValue("http://");

      AddText(UserAnswer, "Odpověď je pivo:").
        AddRule("Zadejte pivo.", s => String.Compare("pivo", s, true) == 0);

      AddSubmit(Submit, "Přidat komentář");
    }
  }
}

Tento formulář pak použivám ve View i handleru. V handleru se vytváří s daty poslanými přes POST, která se pak validují a dále zpracovávají. Líbí se mi, že data se předávají jako NameValueCollection, díky tomu se dá bez problému načítat z Request.Forms, Request.QueryString, nebo z kolekce Cookies.Values. Těmi můžu data předvyplňovat, nebo je nechat validovat a tak. V budoucnu by mohlo přibýt i inteligentní vytváření objektů…

Další featury

  1. U komentářů jsem oprášil Gravatary, které jsem tu už kdysi míval. Použil jsem implementaci z dotnetKicks, kde se používá lokální cachování.
  2. Bezpečnostní otázka se vyplňuje JavaScriptem, takže už vás nebude otravovat.
  3. Po letech jsem přidal stránkování v článcích. Jak na hlavní stránce blogu, tak v rubrikách.
  4. Zvýrazňovač syntaxe teď funguje jen napůl, protože už přestal stačit mým potřebám. Čekám na uvolnění zvýrazňavoče z Codeplexu, který by měl být o dost lepší.

Jsou to takové drobnosti, ale mám z nich radost, protože jsem je dlouho dobu odbýval.

Závěrem

Ještě mi zbývá pár věcí dopsat, aktualizovat odkazy v článcích na nové URL, ale už jsou to spíš drobnosti (doufám). Ještě bych chtěl závěrem poděkovat Davidovi a Honzovi, protože u nich jsem se dost inspiroval. Taky děkuju Exíkovi za hodnotné připomínky, Jerrymu za hosting a naší zahradě za příjemné pracovní prostředí atd.

Gryphoon 1.82 je venku

17.04 - 2. června 2008 | Moje práce

Kolega Ondra uvolnil systém Gryphoon, který pohání tento a mnoho dalších webů včetně nějakých vylepšení. Najdete ho ke stažení včetně návodu k nasazení na stránkách projektu.

Je to záležitost na kterou jsem nesahal takřka 3 roky a taky je to systém, na kterým jsem se učil. Spousta věcí je pojmenována česky, žádný komentáře v kódu a tak. Fakt to není dobrý ke studování, ale funguje to ;) Vím o spoustě míst, které by se daly snadno rozšířit, vylepšit, doplnit. Ani by to nezabralo moc času, ale z pricipu se mi nechce.

Měl jsem pak napsanou velkou část verze dvě, ale nikdy jsem ji nedotáhl do konce. Nelíbilo se mi, že jsem použil typované DataSety a nikdy jsem pro něj nevytvořil administraci. Dvojka je tedy mrtvá. V plánu je trojka postavená na 3.5 frameworku, ASP.NET MVC a ActiveRecord. Ale u tý jsem ve fázi pokusů a designování architektury.

Enjoy

Redakční systém na ASP.NET MVC

18.56 - 23. prosince 2007 | Webdesign

Rozhodl jsem se, že, jako praktickou ukázku použití TDD a ASP.NET MVC (dále jen MVC), budu psát seriálek, výsledkem něhož bude základ třetí verze redakčního systému Gryphoon.

Upozornění: Je možné, že některým věcem nebudete v průběhu čtení rozumět. Dopuručuji si přečíst související články, na jejichž základě tento seriál staví.

Už z této podstaty vyplívá, že půjde o OSS. Projekt je hostován na Codeplexu pod MS-PL. Dalším důležitým znakem je použití Texy.net jako základního kamene systému, spojení s databází bude zajišťovat Castle ActiveRecord, pro testování použiji xUnit.net a Rhino Mocks. Tím jsou nastíněny základní prvky architektury a můžeme se pomalu dát do práce.

Struktura projektu

Prozatím to vypadá na tři projekty v řešení:

  1. Rarous.Gryphoon – Knihovna, jádro systému, které bude obsahovat objekty doménového modelu, konfiguraci a další potřebné komponenty.
  2. Rarous.Grypho­on.Spec – Knihovna s jednotkovými testy. xUnit.net místo termínu test používá fakt, proto bude brát tento projekt jako specifikaci zbylých částí.
  3. Rarous.Grypho­on.Web – Webová aplikace. Projekt bude obsahovat webovou část tj. Controllery a View (řadiče a pohledy) a Helpery (pomocníky).

První řádky specifikace

Naší jedinou specifikací bude projekt Rarous.Grypho­on.Spec. Tím co je v něm dáno, by se měly řídit oba zbylé projekty. Dobrým zvykem v TDD je navrhovat systém od shora dolů. První věc, se kterou přijdete do styku, je URL. Zatím nebudu výchozí schéma URL měnit, proto ani nebudu psát testy na Routování (zatím). Defaultní schéma URL by mělo být už milionkrát otestované v rámci MVC projektu.

Takže budeme pokračovat dál a to k řadiči článku (ArticleController). Ten by měl být zodpovědný za vytváření článků nových, jejich následnou editaci, zobrazování a v poslední řadě i mazání.

V prvním CTP, zatím nejsou předdefinované Mock Objekty pro controllery, proto použijeme Test subclass pattern, pro ověření činnosti controlleru. Controller bude mít následující rozhranní:

Diagram IArticleController

A třída pro testování vypadá následovně:

public class TestArticleController : ArticleController {
  public string ActualViewName { get; set; }
  public string RedirectViewName { get; set; }
  public string ActualMasterName { get; set; }
  public object ActualViewData { get; set; }

  protected override void RenderView(string viewName, string masterName,
                                     object viewData) {
    ActualViewName = viewName;
    ActualMasterName = masterName;
    ActualViewData = viewData;
  }

  protected override void RedirectToAction(object values) {
    RedirectViewName = values.ToDictionary()["Action"];
  }
}

Teď můžeme napsat první test, který ověří, že pokud přijdeme na adresu /article/ otevře se nám editor nového článku. Pozn. Využívám výchozího schématu routeru [controller]/[action]/[id] -Pokud není action definovaná vybere se Index. V budoucnu ho změním na lepší, ale pro začátek stačí.

[Fact]
public void ArticleController_DefaultActionShouldShowEditor() {
  TestArticleController controller = new TestArticleController();

  controller.Index();

  Assert.Equal("Editor", controller.ActualViewName);
}

Spustíme test – neprojde. Aby test prošel, musíme doimplementovat metodu ArticleController.Index.

[ControllerAction]
public void Index() {
  RenderView("Editor");
}

Teď už by měl test projít. Jenže aby to fungovalo i na webu, musíme ještě dopsat View /Views/Article/Editor.aspx… Do příště za domácí úkol.

Závěrem

Aktuální stav je na codeplexu ke stažení, ale zdaleka není funkční. :) Průběžně ho budu s dalšími díly doplňovat. Příště tedy uděláme ukládání nových příspěvků a editaci. Když se pozorně podíváte na zdrojáky, zjistíte, že tak trochu cheatuju :)

Jo abych nezapoměl, pokud jste sem přišli přes RSS a ještě jste si nezměnili adresu feedu, učiňte tak zavčasu. Děkuji

Související

Tagy: ,