Forum: Projeler turna RSS
HTML oluşturma modülü
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4428 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: HTML oluşturma modülü
CGI programı örneği olarak zamanında yazıverdiğim program, programcılık açısından içler acısı:

    /*
     * Bu içeriği oluşturmak için bir kütüphane kullanmak çok daha yararlı
     * olacaktır. Bunu küçük bir deneme olarak kabul edin:
     */
    dout.writef("Content-type: text/html; charset=utf-8\n\n");
    dout.writef("<html>\n  <body>\n");
 
    dout.writef(
       `<b>Seçiminiz?</b><br>
        <form method="GET" action="http://ddili.org/cgi-bin/deneme">
        <input type="RADIO" name="hayvan" value="kedi"> Kedi<br>
        <input type="RADIO" name="hayvan" value="köpek"> Köpek<br>
        <input type="RADIO" checked name="hayvan" value="at"> At<br>
        <br><b>Ne derece seviyorsunuz?</b><br><br>
        <select name="derece" derece=1>
        <option>Az
        <option selected>Orta
        <option>Çok
        </select>
        <br>
        <input type="HIDDEN" name="sevilen hayvan" size="32">
        <input type="Submit" value="Bir Düğme" name="birinci düğme">
        <input type="Submit" value="Başka Düğme" name="ikinci düğme">
        <input type="Submit" value="İptal" name="iptal">
        </form>`);
 
    dout.writef("\n<hr>\n<b>Ortam değişkenleri:</b><br><br>\n");
 
    foreach (değişken; ortamDeğişkenleri) {
        dout.writef("<b>%s</b>: %s<br>\n", değişken, getenv(değişken));
    }
 
    dout.writef("\n<hr><br>\n<a href=\"http://ddili.org/ornek_kod/deneme.d\">"
                "(Bu çıktıyı oluşturan program)</a><br>\n");
 
    dout.writef("\n  </body>\n</html>\n");

:) O içerik tamamen elle oluşturuluyordu. Öyle bir içeriği program kodları ile oluşturmayı denedim. Sonuçta ortaya şöyle bir kullanım çıktı:

    /*
     * Bu içeriği oluşturan kütüphane geliştirilmeye devam ediyor. Bunu küçük
     * bir deneme olarak kabul edin:
     */
    auto içerik = sayfa();
 
    içerik.ekle(
        postFormu("http://localhost/cgi-bin/cgi_deneme",
 
                  bold("Seçiminiz?"), br(),
 
                  radyoDüğmeleri("hayvan",
                                 [ Düğme("Kedi", "kedi"),
                                   Düğme("Köpek", "köpek"),
                                   Düğme("At", "at", SeçimDurumu.seçili) ],
                                 br()),
 
                  br(), br(), bold("Ne derece seviyorsunuz?"), br(),
 
                  seçimListesi("derece",
                               [ Seçenek("Az"),
                                 Seçenek("Orta", SeçimDurumu.seçili),
                                 Seçenek("Çok") ]),
 
                  br(),
 
                  basılanDüğmeGrubu([ Düğme("Bir Düğme", "bir_düğme"),
                                      Düğme("Başka Düğme", "başka_düğme"),
                                      Düğme("İptal", "iptal") ])
                  ));
 
    içerik.ekle(çizgi(), bold("Standart giriş:"), br());
 
    foreach (satır; stdin.byLine()) {
        içerik.ekle(paragraf("satır: " ~ satır));
    }
 
    içerik.ekle(çizgi(), br(), bold("Ortam değişkenleri:"), br());
 
    string[string] tanımlar;
    foreach (değişken; ortamDeğişkenleri) {
        tanımlar[değişken] = getenv(değişken);
    }
    içerik.ekle(tanımListesi(tanımlar));
 
    içerik.ekle(çizgi(), br(),
                bağlantı("(Bu çıktıyı oluşturan program)",
                         "http://ddili.org/ornek_kod/deneme.d"));
 
    writeln(new HtmlBelgesi(içerik));

Bu haliyle önceki koddan daha uzun ama artık HTML içeriği ile oynamak çok kolay. Daha çoook değişikliğe ihtiyacı var. Şimdilik karalama olarak şöyle:

module xml_elemani;
 
import std.stdio;
import std.conv;
import std.string;
 
struct Nitelik
{
    string etiket;
    string değer;
 
    this(const(char)[] etiket, const(char)[] değer = null)
    {
        this.etiket = etiket.idup;
 
        if (değer) {
            this.değer = değer.idup;
        }
    }
 
