Merb 0.9

Posted by Jarosław Zabiełło Wed, 13 Feb 2008 00:10:00 GMT

W nowej wersji Merba wprowadzono sporo zmian. Generatory kodu zostały wyniesione do skryptu merb-gen. Instalacja projektu też jest wykonywana przez merb-gen nazwa projektu. Ta wersja Merba ma już ustabilizowane API. Większej rewolucji do wersji 1.0 się nie przewiduje. Merb domyślnie działa z wieloma adapterami: mongrel, emongrel, thin, fastcgi czy webrick. Najciekawszy jest oczywiście thin o czym postaram się wkrótce coś napisać.

W momencie pisania tekstu gemy Merba 0.9 nie były dostępne w RubyForge. Trzeba je ściągnąć ze źródeł, zbudować i zainstalować. Operacja jest prosta. Jedynym probleme jest konieczność użycia innego systemu wersjonowania kodu. Kod Merba przeniesiono z Subversion do Git’a. Na stronie Merba jest stara informacja że źródła są w SVN. Strona Traca zawiera już bardziej aktualne informacje. Zakładając, że mamy zainstalowany klient git (dla OSX i MacPorts: sudo port install git-core) można pobrać źródła

git clone git://github.com/wycats/merb-more.git

Potem należy wejść do środka wykonać komendę rake package; rake install -l pkg/* Dla wybranych folderów należy wejść do środka i powtórzyć operację. Starsze wersje gemów wyczyści komenda sudo gem cleanup.

Projekt tworzy się za pomocą skryptu merb-gen nazwa_projektu. Zwraca uwagę estetyka i zwięzłość generowanych folderów. Domyślnie nie ma app/models bo Merb działa niezależnie od bazy czy ORM’a. Aby uaktywnić któryś z ORM’ów (do wyboru: Active Record, DataMapper lub Sequel) należy odkomentować stosowną linijkę w pliku config/init.rb. Np. dla Sequela będzie to use_orm :sequel. Domyślnie ustawiny jest RSpec jako system testowania więc każdy nowo wygenerowany model (merb-gen model Anything) będzie od razu miał budowane pliki rspec’a zamiast starego unit testa.

Uwaga, pierwsze uruchomienie modelu może nic nie dać. Skrypt wykona się bez komunikatu o błędzie czy stworzenia czegokolwiek. Tak naprawdę jednak powstanie przykładowy plik z konfiguracją bazy config/database.sample.yml Należy zmienić mu nazwę na database.yml i wpisać swoje ustawienia.

Uwaga 2: Instalacja Hamla jest też trochę inna. Trzeba używać gem merb-haml, a nie haml. Jednakże gem memcache należy umieścić poza blokiem. W pliku config/init.rb wygląda to mniej więcej tak:

# ... początek pliku config/init.rb
Merb::BootLoader.after_app_loads do
  dependencies 'merb-haml','merb_helpers'
  dependency 'RedCloth'  
end

dependency 'memcache'
CACHE = MemCache.new 'localhost:11211',

Merb rozwija się bardzo szybko dzięki pełnoetatowej pracy zatrudnionych programistów. Czy to początek końca jedynego słusznego frameworku w Ruby jakim był dotąd Rails? Czas pokaże.

Dla tych, co jeszcze nie wiedzą: Merb jest najpoważniejszą konkurencją dla Rails. Skopiowano tam wiele dobrych założeń RoR (ba, nawet zapożyczono część kodu źródłowego), jednakże framework ten jest tworzony w inny sposób i przez innych ludzi. Inny w tym wypadku znaczy – lepszy. Ezra Zygmuntowicz (twórca Merba) prezentuje solidne, inżynierskie podejście do tematu. Odrzucił lamerską filozofię odkładania optymalizacji kodu na wieczne “potem”. Merb jest od początku tworzony z założeniem maksymalnej wydajności i prostoty. Merb jest także wielowątkowy i system pluginów oparł na gemach (ułatwiając tym samym sposób ich zarządzania i aktualizacji). Zapewnia też łatwe tworzenie komponentów (w ramach tzw. Parts) i umożliwia wielokrotne składanie w całość renderowanych fragmentów kodu (RoR sypie wyjątkiem, jeśli jakieś fragment kodu zechce dodatkowo renderować odpowiedź). Ogólnie rzecz biorąc, Merb posiada lepszą architekturę niż RoR i Ezra udowodnił DHH, że jest możliwe napisanie lepszych, wielowątkowych Rails. (vide prezentacja Ezry Dispatching Rails vs Merb)

Updates:

Pojawiły już się tutoriale do Merba! Zobacz też ten zbiór artykułów i zbierane na bieżąco FAQ do Merba.

Dla tych co chcą pomóc Merbowi:

Już są gemy 0.9 do Merba:
sudo gem install --source http://merbivore.com merb

Należy pamiętać że 0.9 to wersja developerska, pre release dla wersji 1.0 (która mam nadzieję niebawem będzie wydana).

Pojawiła się pierwsza książka n/t Merba: Meet Merb. Your first sidekick. Jest dostępna online w formie pliku PDF cenie 9$. Jest to wersja Draft, czyli książka jest w trakcie tworzenia i co ważne, opisuje najnowszą wersję Merba 0.9!

W związku z tym że na stronie Merba udostępniona dokumentacja API jest lekko nieświeża, udostępniłem najnowszą dokumentację RDoc do merb-core. Jest automatycznie regenerowana co godzinę z repozytoriów Gita: http://blog.zabiello.com/merb-core/

29 comments

Comments

  1. Avatar Ris said about 9 hours later:

    Nie rozumiem do końca dlaczego brniesz w tak młode, kruche projekty nie lepiej korzystać ze sprawdzonych rozwiązań takich jak Java?

  2. Avatar Jarosław Zabiełło said about 10 hours later:

    @Ris: Po pierwsze, z tych samych powodów dla których nie brnę w “sprawdzone rozwiązania” takie jak PHP, Perl, Visual Basic czy .NET. Tip: bo nie jestem masochistą. Miałem okazję pracy z .NET i raczej więcej nie chcę. Projekt pisany przez kilku ludzi w .NET przez 6 miesięcy zaimplementowałem w Pythonie w tydzień. Wyszło dużo szybciej napisać to od nowa w języku very highlevel niż wiecznie naprawiać ciągle pojawiające się, trudne do naprawy, błędy.

    Co zaś do samej Javy, to przecież w JRuby mam dostęp do wszystkich bibliotek Javy bez niepotrzebnego narzutu jej kulawej składni, tylko że prościej i przyjemniej.

  3. Avatar Damian said about 12 hours later:

    Mają tempo dopiero co była wersja 0.5. Ten thin też wygląda ciekawie. Jak tak dalej pójdzie dam sobie spokój z ror! Chętnie bym przeczytał trochę więcej o tym może dać sobie spokój z kolejną książką o ror a skupić się na Merb?

  4. Avatar Tomash said about 12 hours later:

    Ostatni akapit pełen mocnych i odważnych słów. Bardzo mocnych i bardzo odważnych jak na opisywanie projektu traktowanego raczej jako “ciekawostka przyrodnicza”.

    Czekam na pierwsze sajty stworzone w Merbie, z podaniem czasu ich napisania.

  5. Avatar S!N said about 13 hours later:

    Jak dla mnie super wiadomość – Merb1 już tuż tuż :D Uzbrajam się w cierpliwość i czekam na RubyForge. Tymczasem mam kilka pytań: Jak wygląda migracja projektu z 0.5 do 0.9 – jest całkowicie kompatybilny wstecz, czy stary kod lub struktura wymaga zmian? Jaka jest ostatecznie różnica między wersjami -core i -more?

    @Tomash: Z tego co mi widomo to np. bezbiura.pl. Z własnego doświadczenia wiem, że pisanie projektów w rozwijającym się frameworku jakim niewątpliwie jest Merb nie jest tak szybkie jak np. w ROR, który posiada bogatą dokumentację, wiki, liczne tutoriale, casty, literaturę, itp. Merb 1.0 ma być przełomem w tej kwestii.

    @Ris: Prawdopodobnie też z tego samego powodu z jakiego kiedyś ludzie zajmujący się Javą brneli w projekty z których teraz korzystasz :) A brnięcie z takim językiem jak Ruby to dla programisty sama przyjemność – najlepiej przekonać się samemu.

    Osobiście uważam, że Merb to przyszły killer app Rubyego. Teraz czekam tylko na “Merb. Od podstaw” z mojej ulubionej księgarni ;)

  6. Avatar Jarosław Zabiełło said about 14 hours later:

    @Damian: ma sens uczyć się RoR bo większość te wiedzy się nie zmarnuje przy ewentualnym przejściu na Merba. Merb sporo dobrych pomysłów skopiował z RoR.

    @S!N: Na IRCu radzili aby lepiej od nowa wygenerować projekt w Merb 0.9 niż poprawiać Merb 0.5. Zmian jest dużo. Ale na szczęście sam kod ORM’a, czy szablonów praktycznie nie trzeba zmieniać.

  7. Avatar Ris said about 16 hours later:

    @Jarosław Zabiełło To skoro ta składnia ruby jest taka wspaniała to czemu nie używać sprawdzonej javy pisząc w jruby?

  8. Avatar Jarosław Zabiełło said about 17 hours later:

    @Ris: Javy czyli czego konkretnie? Przecież Java to język, więc napisałeś bez sensu. A jeśli chodzi ci o jakieś biblioteki, to używaj jeśli ich jakoś potrzebujesz. Na pewno to trochę komplikuje kod. No i wyjątki z ewentualnych błędów są mętne i skomplikowane z Javy. Z Rubiego są czytelniejsze. Poza tym JRuby 1.1RC1 jeszcze nie jest wersją stabilną i trwają prace nad nim.

  9. Avatar Uzytkownik said about 18 hours later:

    > Potem należy wejść do środka wykonać komendę > rake package; rake install -l pkg/*

    Nie lepiej rake gem; gem install plik.gem

    > Przecież Java to język, więc napisałeś bez sensu.

    Java to język i platforma (a właściwie to jest język Java i platforma o nazwie Java).

    http://en.wikipedia.org/wiki/Java_%28Sun%29

  10. Avatar Ris said about 23 hours later:

    @Jarosław Zabiełło Napisałeś, że nie w Javie bo wolisz język Ruby. To ja pytam czemu nie pisać w JRuby, co nam daje dostęp do świata Javy, nie języka tylko do API, itp. itd.

  11. Avatar Jarosław Zabiełło said 2 days later:

    @Ris: JRuby chyba nie jest jeszcze stabilny (coś czytałem o jakiś wyciekach pamięci dla RoR), nie wszystkie biblioteki standardowe są też przeniesione. Jak już pisałem wyżej, JRuby sypie koszmarnie nieczytelnymi (javowymi) wyjątkami podcza błędu w kodzie. Wolę wyjątki w Ruby, śą czytelniejsze. Poza tym Ruby jest lżejszy do developingu, graficzny debugger do Rails w Netbeans 6 działa też tylko z CRuby a nie JRuby.

    Poza tym (jak na razie) niespecjalnie potrzebuję świata Javy tak, jak nie potrzebuję świata .NET. Jak będę potrzebował to użyję JRuby, IronPythona, IronRuby (czy co tam będzie wygodniejsze). Na razie ani mi się śni zakopywać w złożonych, bizantyjsko rozbudowanych API do Javy.

    (BTW, myślę, że przyszłość Rubiego należy raczej do Rubiniusa niż JRuby czy CRuby).

  12. Avatar Jarosław Zabiełło said 2 days later:

    @Uzytkownik:

    > Nie lepiej rake gem; gem install plik.gem

    A co to jest “plik.gem”? Nie. Bo jest kilka różnych gemów i trzema było je zbudować niezależnie. Ale to już trochę nieaktualne, bo można od niedawna użyć konstrukcji
    sudo gem install --source http://merbivore.com merb
  13. Avatar Jiima said 4 days later:

    @JZ Witam po latach :)

    Generalnie od tamtego czasu, kiedy się wykłócaliśmy na JUG-u sporo się zmieniło. Trochę tęsknię w Javie za dynamicznym typowaniem, ale jak coś, to mam Groovy i JRuby. Ewentualnie Jythona, który ostatnio też się ostro rozwija. Sporo się od czasu naszych ścięć bawiłem Ruby, napisałem parę rzeczy w Railsach, ostatnio spodobał mi się Merb – niestety za dużo kombinacji by odpalić go pod windozą, a niestety głównie jej używam z różnych względów.

    Co do JRuby, muszę ci wytknąć kilka nieścisłości. Owszem, 1.1 to nadal wersja nie – release, ale w wypadku codehausa RC to niemal to samo (a mamy RC2). Jednak 1.0 wyszło już prawie rok temu.

    Debugger – czemu niby nie działa pod NB? Nie działa fastdebug (na bibliotece ruby-debug) gdyż opiera się on na natywnych roszerzeniach. Założę się, że za jakiś czas doczekamy się gema dla JRuby. Zwykły (“slow”) debug działa całkiem nieźle. Poza tym podobno w Rails debugger jest zbędny (nie zgodzę się, niezbyt często go stosuję, ale nie nazwałbym go zbędnym).

    Co do używania javowych frameworków z JRuby (domyślam się że chodzi o Strutsy i inne takie), co ktoś inny rzucił, to owszem, masochizm jest przydatny. Raz, że nie są one przystosowane do wykorzystywania innych języków, a dwa, same w sobie są cokolwiek debilne. Za to np. Spring wspiera języki skryptowe i to naprawdę nieźle (vide Grails – klon Rails w Groovy, który tak naprawdę jest nadbudową na Springa).

    Co do czytelności wyjątków, czy używania Javy i .NETu, nie dyskutujmy dalej o tym, bez względu na to co uważasz, jest to dyskusja o przewadze świąt bożego narodzenia nad wielkanocą. W skrócie nie ma sensu się nad tym zastanawiać.

  14. Avatar Jarosław Zabiełło said 4 days later:

    @Jiima: Wiem dobrze że wydano JRuby 1.0, ale to wersja mało użyteczna (wolna i nieoptymalizowana). Dopiero w wersji 1.1 zaczęto optymalizować i porządkować kod tak, że już teraz JRuby 1.1RC w niektórych testach deklasuje nawet Ruby 1.9.

    Co do użycia JRuby w kontekście Javy to miałem na myśli Rails i Merba używających bibliotek Javy, a nie żadnego Struts, czy Springa. Zaś co do Grails to JRuby jest dużo szybszy od Groovy.

  15. Avatar Tomasz Czubiński said 7 days later:

    Świetnie, że coraz więcej ludzi zaczyna się interesować Merb, niezły kawałek wykonanej pracy. Ostatnio trochę powstało mikro frameworków. Każdy próbuje odkryć inne podejscie do tematu. Najbardziej obiecujący jest oczywiscie Merb. Dobrze widzieć polskie wzmianki na ten temat.

    Pare dni temu trafilem na ciekawostkę http://m.onkey.org/2008/2/16/single-file-rails-application

    Zastanawiające co nie ? Warto przeczytać komentarze.

  16. Avatar Jarosław Zabiełło said 8 days later:

    Tomasz: zobacz jaki projekt powstaje w Merbie za pomocą komendy

    merb-gen myapp --flat

    lub

    merb-gen myapp --very-flat
    :)
  17. Avatar Tomasz Czubiński said 9 days later:

    Jarek, tak wiem :)

    Osobiście uważam MERB za inzyniersko genialny projekt. A z wersji na wersje jest coraz ciekawiej. 0.9 juz pokazuje swoje rogi :)

    Dotad korzystalem z RAILS, ale powoli wszystkie swoje projekty developersko przepisuje na MERB. Osobiscie nic nie mam do RAILS, ale MERB daje o niebo wieksze pole dzialania.

    Moj poprzedni post powinienem nieco rozwinac. W swiecie RAILS jak juz wiemy troche sie ostatnio dzieje, mam na mysli glownie niezadowolenie z obranych kierunkow oraz postawy. Przykladem jest wspomniana “ciekawostka”, ktora wskazuje na dokladnie to samo, programista, ktory ma tez inne wymagania co do RAILS. Pokazal, ze tez mozna cos innego z nich wykrzesac. Ale czy to do czegos doprowadzi? Chyba nieco za pozno.

    Pozdrawiam

  18. Avatar Jiima said 12 days later:

    @TC
    Nie wiem czemu “za późno”. Rails ma za sobą kasę, Merb zapał. Jedno i drugie jest w stanie zrobić wiele, ale dopóki twórcy narzędzi i oficyny wydawnicze nie przestaną promować Rails, raczej upadek im nie grozi.

    @JZ
    Wiem, że ty miałeś na myśli używanie bibliotek Ruby na JVM, ale pytający raczej mieli chyba co innego na myśli. Co do Groovy, to pytanie, czy mówimy o AOT czy o interpretowanym? Rzeczywiście, interpreter Groovy najszybszy nie jest…

    Co do przyszłości Ruby, myślę że rzeczywiście leży ona w Rubiniusie, ale nie oznacza to, że ten projekt “zeżre” inne implementacje. Raczej pozwoli je ulepszyć. Bólem Ruby, który najbardziej jest widoczny przy tworzeniu interpreterów dla innych architektur (JVM, CLI, Parrot) jest spora ilość rozszerzeń natywnych, porównywalna z ilością dla PHP. Nic dziwnego, Ruby 1.8 to Tuptuś 1 – Żółw Przestrzeni i każdy kawałek C poprawiał wydajność. Niestety, aby sensownie przenosić bibliotekę standardową, trzeba się z niej pozbyć natywnych rozszerzeń i dać alternatywę tym którzy tworzą własne biblioteki. To właśnie robi Rubinius.

    Najwięcej światełek na przyszłość jednak daje zarówno Rubiemu jak i Pythonowi zainteresowanie dużych firm. Rubym zainteresował się Sun i Borland, a Pythonem Microsoft. A to jest niezbędne by te języki przestały być zabawkami dla fanów. Niestety, to smutna prawda – ja na przykład jestem wielkim fanem Smalltalka (Seaside to jeden z lepszych frameworków jakie widziałem), ale co z tego – poza paroma prywatnymi projektami raczej nic w nim nie napiszę, bo nie ma z tego pieniędzy…

  19. Avatar Jarosław Zabiełło said 12 days later:

    @Jiima: zapomniałeś wspomieć o Google. Oni mocno używają Pythona. Zatrudnili nawet jego twórcę, Guido van Rossuma. Smalltalk chyba nie wstrzelił się w swoje czasy i już się nie podniesie.

  20. Avatar Jiima said 12 days later:

    @JZ
    Zapomniałem o Google, fakt. Ale z Google jest ten problem, że jest tam spora frakcja wierząca w Javascript 2.0 i jeśli w końcu ten język powstanie, dni Pythona mogą być policzone. Chyba że wiązania XPCOM dla Pythona + safe mode (by mieć python scripting poza Chrome) szybciej staną się popularne – wtedy to dni Javascipt mogą być policzone. Hmm. Ajax w pythonie? Byłoby cudownie :) O IE nie mówię, na upartego już da się w nim pisać aplikacje Ajaxowe w pythonie. Poza tym to w złym guście mówić o IE :P. To tak jak z muszlą klozetową, wszyscy jej używają, ale jakoś nie jest to temat do rozmów…

    Co do SmallTalka, nie grzebałbym go tak szybko. Jak sam zauważyłeś, Ruby i Python powstały mniej więcej wtedy co Java (i oficjalna, pełna specyfikacja C+). Tymczasem C+ powoli przemija (długo jeszcze będzie żył w embedded development), Java ma swoje wzloty, upadki i nowe wzloty (ostatnio odżywa zainteresowanie Swingiem i desktopową Javą na których wszyscy już dawno postawili krzyżyk). Python miał swoje piętnaście minut wiele lat po powstaniu, teraz zainteresowanie spadło, ale IronPython może znów nakręcić spiralę. Ruby stało się znane dopiero po Rails (a pamiętam jak pisałem pierwsze skrypty w tym języku jakieś 5 – 6 lat temu). Smalltalk ma olbrzymi potencjał, a rubystom jest łatwiej się na niego przesiadać niż die-hard fanom C++.

    Ostatnie pytanie – na jakiej podstawie twierdzisz że Grailsy są wolniejsze od RoR? Z mojej praktyki wynika coś odwrotnego, a na sieci opinie są podzielone i co więcej zwykle dotyczą mocno wczesnych implementacji Groovy i Grails. Z chęcią wymieniłbym opinie, bo mam pewne plany komercyjne odnośnie jednego lub drugiego…

    BTW, widziałeś może wspomniane Seaside? Spodobałoby ci się (no, może poza koniecznością pisania w Smalltalku). Pod niektórymi względami przypomina Zope (np. tryb developerski i tworzenie kodu bezpośrednio w przeglądarce)...

  21. Avatar Jarosław Zabiełło said 12 days later:

    Chodziło mi o Grooviego vs JRuby a nie GRails. Poza tym nie jest tajemnicą, że Rails są mało zoptymalizowane. Już prędzej bym zobaczył jakieś porównanie Grails z Merbem.

    Seaside oglądałem. Nie podoba mi się, bo przypomina anti-pattern (spaghetti code) w środku – ma wymieszaną warstwę kontrolera z warstwą widoku. Do Zope to ma się nijak, bo Zope nie używa kontynacji, jest cały obiektowy, ma bazę obiektową, rozdzieloną warstwę prezentacji od kontrolera i ma wbudowane undo do prawie wszystkiego.

  22. Avatar Jiima said 12 days later:

    Spaghetti code? W Smalltalku? Chyba inaczej rozumiemy to pojęcie. Poza tym co to znaczy “cały obiektowy”, nie wyobrażam sobie bardziej obiektowego języka niż Smalltalk. Wymieszanie kontrolera i widoku też da się naprawić. A co do kontynuacji, są one właśnie siłą tego rozwiązania. Problem w tym, że w niewielu językach da się je zrobić bez stawiania wszystkiego na głowie (głównie oprócz ST w Ruby i Lua).

    Co do Groovy vs JRuby, podrzuć mi proszę namiary na benchmarki, jak już mówiłem, nie chcę dyskutować o wyższości jednych świąt nad drugimi, tylko szukam konkretnych danych, więc proszę o pomoc . Grails z Merbem póki co nie da się niestety porównać, głównie dlatego że chwilowo parser ruby inline jest nie przenośny…

  23. Avatar Ris said 12 days later:

    @Jiima Google to wspiera różne języki, np. w GWT, Android piszę się w javie.

  24. Avatar Jarosław Zabiełło said 12 days later:

    Jakim znowu Smalltalku? Nie w Smalltalku ale we framdeworku Seaside. A kontynuacje nie są wcale takie idealne choć krytyka może dotyczy bardziej implementacji niż samej idei. Generują paskudne, nieczytelne URI i pożerają więcej zasobów.

  25. Avatar Tomasz Czubiński said 12 days later:

    @Jiima

    Rails trzymają się dobrze i pociąg nie zatrzyma się na żadnej stacji ;) Przekładając na fizykę i nie rozdrabniając zbytnio tematu, dosłownie mówiąc Rails mają niezły bagaż, i im szybciej coś pędzi o wielkiej wadze to tym trudniej tym kierować ;)

    Natomiast twórcy MERB mają fantastyczne podejście z merb-core i merb-more. Myślę, że to dopiero początek. Dosłownie mówiąc to jest sztuka jak ciężar wyważyć i rozłożyć na mniejsze. Efekt murowany, łatwiej tym kierować. Developerzy już od jakiegoś czasu zacierają ręce i coraz szerzej pokazują możliwy obszar zastosowania MERB.

    No i oczywiście MERB też ma za sobą pełne wsparcie Engine Yard, który jakiś czas temu otrzymał 3.5 miliona dolarów od VC.

    Na razie jest za wcześnie aby cokolwiek opiniować ale wydaje mi się, że MERB będzie perełką wśród developerów.

  26. Avatar Szymon said 4 months later:

    HAML… tak sobie patrzę w dokumentację i nie znalazłem tylko jednego: jak zrobić taki master-template… i w nim robić sobie include innych szablonów. To co znalazłem w sieci też nie nastraja optymistycznie… cóż.

  27. Avatar Jarosław Zabiełło said 4 months later:

    @Szymon: do włączania treści z innych szablonów masz trzy metody: (1) partials, (2) parts, (3) catch_content + throw_content. Haml do tego nic nie mają.

  28. Avatar Szymon said 4 months later:

    Rzeczywiście, zupełnie inna filozofia niż to do czego byłem przyzwyczajony, szukałem czegoś innego i już wiem dlaczego nic nie znalazłem. Który z tych sposobów polecasz?

  29. Avatar Jarosław Zabiełło said 4 months later:

    @Szymon: każdy sposób służy do czego innego. Pierwsza i trzecia metoda ma swój odpowiednik w Rails, druga – nie. Są jeszcze merb-slices pozwalające na składanie aplikacji z gemów. Tego też Rails nie ma.

(leave url/email »)

   Comment Markup Help Preview comment