    string toString() const
    {
        string sonuç = etiket;
 
        if (değer) {
            sonuç ~= format("=\"%s\"", değer);
        }
 
        return sonuç;
    }
}
 
interface XmlElemanı
{
    string girintili(int düzey) const;
}
 
class TekEleman : XmlElemanı
{
    string etiket;
    string değer;
    Nitelik[] nitelikler;
    XmlElemanı[] altElemanlar;
 
    this(const(char)[] etiket, const(char)[] değer = null)
    {
        this.etiket = etiket.idup;
 
        if (değer) {
            this.değer = değer.idup;
        }
    }
 
    TekEleman nitelik(const(char)[] isim, const(char)[] değer = null)
    {
        nitelikler ~= Nitelik(isim, değer);
        return this;
    }
 
    TekEleman ekle(XmlElemanı[] altElemanlar ...)
    {
        this.altElemanlar ~= altElemanlar;
        return this;
    }
 
    TekEleman ekle(ÇokluEleman çoklu)
    {
        TekEleman[] eklenecekler = çoklu.elemanlar;
 
        if (eklenecekler.length) {
            this.altElemanlar ~= eklenecekler[0];
            eklenecekler = eklenecekler[1 .. $];
        }
 
        foreach (eklenecek; eklenecekler) {
            if (çoklu.ayraç) {
                this.altElemanlar ~= çoklu.ayraç;
            }
 
            this.altElemanlar ~= eklenecek;
        }
 
        return this;
    }
 
    string girintili(int düzey) const
    {
        enum girintiAdımı = "  ";
        string girinti = repeat(girintiAdımı, düzey);
        string sonuç = girinti ~ '<' ~ etiket;
 
        foreach (nitelik; nitelikler) {
            sonuç ~= ' ' ~ to!string(nitelik);
        }
 
        if (altElemanlar.length || değer.length) {
            sonuç ~= '>';
 
            if (altElemanlar.length) {
 
                foreach (eleman; altElemanlar) {
                    sonuç ~= '\n' ~ eleman.girintili(düzey + 1);
                }
 
                if (değer.length) {
                    sonuç ~= '\n' ~ girinti ~ girintiAdımı ~ değer;
                }
 
                sonuç ~= '\n' ~ girinti ~ "</" ~ etiket ~ '>';
 
            } else {
                assert(değer.length);
                sonuç ~= değer ~ "</" ~ etiket ~ '>';
            }
 
        } else {
            sonuç ~= "/>";
        }
 
        return sonuç;
    }
 
    override string toString() const
    {
        return girintili(0);
    }
}
 
TekEleman sayfa()
{
    return new TekEleman("body");
}
 
TekEleman bold(const(char)[] metin)
{
    return new TekEleman("b", metin);
}
 
TekEleman br()
{
    return new TekEleman("br");
}
 
TekEleman paragraf(const(char)[] metin)
{
    return new TekEleman("p", metin);
}
 
TekEleman bağlantı(const(char)[] metin, const(char)[] bağ)
{
    return (new TekEleman("a", metin)).nitelik("href", bağ);
}
 
TekEleman çizgi()
{
    return new TekEleman("hr");
}
 
TekEleman radyoDüğmesi(const(char)[] seçenekMetni,
                       const(char)[] değişkenİsmi,
                       const(char)[] değer)
{
    return
        (new TekEleman("input", seçenekMetni))
        .nitelik("type", "RADIO")
        .nitelik("name", değişkenİsmi)
        .nitelik("value", değer);
}
 
enum SeçimDurumu { seçili_değil, seçili }
 
struct Düğme
{
    string metin;
    string değer;
    SeçimDurumu durum = SeçimDurumu.seçili_değil;
}
 
class ÇokluEleman : XmlElemanı
{
    TekEleman[] elemanlar;
    TekEleman ayraç;
 
    this(TekEleman[] elemanlar, TekEleman ayraç = null)
    {
        this.elemanlar = elemanlar;
        this.ayraç = ayraç;
    }
 
    override string girintili(int düzey) const
    {
        string sonuç;
 
        const(TekEleman)[] yazdırılacaklar = elemanlar;
        if (yazdırılacaklar.length) {
            sonuç ~= yazdırılacaklar[0].girintili(düzey);
            yazdırılacaklar = yazdırılacaklar[1..$];
        }
 
        foreach (eleman; yazdırılacaklar) {
            if (ayraç) {
                sonuç ~= '\n' ~ ayraç.girintili(düzey);
            }
            sonuç ~= '\n' ~ eleman.girintili(düzey);
        }
 
        return sonuç;
    }
 
    override string toString() const
    {
        return girintili(0);
    }
}
 
ÇokluEleman radyoDüğmeleri(const(char)[] değişkenİsmi,
                           Düğme[] seçenekler,
                           TekEleman ayraç = null)
{
    TekEleman[] grup;
 
    foreach (seçenek; seçenekler) {
        TekEleman eleman = radyoDüğmesi(seçenek.metin,
                                        değişkenİsmi,
                                        seçenek.değer);
 
        if (seçenek.durum == SeçimDurumu.seçili) {
            eleman.nitelik("checked");
        }
 
        grup ~= eleman;
    }
 
    return new ÇokluEleman(grup, ayraç);
}
 
struct Seçenek
{
    string metin;
    SeçimDurumu durum = SeçimDurumu.seçili_değil;
}
 
TekEleman seçimListesi(const(char)[] değişkenİsmi, Seçenek[] seçenekler)
{
    TekEleman liste = (new TekEleman("select")).nitelik("name", değişkenİsmi);
 
    foreach (seçenek; seçenekler) {
        TekEleman eleman = new TekEleman("option", seçenek.metin);
 
        if (seçenek.durum == SeçimDurumu.seçili) {
            eleman.nitelik("selected");
        }
 
        liste.ekle(eleman);
    }
 
    return liste;
}
 
ÇokluEleman listeSatırları(string[] satırlar,
                           TekEleman ayraç = null)
{
    TekEleman[] elemanlar;
 
    foreach (satır; satırlar) {
        elemanlar ~= new TekEleman(satır);
    }
 
    return new ÇokluEleman(elemanlar, ayraç);
}
 
TekEleman liste(const(char)[] listeÇeşidi,
                const(char)[][] satırlar,
                TekEleman ayraç = null)
{
    TekEleman sonuç = new TekEleman(listeÇeşidi);
 
    foreach (satır; satırlar) {
        sonuç.ekle(new TekEleman("li", satır));
    }
 
    return sonuç;
}
 
TekEleman sıralıListe(const(char)[][] satırlar)
{
    return liste("ol", satırlar);
}
 
TekEleman sırasızListe(const(char)[][] satırlar)
{
    return liste("ul", satırlar);
}
 
TekEleman tanımListesi(const(char)[][const(char)[]] tanımlar)
{
    TekEleman sonuç = new TekEleman("dl");
 
    foreach (tanımAnahtar, tanımDeğer; tanımlar) {
        sonuç.ekle(new TekEleman("dt", tanımAnahtar));
        sonuç.ekle(new TekEleman("dd", tanımDeğer));
    }
 
    return sonuç;
}
 
ÇokluEleman basılanDüğmeGrubu(Düğme[] düğmeler, TekEleman ayraç = null)
{
    TekEleman[] elemanlar;
 
    foreach (düğme; düğmeler) {
        elemanlar ~= (new TekEleman("input"))
                     .nitelik("type", "Submit")
                     .nitelik("value", düğme.metin)
                     .nitelik("name", düğme.değer);
    }
 
    return new ÇokluEleman(elemanlar, ayraç);
}
 
TekEleman form(const(char)[] yöntem,
               const(char)[] eylem,
               XmlElemanı[] elemanlar ...)
{
    TekEleman form = (new TekEleman("form"))
                     .nitelik("method", yöntem)
                     .nitelik("action", eylem);
 
    foreach (eleman; elemanlar) {
        form.ekle(eleman);
    }
 
    return form;
}
 
TekEleman postFormu(const(char)[] eylem, XmlElemanı[] elemanlar ...)
{
    return form("POST", eylem, elemanlar);
}
 
TekEleman getFormu(const(char)[] eylem, XmlElemanı[] elemanlar ...)
{
    return form("GET", eylem, elemanlar);
}
 
class HtmlBelgesi
{
    TekEleman belge;
 
    this(XmlElemanı içerik)
    {
        belge = (new TekEleman("html")).ekle(içerik);
    }
 
    override string toString() const
    {
        return "Content-type: text/html; charset=utf-8\n\n" ~ to!string(belge);
    }
}

Ali
canalpay (Moderatör) #2
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sanırım mvc deseni tasarımında böyle şeyler system helper'a konuyor sanırım değil mi Mengü?
Kadircanında cgi işini halletmede yazabileceği bir işte bulmuş olduk :-)

Web kütüphanesi içinde örnek verdiler: http://www.digitalmars.com/webnews/newsgroups.…?art_grou…

Zaten Adam D. Ruppe 'nin yazdığını biliyordumda yerini kaybetmiş ayrıca D2 için mi bilmiyordum.
Mengu (Moderatör) #3
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Sanırım mvc deseni tasarımında böyle şeyler system helper'a konuyor sanırım değil mi Mengü?
Kadircanında cgi işini halletmede yazabileceği bir işte bulmuş olduk :-)

Web kütüphanesi içinde örnek verdiler: http://www.digitalmars.com/webnews/newsgroups.…?art_grou…

Zaten Adam D. Ruppe 'nin yazdığını biliyordumda yerini kaybetmiş ayrıca D2 için mi bilmiyordum.

genel html uretenlere html helper deniyor, form uretenlere de form helper.
http://www.mengu.net - some kind of monster
canalpay (Moderatör) #4
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bunu turna web framework projesine koyalım mı? system/helpers dizinine.
Tam benim düşündüğüm gibi.
Yalnız mengünün dediği gibi:
Ayrıca umarım o standartlar kimseyi kodlamaktan caydırmaz.
iki ayrı modül olarak yazılırsa daha iyi olabilir. Birde belki ilerde yardım alırız diye ayrıca Mengü'ye sorun oluşturmasın diye ingilizce başlamıştım. Özellikle sordum ancak kimse fikrini belirtmedi. İngilizce olsa olur mu? Yoksa projeyi Türkçeye çevirelim mi?

Birde Projeye eklenmek isteyen var mı?(Ali Bey ile Mengü ilk eklemiştim, sonra izinsiz eklediğim için silip tekrar sormayı düşündüm.)


Not: Sadece proje hakkında konuşuyorum. İlerde yeni forum açılırsa konu tamamen oraya taşınacak bir niteliğe sahip diye.
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4428 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu yardımcı modüllerin biraz elden geçmesi gerekiyor. İsimlerin filan değişmesi şart. Ama evet, projede yardımı olur. Sen ekle, zamanla düzeltiriz.

Beni seve seve ekleyebilirsin. Birim testleri eklemek için sabırsızlanıyorum. ;)

Ben Türkçe olmasını isterim ama İngilizceye itirazım olmaz.

Ali
Mengu (Moderatör) #6
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Bu yardımcı modüllerin biraz elden geçmesi gerekiyor. İsimlerin filan değişmesi şart. Ama evet, projede yardımı olur. Sen ekle, zamanla düzeltiriz.

Beni seve seve ekleyebilirsin. Birim testleri eklemek için sabırsızlanıyorum. ;)

Ben Türkçe olmasını isterim ama İngilizceye itirazım olmaz.

Ali

ustad ingilizce olsun, cumle alem faydalansin derim.
http://www.mengu.net - some kind of monster
canalpay (Moderatör) #7
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #5
Ben Türkçe olmasını isterim ama İngilizceye itirazım olmaz.

Benim içinde farketmez. Bencede Türkçe olması daha iyi ancak belki bir başka yabancıda yardım eder etmese bile eğer bir şeyler yaparsak kullanır umuduyla ingilizce yaptım. Birde tabiki Mengüde katılıp bize yardım etsin diye :-)

Bu yardımcı modüllerin biraz elden geçmesi gerekiyor. İsimlerin filan değişmesi şart. Ama evet, projede yardımı olur. Sen ekle, zamanla düzeltiriz.

Diğer katılmak isteyen kişilerde dil hakkında kararını versin. O dile göre adları değiştirip koyarız diye düşünüyorum. Ayrıca mengünün dediği gibi form ve genel html kod üreticisi olarak en az ikiye ayıracağız. Ayırıp koymak sorun değil ama.

derken Mengüde yorumunu yapmış:

ustad ingilizce olsun, cumle alem faydalansin derim.

Mengü senide ekleyeyim mi? Hatta session ve cookies modüllerini yazmak senden olsun :-)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4428 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İngilizce tamamdır. Ben yine de üşenmeyip Türkçe açıklamalar da eklerim.

Ali
canalpay (Moderatör) #9
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İngilizce tamamdır. Ben yine de üşenmeyip Türkçe açıklamalar da eklerim.
Onu asıl ben yaparım :-)

Kodlarda hem ingilizce hemde Türkçe açıklamar konsun. Ben ingilizce açıklama koymayabilirim ona göre :-p Birisi benim yerime çevirir :-)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Projeler turna RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-07-22, 09:45:09 (UTC -07:00)