Bu site de ne?

Çok büyük heves ile ve aslında hiç de fena başlamadığımız ve eskiden bağımsız bir yerde host ettiğimiz bu blogu artık çok da canlı tutamadığımızın farkına vardık. İşlerimiz yüzünden başlangıçta koyduğumuz hedefleri tutturamadık ve bu yüzden üzgünüz. Canlı tutamadığımız siteyi host ettirmek için daha fazla uğraşmak istemiyoruz. Ancak yazdığımız yazılar birçok insan tarafından okundu, yorumlandı ve hatta başkalarının yazılarında referans olarak linklendi. Halen yazmaya çalıştığımız konularda Türkçe kaynak çok fazlalaşmadığından yazıların yokolup gitmesini istemedik. Bu yüzden sanalBellek'i burada parka çekmeye karar verdik. Tüm yazıları taşıdık ancak yorumları maalesef taşıyamadık. Yorumlarıyla katkıda bulunanlara çok teşekkür ediyor ve yorumları kaybolacağından dolayı kendilerinden özür diliyoruz. Buradaki yazılara bağlantı verenleri, bağlantılarını değiştirmeleri için mümkün olduğunca bulmaya ve uyarmaya çalışacağız. Kısa bir süre sonra tümüyle silinecek olan eski sitedeki umutlarımızı belki de yeniden hayata döndürebiliriz diye bu yeni adresinde sanalBellek'e ya da kişisel olarak girişeceğimiz yeni sitelere taşıyacağız. Şimdiye kadar bu siteyi eski adresinde ziyaret etmiş, yazıları okumuş, yorumlar yazmış ve hatta sitelerinde buraya bağlantılar vermiş herkese çok teşekkür ediyoruz. Başka mecralarda görüşmek dileğiyle...

Labels:


yazının tamamını okumak için burayı tıklayın...

Web Standartlarını Kullanarak Geliştirmek

Öneriler ve en iyi uygulamalar

Roger Johansson, 456 Berea Street Son güncelleme tarihi: 2004-08-09 - Çeviren: Mert Derman

İçerik

  1. Giriş
  2. Tarihçe
  3. Web Standartları
  4. Yapı ve görüntüleme
  5. (X)HTML
  6. CSS
  7. Erişilebilirlik
  8. URLs
  9. Referanslar
  10. Dizin

1. Giriş

Bu döküman, web standartlarını kullanmanın, geliştiricinin daha az zaman ve para harcayarak üretebildiği yöntemle ve ziyaretçilerin daha iyi bir deneyim yaşayacağı web sayfaları oluşturmanızı nasıl ve neden sağlayacağını açıklamaktadır. Bunun yanısıra, olabildiğince çok kişi tarafından erişilebilir, yüksek kalitede web sayfaları üretmenin diğer yöntemlerini, prensiplerini ve en iyi uygulamalarını tartışmaktadır.

2. Tarihçe

Doksanların ikinci yarısında internet ve web ana akım haline geldiğinde, tarayıcı üreticileri, henüz, CSSi (Cascading Style Sheets) tasarımcıların bir HTML dökmanının sunumunu kontrol edebilmek amacıyla kullanabilmelerine yetecek kadar geliştirmemişlerdi. CSS Level 1’in belirtiminin (specification) 1996’da, CSS Level 2’nin belirtiminin ise 1998’de yayınlandığı düşünülürse, bu geliştirmenin o zamanki eksikliği bir miktar anlaşılabilir.

Tarayıcılardaki CSS desteğinin eksikliği, basılı malzeme üzerinde çalışırken mümkün olabilen denetim düzeyine alışmış grafik tasarımcıların beklentileri ile birleştiğinde, HTML, web sayfalarının görünüşünü kontrol etmeyi olası hale getiren her türlü yöntemle suistimal edildi. Bu suistimallere en büyük örnek, tasarımcılar, border="0" özelliğini kullanaraktabloların sınırlarını gizleyebildiklerini, böylece sayfa düzenini kontrol edebilecekleri görünmez bir ızgara oluşturabildiklerini keşfettiklerinde oluşan akımdır. Diğer bir örnek ise yine sayfa düzenini kontrol etmeye yardımcı olan, saydam yani görünmez aralık (spacer) GIF’lerinin kullanımıdır.

HTML’in hedefi hiçbir zaman döküman görünüşünü kontrol etmek olmadığından, kısa yollar, geçersiz kodlar ve üreticiye özel elemanlar (etiket/tag), özellikler (attribute) kullanıldı. Geçerleme çok az kişi tarafından bilinen ya da kullanılan birşeydi. Bu tarz kod için en açıklayıcı isim etiket (tag) çorbasıdır.

Tarayıcıların yeni sürümleri çıktıkça, CSS desteği geliştirildi ve genişletildi ama bu gelişme ve genişlemenin hızı olması gerektiği kadar değildi. Tarayıcı üreticilerinin CSS’i geliştirmek konusunda bu kadar yavaş olmalarına rağmen, çok sayıda insanın makul düzeyde CSS desteği olan tarayıcıları kullanıyor olduğu öyle bir noktaya geldik ki artık HTML’i sadece gerçek amacıyla, yani bir dökümanın görünüşünü değil yapısını tanımlamak amacıyla kullanmamamız için hiçbir neden kalmadı. Bu yüzden, artık özellikle bu amaçla tasarlanmış olan CSS’i kullanabiliriz.

3. Web standartları

Web standartları nedir?

Web standartları, W3C ve diğer standart oluşumları tarafından bir araya getirilmiş olan, web tabanlı içeriğin yaratılmasında ve çözümlenmesinde kullanılan teknolojilerdir. Bu teknolojiler, gelecekte de doğru biçimde görüntülenebilecek dökümanların Web’de yayımlanmasını ve bu dökümanların olabildiğince çok insan tarafından erişilebilir olmasını sağlamak üzere tasarlanmışlardır.

Yapısal diller

Sunum dilleri

Nesne Modelleri

Betik (script) dilleri

Bu döküman, yapı için XHTML 1.0 Strict, sunum için CSS Level 1 and Level 2 ve betik (sript) yazma için ECMAScript 262 (betik yazma için çok fazla örnek olmasa da) üzerinde durmaktadır.

Bir dökümanın web standartlarına bağlı kalınarak oluşturulduğu söylendiğinde döküman yukardaki teknolojiler kullanılarak üretilmiş olmanın yanısıra aşağıdaki özellikleri de sergiliyor demektir:

  • geçerli XHTML’den oluşur
  • sayfa düzeni için tabloları değil CSS’i kullanır
  • düzgün biçimde yapılandırılmış ve semantik olarak yazılmıştır
  • ve tüm tarayıcılarda çalışır.

Çevirenin notu: Yazı boyunca semantic kelimesi semantik olarak çevrilmiştir. Tam karşılığı “anlam bilimsel”dir, ancak bu yazıda “doğru, mantıklı ve olması gerektiği gibi, anlamına uygun biçimde” anlamında kullanılmaktadır.

“Tüm tarayıcılarda çalışır” cümlesinin “tüm tarayıcılarda aynı görünür” demek olmadığına dikkat edin. Bir dökümanın tüm tarayıcılarda aynı görünmesini sağlamak neredeyse imkansızdır. Yalnızca resimden oluşsa bile bir web sayfasının heryerde aynı görünmesi sağlanamaz. Web’de sunulan dökümanlara, farklı işletim sistemlerinde çalışan çok fazla sayıda değişik tarayıcı araç kullanarak değişik boyutlardaki ve kalitelerdeki monitörler aracılığıyla (ya da hiç monitörsüz), tarayıcılarının varsayılan metin büyüklüğünü ve diğer seçeneklerini değiştirmiş kullanıcılar tarafından erişilir. Bunu kabullenmek hayatınızın çok daha az karışık olmasını sağlar. Web sayfaları hazırlayan herkes, kağıt üzerinde yayın çıkaranlar ya da televizyon için filmler üretenler gibi düşünülmesi gereken önkoşulların varolduğunu bilmelidir.

Neden web standartlarını kullanmalı?

Bazı web geliştiricileri ve tasarımcıları web standartlarını kullanmaya karşı direnç gösterirler. Sık görülen nedenler şunlardır: Çok zor, Nasıl olsa her şekilde çalışıyor ve Kullandığım araçlar geçersiz kod üretiyor, ne yapayım.

Duygusal olarak tepki göstermek ve bildiğiniz, kullanırken kendinizi rahat hissettiğiniz teknikleri bırakıp yeni birşey öğrenmeye direnç geliştirmek çok kolaydır. Ancak, duruma mantıklı olarak bakarsanız web standartlarını öğrenmenin ve kullanmanın bir çok getirisi vardır. Bunlara bir kaç örnek:

  • Daha kolay geliştirme ve bakım: Daha semantik ve yapılandırılmış HTML kullanmak başka birisi tarafından yazılmış kodu anlamayı kolaylaştırır ve hızlandırır.
  • Gelecekte ortaya çıkacak tarayıcılarla uyumluluk: Tanımlanmış standartları kullanır, geçerli kod yazarsanız, yeni çıkacak tarayıcıların dökümanlarınızı anlamaması riskini azaltır yani dökümanlarınızı gelecek uyumlu yapmış olursunuz.
  • Web sayfalarının daha hızlı indirilmesi ve çözümlenmesi: Daha az HTML kodu daha küçük dosya boyutu ve daha hızlı indirilme demektir. Modern tarayıcılar, sayfaları, standart moddayken, geçmiş uyumlu moddayken olduğundan daha hızlı çözümlerler.
  • Daha fazla erişilebilirlik: Semantik HTML, yani yapının sunumdan ayrıldığı HTML, ekran okuyucuların ve alternatif tarayıcı araçlarının içeriği daha kolay algılamasını sağlar.
  • Daha yüksek arama motoru sıraları: İçeriğin ve görünüşün ayrılması içeriğin sayfa boyutunun çok daha fazlasını temsil etmesi anlamına gelir. Semantik kodlarla birlikte bu, sayfanın arama motoru sırasını yükseltir.
  • Daha kolay uyum: Semantik biçimde oluşturulmuş bir döküman, yalnızca farklı bir CSS dosyası ile ilişkilendirilerek yazdırma işlemi ya da el bilgisayarları veya cep telefonları gibi alternatif tarayıcı araçlara çok daha kolay uyumlu hale getirilebilir.

Web standartları, web sitesi yaratıcılarına para ve zaman kazandırır, ziyaretçilere ise çok daha güzel bir deneyim yaşatır. Bunun yanısıra, web standartları “gelecek”tir. Hali hazırda, web standartlarını kullanmıyorsanız şimdi başlamanın tam zamanıdır, aksi taktirde arkada kalma riskini almış olursunuz.

Daha fazla okuma:

Geçerleme

Geçerleme, bir dökümanın, yazıldığı dilin kurallarına uyup uymadığını kontrol etme işlemidir. Bu işlemi, bir metnin yazım ve sözdizim kurallarına uyumunu kontrol etmeye benzetebilirsiniz.

Geçerleme, web sayfaları geliştirme sürecinin çok önemli bir parçasıdır. Farkedilmesi zor birçok hata geçerleme sırasında bulunur. Hatalar, yazım hataları kadar basit olabileceği gibi yanlış kullanılan bir elaman ya da özellik kadar ciddi de olabilir.

Ne yazık ki bir çok insan sayfalarını geçerlemez. Bazı insanların bundan haberleri bile yoktur, diğerleri ise bu işlemi unuturlar ve hatta bazıları bilerek ve isteyerek geçerlemeden sakınırlar. Bu durum için ağırlıkla tarayıcı üreticileri suçlanabilir. Birçok tarayıcı hata vermek yerine, geçersiz HTML kodlarını ellerinden geldiğince düzgün biçimde çözümlemeye ve yazan kişinin ne kastettiğini becerebildiği kadar kestirmeye çalışır. işte tarayıcıların bu davranışları bugün yazılmakta olan özensiz kodlara neden olmuştur. Bu tür kodlar kestirilemeyen sonuçlar ürettikleri ve web tarayıcıların hata işleme yöntemlerine güvendiklerinden dolayı sorunludurlar.

HTML ve CSS kodlarınızı geçerlememeniz için hiç bir neden yok. Aksine, bu sizin leyhinize.

Why we won’t help you (Neden size yardım etmeyeceğiz?), Mark Pilgrim’in geçerlemenin avantajlarını anlattığı harika bir yazısıdır. Makale, ayrıca, yardım istemeden önce dökümanlarınızı geçerlemezseniz forumlarda ve e-posta gruplarında yardım bulmanızın neden daha zor olabileceğinden bahsetmektedir.

BBEdit ve Homesite gibi birçok HTML editörü, yerleşik geçerleme araçlarına sahiptir. Geliştirme aracınızın yerleşik geçerleme yöntemleri yoksa W3C’nin çevrimiçi erişilebilen geçerleme serviserinden faydalanabilirsiniz:

Geçerleme araçlarının ürettikleri hata mesajlarını anlamak bir miktar ustalık isteyebilir. Hata listesinin başlarında yeralan bir hata altınaki birçok hataya neden oluyor olabilir. Bu hataya neden olan kodu düzeltir ve dökümanı yeniden geçerlerseniz hata listesini beklediğinizden fazla kısaltırsınız. Sıkça görülen hata mesajlarının açıklamalarını Black Widow Web Design’ın Common XHTML Validation Errors sayfasında bulabilirsiniz.

Kodunuzu tamamıyla geçerlenmiş hale getirmek çok iyi bir fikirdir ama bazı geçerleme hatalarından kurtulmak oldukça zor olabilir. Buna en iyi örnek sayfaya Flash ya da eklenti (plugin) isteyen başka bir içerik gömmek olabilir. Flash’la ilgili sorunlar hakkında daha detaylı bilgiye Flash Satay: Embedding Flash While Supporting Standards (Web Standartlarını Desteklerken Sayfaya Gömülü Flash Kullanmak) ve Embedding flash without <embed> (<embed> Kullanmadan Sayfanıza Flash Gömmek) sayfalarından erişebilirsiniz.

4. Yapı ve sunum

Web standartlarından sözedilirken sıkça değinilen konulardan biri yapıyı ve sunumu belirleyen kodun birbirinden ayrılmasıdır. Özellikle dökümanın semantik yapısını düşünmeye alışkın değilseniz başlangıçta yapı ve sunumu belirleyen kodun farkını anlamak zor olabilir. Ama, bunu anlamak çok önemlidir. Çünkü bu ikisi birbirinden ayrıldığında bir dökümanın sunumunu CSS ile konrtrol etmek daha kolaydır.

Yapı bir dökümanın olmazsa olmaz parçaları ve içeriğinin semantik ve yapısal kodudur.

Sunum ise içeriğe verdiğiniz stildir. Birçok durumda sunum dökümanın nasıl göründüğü ile ilgilidir ancak herkes grafik bir tarayıcı kullanmadığından bazen dökümanın nasıl duyulduğunu da belirler.

Yapıyı ve sunumu mümkün olduğunca birbirinden ayırın. İdeal olarak, sadece yapıyı ve içeriği kapsayan bir HTML dökümanınız ve sunumu kontrol etmenizi sağlayan bir de CSS dökümanınız olmalıdır.

Yapının ve sunumun birbirinden ayrılması günümüz web tasarımında yaygın değildir. Birçok web sitesinde HTML kodu hem yapısal hem de semantik olarak eksiktir.

Sayfa düzeni için tablo kullanmak

Yapıyı ve sunumu birbirinden ayırmak için dökümanın sunumunu kontrol etmek amacıyla tabloları kullanmak yerine CSS kullanmalısınız. Sayfa düzeni için tablo kullanmaya alıştığınızda bu söylediğimi yapmak size zor gelebilir ama düşündüğünüz kadar zor değildir. Bu konuda internette çok miktarda yardım bulabilirsiniz. Ayrıca size katacağı avantajları da çok fazladır. Bu yüzden bu farklı düşünüş tarzını öğrenmeye zaman ayırmaya değecektir.

Daha fazla okuma:

Semantik HTML

Yapıyı sunumdan ayırmanın diğer bir önemli parçası dökümanın yapısını kodlamak için semantik HTML kullanmaktır. Dökümanın o bölümünde kullanmaya uygun yapısal anlamı olan bir xhtml etiketi varsa onun yerine başka bir şey kullanmak için hiçbir nedeniniz olamaz. Diğer bir deyişle bir HTML etiketini başka bir HTML etiketi gibi göstermek için CSS kullanmayın. Örneğin; bir başlığı kodlamak için <h1> yerine <span> elemanını kullanmayın.

Semantik HTML kullanarak bir dökümanın değişik bölümlerinin tüm web tarayıcıları için anlamlı olmasını sağlarsınız. Bu tarayıcı, modern bir PC’deki en son grafik tabanlı web tarayıcı, CSS’i işleyemeyen eski bir tarayacı ya da Unix üzerinde metin tabanlı bir tarayıcı olsa da farketmez.

Başlıklar

Başlıkları kodlamak için başlığın seviyesine göre <h1>, <h2>, <h3>, <h4>, <h5> ya da <h6> kullanın. <h1> en üst seviye başlık için kullanılır.

Örnekler:
<h1>Döküman başlığı</h1>

<h2>Alt başlık</h2>

Döküman başlığı

Alt başlık

Paragraflar

Paragrafları kodlamak için <p> elamanını kullanın. Paragraflar arasında boşluk yaratmak için <br /> elemanını kullanmayın. Paragraflar arasındaki aralıklar (margin) CSS tarafından belirlenir; bu da paragrafların doğru biçimde kodlanmasını gerektirir.

Örnek:
<p>Lorem ipsum dolor sit amet, consectetuer adipiscingelit. Donec risus. Ed rhoncus sodales metus. Donec adipiscingmollis neque. Aliquam in nulla.</p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Donec risus. Sed rhoncus sodales metus. Donec adipiscing mollis neque. Aliquamin nulla.

Listeler

Birşeylerin listesini kodlayacaksanız liste yapın. XHTML’de üç farklı liste türü vardır: sırasız listeler, sıralı listeler ve tanım listeleri.

İmli listeler olarak da bilinen sırasız listeler <ul> ile başlar ve </ul> ile sonlanır. Her liste elemanı <li> elamanı içinde yazılır.

Sıralı listeler ise <ol> ile başlayıp </ol> ile sonlanır.

Tanım listeleri biraz daha farklıdır. Terimler ve anlamları/açıklamaları gibi bölümleri kodlamada kullanılırlar. Tanım listeleri <dl> ile başlayıp </dl> sonlanır. Açıklanacak her terim <dt> elemanı, terimin anlamı/açıklaması da <dd> elemanı içinde yazılır.

Örnekler:
<ul>
<li>Öge 1</li>
<li>Öge 2</li>
<li>Öge 3</li>
</ul>
  • Öge 1
  • Öge 2
  • Öge 3
<ol>
<li>Öge 1</li>
<li>Öge 2</li>
<li>Öge 3</li>
</ol>
  1. Öge 1
  2. Öge 2
  3. Öge 3
<dl>
<dt>web sitesi</dt>
<dd>Bir kuruma ya da kişiye ait birbiri ile bağlantılı web sayfalarının toplamı.</dd>
<dt>web sayfası</dt>
<dd>Metin, grafik ve diğer ortam bileşenlerini içerebilen, internet üzerindeki temel bilgi birimi.</dd>
</dl>
web sitesi
Bir kuruma ya da kişiye ait birbiri ile bağlantılı web sayfalarının toplamı.
web sayfası
Metin, grafik ve diğer ortam bileşenlerini içerebilen, internet üzerindeki temel bilgi birimi.

Listenin içeriğinin alışılmış bir liste gibi görünmesini istemediğiniz de bile CSS liste kullanımını olanaklı kılar. Bağlantıların bir listesi olan yol bulma (navigation) barı buna iyi bir örnek olabilir. Bir menüyü liste gibi kullanmak menünün CSS desteklemeyen tarayıcılarda da anlamlı görünmesini sağlar.

Alıntılar

<q> elemanı, kısa, satır içi (inline) alıntılar için kullanılmalıdır. Web tarayıcıları <q> elamanının içeriğinden önce ve sonra otomatik olarak tırnak imleri ekler. Ne yazık ki, Internet Explorer bunu yapmaz ve hatta bazı durumlarda <q> elemanı erişim sorunlarına dahi neden olabilir. Bu nedenle kimileri <q> kullanmaktan kaçınmanızı onun yerine tırnak imlerini sizin eklemenizi salık verir. Satır içi (inline) alıntıları uygun sınıflarla <span> elemanları ile kullanmak alıntıları CSS ile biçimlendirmenizi sağlar ancak bu kodun semantik olarak hiçbir değeri yoktur. <q> elemanı hakkındaki sorunlarla ilgili daha ayrıntılı bilgi için Mark Pilgrim’in The Q tag (Q etiketi) adlı makalesini okuyabilirsiniz.

Daha uzun, bir iki paragraflık alıntılar için <blockquote> elemanı kullanılmalıdır. O zaman alıntıyı biçimlendirmek için CSS kullanabilirsiniz. <blockquote> elemanının içine doğrudan metin yazılamayacağına dikkat edin – içine yazılacak metin bir elemanın içinde olmalı; örneğin <p>.

cite özelliği, alıntının kaynağını belirtmek için hem <q> ile hem de <blockquote> ile kullanılabilir. Dikkat edin; eğer satıriçi alıntılar için <q> yerine <span> kullanırsanız cite özelliğini kullanamazsınız.

Örnekler:
<p>W3C’ye göre <q cite="http://www.w3.org/TR/REC-html40/struct/text.html#h-9.2.1">İfade elamanlarının görüntüleniş biçimi kullanıcıaracına bağlıdır.</q>.</p>

W3C’ye göre İfade elamanlarının görüntüleniş biçimi kullanıcı aracına bağlıdır.

<p>W3C’ye göre <span class="quote">&#8220;İfade elamanlarının görüntülenişbiçimi kullanıcı aracına bağlıdır.&#8221;</span>.</p>

W3C’ye göre “İfade elamanlarının görüntüleniş biçimi kullanıcı aracına bağlıdır.”.

<blockquote cite="http://www.w3.org/TR/1999/REC-html401-19991224/struct/text.html">    <p>&#8220;İzleyen bölümler metinleri yapılandırma konuları    üzerinde duruyor. Metin görünümleri ile ilgili elemanlar (hizalama    elemanları, font elemanları, biçem sayfaları, vb.) belirtimde    bulunmaktadır. Karakterler hakkında bilgi için döküman karakter    seti ile ilgili bölüme başvurunuz.&#8221;</p></blockquote>

“İzleyen bölümler metinleri yapılandırma konuları üzerinde duruyor. Metin görünümleri ile ilgili elemanlar (alignment elemanları, font elemanları, biçem sayfaları, vb.) belirtimde bulunmaktadır. Karakterler hakkında bilgi için döküman karakter seti ile ilgili bölüme başvurunuz.”

Vurgu

<em> vurgu için, <strong> ise daha güçlü vurgu için kullanılır. Birçok tarayıcı vurgulanmış metni italik,daha güçlü vurgulanmış metni kalın görüntüler. Ancak bu bir zorunluluk olmadığından vurgulanmış metnin nasıl görüntüleneceğinden emin olmak için görünümlerini CSS ile belirlemek en doğrusu olacaktır. Yapmak istediğiniz sadece görsel bir efekt ise vurgu elemanı kullanmayın.

Örnek:
<p><em>Vurgulanmış</em> metin normalde italik olarak,<strong>daha güçlü vurgulanmış</strong> metin ise kalın görüntülenir.</p>

Vurgulanmış metin normalde italik olarak, daha güçlü vurgulanmış metin ise kalın görüntülenir.

Tablolar

XHTML tabloları sayfa düzeni için kullanılmamalıdır. Ama, tablo verilerini göstermek için tabii ki tablolar kullanılmalıdır. Veri tablolarını olabildiğince erişilebilir kılmak için tabloyu oluşturmakta kullanılabilen birçok farklı bileşeni bilmek ve kullanmak gerekir. Bunlara örnek, tablo başlıkları (<th>), özetler (summary özelliği), ve etiketlerdir (<caption> elemanı).

Örnek:
<table class="example" summary="Bu tablo İsveç’teki1999–2003 yılları arası nüfus artışını göstermektedir.">
<caption>İsveç’teki yıllık nüfus artışı, 1999–2003</caption>
<thead>
<tr>
<td>&#160;</td>
<th scope="col">1999</th>
<th scope="col">2000</th>
<th scope="col">2001</th>
<th scope="col">2002</th>
<th scope="col">2003</th>
</tr>
</thead>
<tbody>
<tr>
<th>Nüfus</th>
<td scope="row">8 861 426</td>
<td scope="row">8 882 792</td>
<td scope="row">8 909 128</td>
<td scope="row">8 940 788</td>
<td scope="row">8 975 670</td>
</tr>
<tr>
<th>Artış</th>
<td scope="row">7 104</td>
<td scope="row">21 366</td>
<td scope="row">26 368</td>
<td scope="row">31 884</td>
<td scope="row">34 882</td>
</tr>
</tbody>
</table>
İsveç’teki yıllık nüfus artışı, 1999–2003
  1999 2000 2001 2002 2003
Nüfus 8 861 426 8 882 792 8 909 128 8 940 788 8 975 670
Artış 7 104 21 366 26 368 31 884 34 882

Tablolar ve kullanımları hakkında daha fazla bilgi için, Tables in HTML documents (HTML dökümanlarında tablolar) ve HTML Techniques for Web Content Accessibility Guidelines 1.0 (Web İçeriği Erişilebilirlik Yöntemleri için HTML Teknikleri 1.0) yazılarından faydalanabilirsiniz.

Daha fazla okuma:
  • SimpleQuiz

    Semantik yöntemle nasıl kodlama yapılacağını öğreten harika bir kaynak.

5. (X)HTML

HTML 4.01 kullanarak modern, yapılandırılmış ve standartlara uyumlu web sayfaları oluşturmak mümkündür. Ancak, temiz, semantik kodlamaya geçiş ve XML gibi diğer gelecek kodlama dillerine daha hazırlıklı olmak için yeni oluşturulacak web sayfaları için XHTML 1.0 Strict kullanılmasını öneririm. Bu dökümandaki örnekler de XHTML 1.0 Strict kullanılarak hazırlanmıştır.

XHTML 1.0, HTML 4’ün XML 1.0 içinde yeniden formule edilmiş ve HTML’in yerine kullanılmak için geliştirilmiş halidir. Kullanılmasını önerdiğim XHTML 1.0 Strict sunuma yönelik kodlama yapılmasına izin vermez (HTML 4.01 de buna izin vermez ama burada XHTML’e odaklanmak istiyorum). Bu yüzden, XHTML 1.0 Strict yapıyı sunumdan ayırmaya zorlar.

HTML’in son srümü olan XHTML 1.1 kullanımı teknik açıdan biraz daha zordur. Çünkü belirtim, XHTML 1.1 dökümanlarının MIME türü olarak application/xhtml+xml kullanılması ve text/html olarak sunulmaması gerektiğini belirtir. text/html kullanmak yasaklanmamıştır ama kullanılması önerilmez. Öte yandan, application/xhtml+xml kullanması gereken XHTML 1.0, HTML uyumlu ise MIME türü olarak text/html kullanabilir. XHTML Media Types (XHTML Medya Türleri) başlıklı W3C notu W3C tarafından önerilen MIME türlerine genel bir bakış içerir.

Ne yazık ki, bazı eski tarayıcılar ve Internet Explorer application/xhtml+xml MIME türünü algılamaz ve böyle bir durumda ya kaynak kodu gösterir ya da dökümanı hiç görüntülemez.

application/xhtml+xml kullanmak isterseniz, sunucunun, dökümanı isteyen tarayıcının MIME türünü destekleyip desteklemediğini kontrol etmesini ve destekliyorsa kullanmasını aksi taktirde text/html kullanmasını sağlamalısınız.

Sunucu tarafı betikleri için PHP kullanıyorsanız içerik üzerine anlaşma betiği, farklı tarayıcılara farklı MIME türü göndermek için kullanılabilir. :

<?php
if (stristr($_SERVER[HTTP_ACCEPT], "application/xhtml+xml") ||stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator")) {
header("Content-Type: application/xhtml+xml; charset=iso-8859-1");
header("Vary: Accept");
echo("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
}else {
header("Content-Type: text/html; charset=iso-8859-1");
header("Vary: Accept");
}?>

Betik, kullanıcı ajanının “application/xhtml+xml” değerini içeren Accept HTTP başlığı gönderip göndermediğini ya da kullanıcı ajanının application/xhtml+xml MIME türünü işleyebildiği halde uygun bir Accept HTTP başlığı göndermeyen W3C HTML geçerleyicisi olup olmadığını kontrol eder. Bu durumlardan biri doğruysa döküman application/xhtml+xml olarak sunulur. Bu tarayıcılar ayrıca bir de XML deklerasyonu göndermişlerdir. Internet Explorer’ın da içinde bulunduğu diğer tarayıcılara ise text/html olarak sunulur ve dökümana, IE/Win tarayıcılarını Quirks (acayip) moduna dönüştüren -ki bunun olmasını istemeyiz- XML deklerasyonu eklenmez.

Content-Type başlığından sonra proksi sunucuları gibi ara önbelleklere, dökümanıın içerik türünün dökümanı isteyen istemcinin yeteneklerine göre değişebildiğini söyleyen bir Vary başlığı gönderilir.

PHP kullanılarak yazılmış daha gelişmiş bir içerik üzerine anlaşma betiğini Serving up XHTML with the correct MIME type (XHTML’i doğru MIME türü ile sunmak) yazısında bulabilirsiniz. Bu betik, kullanıcı ajanının q-rating’ini (belirli bir MIME türünü ne kadar doğru işleyebildiğini belirtir) dikkate alır ve dökümanı application/xhtml+xml desteklemeyen kullanıcı ajanlarına text/html olarak göndermeden önce XHTML’i HTML 4’e dönüştürür.

Bu da ASP ve VBScript kullananlar için benzer bir betik:

<%If InStr(Request.ServerVariables("HTTP_ACCEPT"), "application/xhtml+xml") > 0 Or InStr(Request.ServerVariables("HTTP_USER_AGENT"), "W3C_Validator") > 0 Then
Response.ContentType = "application/xhtml+xml"
Response.Write("<?xml version=""1.0"" encoding=""iso-8859-1""?>" & VBCrLf);Else
Response.ContentType = "text/html"End IfResponse.Charset = "iso-8859-1"%>

MIME türü application/xhtml+xml olduğunda Mozilla gibi bazı tarayıcıların hata içeren dökümanları görüntülemediğini göreceksiniz. Bu geliştirme sürecinde çok iyi bir davranış olabilir ama XHTML uzmanı olmayan kişilerce güncellenen çevrimiçi sitelerde tüm kodun hatasız olduğundan emin olamadığınız sürece sorunlara yol açabilir. Böyle bir durumdaysanız HTML 4.01 kullanmayı seçebilirsiniz.

Aşağıdaki liste, HTML yerine XHTML 1.0 Strict kullanmayı düşündüğünüzde en çok dikkat etmeniz gereken noktaları göstermektedir:

  • Hep küçük harf kullanın ve tüm özellikleri tırnak içinde yazın: Tüm eleman ve özellik isimleri küçük harf olmalı ve tüm özellik değerleri tırnak içinde yazılmalı.

    Yanlış: <A HREF="index.html" CLASS=internal>
    Doğru: <a href="index.html" class="internal">

  • Tüm elemanları kapatın: HTML’de bazı elemanları kapatmayabilirsiniz. Bu elemanlar bir sonraki elemanın başlangıcında otomatik olarak kapanır. Ama XHTML buna izin vermez. <img> gibi içeriği boş olan elemanlar dahil tümü kapatılmalıdır.

    Yanlış: <li>Bileşen 1
    Doğru: <li>Bileşen 1</li>

    Yanlış: <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Doğru: <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>

    Yanlış: <br>
    Doğru: <br />

    Yanlış: <img src="image.jpg" alt="">
    Doğru: <img src="image.jpg" alt="" />

  • Özellikler kısaltılamaz: HTML’de bazı özellikler kısaltılabilir ama XHTML buna izin vermez.

    Yanlış: <input type="checkbox" id="checkbox1" name="checkbox1" checked>
    Doğru: <input type="checkbox" id="checkbox1" name="checkbox1" checked="checked" />

  • Kullanımdan kalkmış elemanları kullanmayın: HTML 4.01 Transitional ve XHTML 1.0 Transitional’de kullanılabilen bazı elemanlar XHTML 1.0 Strict’de (ve HTML 4.01 Strict’de ) kullanımdan kaldırılmıştır. Bunlara örnek şunlar verilebilir:<font>, <center>, alink, align, width, height (bazı elemanlar için) ve background.

Daha fazla okuma:

Doctype

Şu an, çok az HTML dökümanının doğru ve tam bir döküman tipi (doctype) ya da DTD’si (Document Type Declaration) vardır. Birkaç yıl öncesine kadar işlevsellikten çok dekoratif olarak kullanılmaktaydı ama artık bir döküman tipinin oluşu tarayıcıda dökümanın nasıl çözümlendiğini büyük oranda etkilemektedir.

Geçerli olmak için tüm HTML ve XHTML dökümanlarının döküman tipi deklerasyonu olması gerekir. Doctype, HTML ya da XHTML’in hangi sürümününün kullanıldığını belirtir. Geçerleyiciler geçerleme işleminde, tarayıcılar ise dökümanı çözümlerken hangi modu kullanaclarını belirlerken bu ifadeden faydalanır. Dökümanda doğru ve tam bir doctype deklerasyonu varsa birçok tarayıcı CSS spesifikasyonunu yakından izleyeceği standart modda çalışır. Ayrıca dökümanın tarayıcıda çözümlenmesi de hızlanır çünkü bu durumda tarayıcı geçersiz HTML kodlarını algılamaya, çözümlemeye çalışmaz. Bu ayrıca farklı dökümanlarda farklı çözümleme yapılmasını engeller.

Aşağıdaki doctype dökümanı XHTML 1.0 Strict kullanılarak oluşturulmuştur ve “doctype switching” (döküman tipi geçişi) özelliği bulunan tarayıcıalrın standart moda geçmesini sağlar.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Daha fazla okuma:

Karakter kodlaması (Character encoding)

HTML dökümanları karakter kodlamalarını belirtmek zorundadır.

Karakter kodlamasını belirtmenin en doğru yöntemi web sunucusunu karakter kodlaması ile birlikte content-type başlığını da gönderecek biçimde yapılandırmaktır. Bunu yapmanın detayları hakkında daha fazla bilgi için kullandığınız web sunucusu yazılımının belgelerine bakmalısınız.

Apache kullanıyorsanız, karakter kodlamasını belirtmek için .htaccess dosyanıza bir ya da birkaç kural eklemelisiniz. Örneğin, tüm dosyalarınız utf-8 kullanıyorsa şu kuralı ekleyin:

AddDefaultCharset utf-8

Belli bir dosya adı uazantısına sahip dosyalar için karakter kodlaması belirtmek için ise:

AddCharset utf-8 .html

Sunucunuz PHP betikleri kullanmanıza izin veriyorsa karakter kodlaması için şunu kullanabilirsiniz:

<?php    header("Content-Type: application/xhtml+xml; charset=utf-8");?>

Sayfalarınızı HTML olarak sunmak istiyorsanız application/xhtml+xml bildirimini text/html olarak değiştirin. Herhangi bir nedenle web sunucunuzu kullandığınız karakter kodlamasına göre yapılandıramıyorsanız dökümanlarınızın <head> bölümünde bir <meta> elemanı kullanın. Hatta web sunucunuz doğru yapılandırılmış da olsa dökümanlarınızda karakter kodlamasını belirtmek iyi bir fikirdir.

Örneğin, aşağıdaki <meta> elemanı tarayıcıya dökümanın ISO-8859-1 karakter kodlaması kullandığını bildirir:

<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1" />
Daha fazla okuma:

6. CSS

Şimdiye kadar çoğunlukla font özelliklerini belirtmek için kullanılan CSS artık dökümanın tüm düzenini kontrol etmek için kulanılabilir. Ancak bunu etkili bir biçimde yapabilmek düzeni tablolar kullanarak belirlemekten çok daha farklı bir yaklaşım gerektirir.

CSS’in düzeni etkili bir biçimde kontrol edebilmesi için yapısal ve semantik XHTML kullamak gerekir.

Tarayıcı desteği

Daha önce de değinildiği gibi CSS için tarayıcı desteği son yıllarda çok gelişmiştir. Ne yazık ki tüm tarayıcı üreticileri açık standartları kullanmakla ilgilenmemektedir, bu yüzden bahsedilen bu desteğin miktarı tarayıcıdan tarayıcıya değişmektedir. Bunun yanında taraycılarda beklendiği biçimde davranmamalarına yolaçan yazılım hataları da bulunmaktadır.

Şu anda (2004) CSS desteği en üst düzeyde olan tarayıcılar Mozilla (ve Gecko üzerine kurulu diğer tarayıcılar: Firefox, Camino, Netscape 6+), Opera ve Safari (WebCore üzerine kurulu diğer tarayıcılar: OmniWeb 4.5 ve daha ileri sürümleri). Internet Explorer 6/Win aynı derecede CSS desteği sunmaz, ama yine de en temel işleri yapmanıza izin verir. Internet Explorer 5/Mac CSS1 için çok iyi desteğe sahiptir ancak CSS2’yi o kadar iyi desteklemez. Windows için IE 5.* bir miktar destekler ama dikkat etmeniz gereken bazı sorunları vardır. Internet Explorer’ın daha önceki sürümleri bahsetmeye değmeyecek derecede az destek sağlamaktadır. Aynı şey Netscape’in 6’dan önceki sürümleri için de geçerlidir.

Birçok insan şu anda Windows altında Internet Explorer kullanmakta olduğundan tarayıcıyı en küçük ortak bölen olarak düşünmelisiniz. Bu, daha iyi CSS desteği olan tarayıcılar için olan tasarımınızda onların yeteneklerini kullanmamalısınız ya da kullanmayacaksınız anlamına gelmez.

Kullanımda olan tarayıcıların tümü, grafiksel olarak çekici bir düzen yaratmak amacıyla tamamıyla CSS kullanan web sitelerini çözümlemek için gereken seviyede CSS desteğine sahip değildir. Ama ne mutlu ki, birçok web sitesine uğrayan ziyaretçilerin çok çok azı CSS-tabanlı sayfa düzenini doğu biçimde çözümleyemeyecek kadar eski tarayıcı kullanmaktadır.

Bu insanların tamamıyla dışarıda bırakılmayacaklarını belirtmek gerek. Doksanlarda, “yanlış” tarayıcı (aslında Windows için Internet Explorer dışındaki herhangi bir tarayıcı) kullananları, sayfaları doğru görebilmeleri için tarayıcılarını güncellemeleri gerektiğini belirten bir sayfaya yönlendirmek için kullanılan kontrol betikleri çok popülerdi.

Şimdilerde destelenmeyen tarayıcıları ele almanın daha iyi yöntemleri var. Mantıklı ve semantik XHTML kullanmanın bir büyük avantajı da CSS olmasa dahi dökümanları erişilebilir kılmasıdır. — Sayfanın nasıl göründüğü — desteklenen bir tarayıcıyla aynı olmayacaktır ama içerik yine ordadır. Birçok durumda, sitenin ziyaretçilerinin çoğu için, içerik sunumdan çok daha önemlidir. Bu yüzden desteklenmeyen tarayıcı kullananları tamamen dışarda bırakmaktansa stil uygulanmamış bir sayfa görüntülmek daha iyidir.

Bunu yapmanın değişik yöntemleri vardır. En sık kullanılan yöntemlerden biri ilgili CSS dosyasına bağlantıyı sağlamak için @import kullanmaktır. Netscape 4 ve daha eski tarayıcılar @import bildirimini tanımazlar ve CSS dosyasını alamazlar. CSS’i tarayıcılardan gizlemenin bir çok yöntemi vardır. CSS’i gizleme yöntemlerinin çoğunun kullandığı ortak nokta web tarayıcılarının CSS kodunu ele alışlarındaki yazılım hatalarıdır. Bunun anlamı, CSS’i gizlemek için kullanılan yazılım hatasını düzelten ama CSS’in bazı bölümlerini gizlemeyi gerektiren eksikliği gidermeyen bir güncellemenin yapılabileceği riskinin varlığıdır. işte bu yüzden sırtınızı CSS atlatma yöntemlerine (CSS hacks) ne kadar az yaslarsanız o kadar iyidir.

Tabii ki tarayıcı kontrolü ve farklı tarayıcılara farklı CSS yönlendirmesi yapmak (ya da hiç CSS göstermemek) için sunucu tarafı teknolojilerini kullanabilirsiniz. Bunu yaparsanız kullandığınız betiği sürekli güncel tutmaya dikkat edin çünkü bir güncelleme ya da yeni bir tarayıcı çıkması durumunda hatalı CSS yönlendirmesi yapıyor duruma düşebilirsiniz.

Daha fazla okuma:

CSS kullanmanın değişik yöntemleri

HTML dökümanındaki elemanlara CSS uygulamanın birden çok yöntemi vardır.

Farklı dosyada

Tüm CSS kurallarını bir yada daha fazla ayrı dosyada tutmanın faydaları vardır. HTML dökümanlarının boyutları küçülür, CSS dosyaları tarayıcının önbelleğinde tutulur ve bu yüzden sadece bir kez indirilmeleri yeter ve son olarak tüm web sitesinin görünümünü değiştirmek için yalnızca bir dosyayı değiştirmeniz yeterlidir. Farklı bir dosyada tutulan CSS şöyle görünebilir:

h1 { font-weight:bold;}

Not: Farklı bir dosyada tutulan CSS’de <style> elemanı bulunmaz.

Bir HTML dökümanına bir CSS dosyasını <link> elemanı kullanarak bağlayabilirsiniz:

<link rel="stylesheet" type="text/css" href="styles.css" />

ya da bir <style> elemanı içinde @import kuralı kullanarak da CSS dosyasına bağlayabilirsiniz:

<style type="text/css">@import url("styles.css");</style>

Satıriçi

Bir HTML elemanında style özelliğini kullanarak doğrudan CSS uygulayabilirsiniz:

<h1 style="font-weight:bold;">Rubrik</h1>

Sunum ve yapıyı birleştirdiği için bu kullanımdan kaçınmalısınız.

Aynı dosyada

Aynı dosyada kullanılan CSS, dökümanın <head> elemanına ait bir <style> elemanı içinde bulunur:

<style type="text/css">h1 { font-weight:bold;}</style>

HTML ve CSS kodlarını ayrı dosyalarda bulundurmak en iyi yol olduğundan bu kullanımdan da kaçınmalısınız.

Daha fazla okuma:
  • At-Rules

    Diğer konuların yanısıra, CSS bağlama ve medya türleri üzerine bir yazı.

CSS Sözdizimi

Bir CSS kuralı bir seçiciden (selector) ve bir ya da daha fazla deklerasyondan oluşur. Seçici, kuralın hangi HTML elemanına ya da elemanlarına uygulanacağını belirler. Her deklerasyon bir özellik ve bir değerden oluşur. Deklerasyon bloğu {} arasında yazılır ve ; (notalı virgül) ile biter.

Basit bir CSS kuralı şöyle görünür:

p { color:#0f0; font-weight:bold;}

Yukardaki örnekte, p seçicidir. Bunun anlamı bu kuralın dökümandaki tüm <p> elemanlarını etkileyeceğidir. Kuraldaki iki deklerasyon <p> elamanı içindeki tüm metnin yeşil ve kalın yazılmasına sebep olur.

CSS kuralları hakkında daha geniş bilgi için, örneğin, CSS Beginner’s Guide veya CSS from the Ground Up sayfalarından ya da bir CSS kitabından faydalanabilirsiniz.

Daha fazla okuma:
  • CSS Crib Sheet

    Okuyucularının da yardımıyla Dave Shea pratik CSS ipuçlarının bir listesini hazırlamış.

  • Writing Efficient CSS

    John Gallant ve Holly Bergevin kısaltılmış CSS yazmanın yöntemlerini anlatıyorlar.

  • Selectutorial - CSS selectors

    Farklı CSS seçicilerinin ve nasıl kullandıklarının çok güzel anlatımı.

Gereksiz elemanlar ve sınıflar (class)

CSS kullanmaya başlarken en sık yapılan hata gereksiz XHTML elemanları, gereğinden fazla sınıf ve fazladan <div> elemanı kullanmaktır. Bu kodunuzun geçersiz olacağı anlamına gelmez ama sunumu ve yapıyı birbirinden ayırmanızın en önemli sebeplerinden biri olan daha basit ve temiz kodlar amacını hiçe saymanız anlamına gelir.

Gereksiz XHTML elemanlarının kullanımına bir örnek:

<h3><em>Headline</em></h3>

Başlığı italik yapmak istiyorsanız <h3> elemanının görünümünü değiştirmek için şu kuralı kullanın:

h3 { font-style:italic;}

Gereğinden fazla sınıf (class) kullanımı şöyle görünebilir:

<div id="main">
<div class="maincontent">
<p class="maincontenttext">
Lorem ipsum dolor
</p>
</div></div>

Oysa şu işinizi görecektir:

<div id="main">
<div>
<p>
Lorem ipsum dolor
</p>
</div></div>

div#main etiketi içindeki elemanları CSS aracılığıyla kontrol etmek için bağlamsal (contextual) seçicileri kullanabilirsiniz. Yukardaki örnek için şöyle görünecektir:

div#main p { /* kurallar */}

Birçok durumda mantıksal XHTML sayfanızın görünümünü CSS kullanarak fazladan kod yazmadan belirleyebilirsiniz. Ancak bazen biraz ekstra kod eklemek buna değen sonuçlar verecektir.

CSS ipuçları

CSS’i ciddi biçimde kullanmaya başladığınızda eninde sonunda bir takım sorunlarla karşılaşacağınız kesindir. Bazı sorunlar yanlış anlamalardan bazılarıysa açıkça ortaya konmamış belirtimler ve hatalı tarayıcılardan kaynaklanabilir. CSS Crib Sheet başlıklı yazıda güzel öenriler Dave Shea tarafından biraraya getirilmiştir. Aşağıda bu yazıdaki en önemli ipuçlarından birkaçını ve CSS Crib Sheet’de olmayan fazladan birkaç ipucunu bulabilirsiniz:

  • Önce geçerleyin: Hata ayıklama sürecinde öncelikle hem HTML’i hem de CSS’i geçerleyin. Birçok sorun geçersiz kodlardan kaynaklanır.

  • İlk etapta en modern tarayıcıyla test edin, daha sonra kodun diğer tarayıcılarda çalışmasını sağlayın: Test yaparken kötü ve/veya yanlış CSS gerçekleştirimi olan eski bir tarayıcı kullanıyorsanız yazdığınız CSS o tarayıcının CSS gerçekleştirimine uyarlanır. Daha gelişmiş bir tarayıcıda test yaparken bazı şeyler sizin yapmayı istediğiniz şekilde görünmeyebilir. Kodlarınızı, önce standartlara en uygun tarayıcıda çalışır duruma getirmek sonra yetenekleri daha yetersiz olan tarayıcılara uyarlamak en doğru yöntemdir.

  • CSS kutucuk modelini (box model) anlayın: Bir elemanın gerçek genişliğini ya da yüksekliğini bulmak için padding ve border değerlerini width ya da height değeri ile toplarsınız. Internet Explorer 5.*/Win’de ise, padding ve border değerleri verilen width ya da height içindedir.

    Diyelim ki CSS’iniz aşağıdaki gibi:

    div.box { width:300px; padding:20px; border:10px solid;}

    Bu div’in toplam genişliği 360px’dir.

    10px + 20px + 300px + 20px + 10px = 360px

    Internet Explorer 5.*/Win’de, toplam genişlik 300px’dir. İçeriğin genişliği ise 240px’dir.

    300px - 10px - 20px - 20px - 10px = 240px

    Bu sorunu aşmak için, ya bunu doğru ve yanlış algılayan tarayıcılara farklı değerler vermek amacıyla CSS atlatma yöntemleri kullanırsınız ya da bir eleman için width değeriyle birlikte padding ya da border kullanmaktan kaçınırsınız.

    CSS kutucuk modeli hakkında detaylı bir anlatım için Box model dökümanından faydalanabilrisiniz.

  • Sıfırdan farklı sayısal değerler için birim belirtin: CSS’de width, height ve font-size gibi özellikler için birim belirtmeniz gerekir. Bunun istisnası, değerin sıfır (0) olması durumudur. Bu durumda, sıfır her şekilde sıfır olduğundan birim kullanmak gereksizdir.

  • Float mantığını kavrayın: float kavramını anlamak biraz zor olabilir ama CSS bazlı sayfa düzenlerinde sıklıkla kullanıldığından bu konu çok önemlidir. Float kavramı ile ilgili bazı güzel makaleler şunlardır: Containing Floats, Floatutorial, ve Float: The Theory.

  • “LoVe/HAte”: Bağlantılar için yarı (pseudo) sınıfları sırayla tanımlayın; Link, Visited, Hover, Active.

  • “TRouBLed”: Bir elemanın margin, padding ya da border özelliklerini kısa yöntemle belirtirken değerleri yukarıdan başlayarak saat yönünde verin: Top, Right, Bottom, Left.

  • Sınıfları ve IDleri görünümlerine göre değil işlevlerine göre isimlendirin: Bir sınıfa .smallblue ismini verip daha sonra metni büyük ve kırmızı yapmak istediğinizde sınıf adı kafa karıştırıcı bir hal alacaktır. İsimleri, .copyright ya da .important gibi, yapıyı ya da işlevi yansıtacak biçimde vermek daha akıllıcadır.

  • CSS büyük/küçük harf duyarlıdır: class ve id HTML özelliklerinin değerleri CSS ile kullanıldığında büyük/küçük harf duyarlıdır (bkz. CSS2 syntax and basic data types).

  • IDlerinizi kontrol edin: Bir dökümanda bir id ismi yalnızca bir elemanda olabilirken class isimlerini birden fazla eleman alabilir.

  • class ve id isimlerinde yalnızca izin verilen karakterleri kullanın: Class ve id isimleri yalnızca [A-Za-z0-9] ve tire (-) karakterlerinden oluşabilir, ve tire ya da rakam ile başlayamaz.(bkz. CSS2 syntax and basic data types).

  • Yorumlarınızı doğru biçimde ekleyin: CSS yorumları /* ile başlar */ ile sonlanır:

    /* Bu bir yorumdur. */

CSS sayfa düzenleri

CSS’in sayfa düzenini belirlemek amacıyla nasıl kullanılacağını anlatan bir çok örnek ve adım adım dersler vardır. Basit bir düzenle başlayıp nasıl çalıştığını öğrenmek ve sonra daha gelişmiş düzenlere geçmek iyi bir yöntem olabilir.

Daha fazla okuma:
  • Simple 2 column CSS layout

    Bir başlık, iki sütun ve bir altlık içeren basit bir sayfa düzeni yaratma örneği.

  • CSS Layouts

    Değişik CSS sayfa düzenlerine bağlantılar içeren bir sayfa.

7. Erişilebilirlik

Erişilebilirlik, bir web sayfasını erişilebilir kılmak için en önemli neden bu olsa da sadece engelli ziyaretçilerin kullanımını desteklemek değildir. Erişilebilir bir web sayfası engelli ya da değil herkes için en iyi şekilde çalışır ve farklı web tarayıcılar veya araçlar kullanan çok sayıda insan tarafından erişilebilir.

Bir web sayfasını erişilebilir yaptıkça o sayfanın daha az çekici olacağı ya da erişilebilir olmayan bir web sayfasından çok farklı görüneceği sık rastlanan bir yanlış algılamadır. Bu kesinlikle doğru değildir. Erişilebilirlik görünümü etkilemek zorunda değildir.

Erişilebilirliğin herkese nasıl faydası olabileceğine bir örnek: Bir web sitesi bir seminere kayıt olmak amacıyla hazırlanmış bir form içermektedir. Formu kullanarak, seminere üç şehirden hangisinde katılınacağı seçilebilmektedir. Her şehrin adı bir seçim düğmesinin (radio button) yanında yer almaktadır. Eğer formu yaratan kişinin aklında erişilebilirlik yoksa grafiksel bir tarayıcı kullanan kişilerin bir şehir seçmek için imleçlerini minik seçim düğmesinin üzerine getirip tıklamaları gerekecektir. Geliştirici erişilebilirlik konusunu biliyorsa ve her seçim düğmesinin yanındaki etiketleri <label> elemanı ile kodlamışsa şehir seçmek için isimlerine de tıklanabilecektir. Sizce formu kullanan herhangi biri için hangisi daha basittir?

Semantik ve iyi yapılandırılmış XHTML kullanmak sizi erişilebilir web sayfalarına oldukça yaklaştıracaktır. Bir dökümanın ne kadar erişilebilir olduğunu anlamak için o dökümanı Lynx gibi metin tabanlı bir taratyıcıda görüntülemeye çalışıp içeriğinin ne kadar anlam ifade edebildiğine bakın. Bu yapmanız gereken erişilebilirlik testlerinden en küçüğü de olsa iyi bir başlangıç olacaktır.

Çerçeveler

Birçok web tasarımcısı tarayıcı penceresini, herbiri kendi HTML dökümanını içeren bağımsız parçalara bölmek için çerçeveleri kullanmayı sever. Bu intranet uygulamaları için faydalı olabilir. Ama herkese açık bir web sitesinde çerçeveleri kullanmanın bir çok sakıncası vardır:

  • Ziyaretçilerin kafasını karıştırısınız. Web’in en temel presniplerinden biri her sayfanın tekil bir URL tarafından temsil edilmesidir. Bu prensibi kırarak ziyaretçilerin web sitenizin yapısını anlamalarını zorlaştırırsınız.
  • Çerçeveler arama motorları için sorun yaratır. Bir arama motorunun çerçeveli bir web sitesini indeksleyebilmesi için tüm içerik sayfalarına bağlantı vermeniz gerekir. Yönlendirme bağlantıları gibi sitenin önemli parçalarının eksik olduğu bir dökümanı görüntülemek istiyor olacaklarından arama motorları aracılığıyla gelen ziyaretçiler de sorunlarla karşılaşacaktır. Bazı çerçeve temelli web siteleri, alt sayfaların indekslenmesini engellemek için robots.txt dosyası kullanarak bunun üstesinden gelmeye çalışırlar. Diğer siteler ise arama motorları aracılığıyla siteye gelen herkesi bir JavaScript yardımıyla ana sayfaya yönlendirirler. Hedef daha az ziyaretçi sayısı ise her iki yöntem de iş görür.
  • Çerçeveler favorilere ekleme işlemini engelleyebilir. Birçok tarayıcı çerçeve temelli bir sitedeki sayfaları favorilere ekleyemez. Böyle bir favoriyi açtığınızda çerçeve grubunun varsayılan durumuna yönlendirilirsiniz, ki bu genellikle web sitesinin ana sayfasıdır.
  • Yazdırmak çok zorlaşabilir. Ziyaretçiler dökümanları yazdırmak istediğinde zorluklar yaşayacaktır. Birçok tarayıcı bir çerçeveyi yazdırmadan önce o çerçeveyi aktive etmenizi bekler.
  • Bağlantıları e-posta aracılığıyla yollamak zorlaşır. Çerçeveler, sitedeki bir sayfaya bağlantıları e-posta ile gönderme olasılığını ortadan kaldırır. Bunu aşmanın yöntemleri vardır ama bu yöntemler siteyi karmaşıklaştırır.
  • Sitenin erişilebilirliğini artırmak zorlaşır. Çerçeveleri destekleyen grafiksel bir tarayıcı kullanmayan ziyaretçiler sorun yaşarlar. Bu yüzden erişilebilirlik kılavuzları çerçeve kullanılmamasını önerirler.

Tüm bunların yanısıra, kendinizi de zora sokarsınız. Çerçeveler bir web sitesinin teknik olarak karmaşıklığını artırır.

Tablolar

Genelde insanlar “sayfa düzeni için tablo kullanmayın” önerisni “tablo kullanmayın” olarak yorumlamaktadır. Ancak bu yanlış bir algılamadır. Kodlamaya çalıştığınız tablo verisiyse bir tablo kullanmalsınız. Ancak, veri tabloları oluştururken tabloları daha mantıklı ve erişilebilir yapmanın birçok yolu olduğunu unutmayın.

Daha fazla okuma:

Formlar

Genellikle formları kullanmak gereksiz derecede zordur. Bunun nedeni biraz mantıksız yöntemlerle hazırlanmış olmaları biraz da arka plandaki HTML kodunun formları daha erişilebilir ve kullanımı kolay kılmak amacıyla varolan elemanları kullanmıyor olmasıdır. <label>, <fieldset> ve <legend> elemanları kullanılmak için vardır.

“Formların düzeni için ne kullanılmalı” sorusu sık sorulan bir sorudur. Kimileri formların tablo verileri olduğunu ve tablo biçiminde kodlanmaları gerektiğini söylerken kimileri de CSS kullanılması gerektiğini savunur. Her ikisini de kullanabilirsiniz ama tablo kullanırsanız, formun doğrusallaştırıldığında dahi anlamlı ve kullanılabilir olmasına dikkat edin.

Daha fazla okuma:

JavaScript ve cookieler

JavaScript’e bağımlı olmaktan kaçının. Düşündüğünüzden çok daha fazla insan güvenlik nedeniyle ya da açılan pencereleri engellemek amacıyla tarayıcısında JavaScript kullanımı devre dışı bırakmıştır. Hatta JavaScript desteklemeyen tarayıcı bile kullanıyor olabilirler. TheCounter.com’a göre web kullanıcılarının 6%’sı JavaScript’i devre dışı bırakmış durumdadır. Bu rakam W3Schools.com’da 8%dir.

JavaScript’in kullanıldığı birçok durumda aslında Javascript ziyaretçiye hizmet etmemektedir. Tabii ki JavaScript kullanmanın ziyaretçilere çok daha iyi deneyimler yaşattığı durumlar da vardır. Bunlara form girişlerinin geçerlenmesi örneği verilebilir.

Tüm bunların JavaScript kullanmayın demek olmadığını unutmayın. Söylemek istediğim bir web sitesinin çalışmasını JavaScript’e bağımlı hale getirmeyin.

Aynı şey cookieler için de geçerlidir. Ziyaretçi cookieleri engellediğinde siteniz çalışmayacak duruma gelecek denli cookielere bağımlı olmasın.

8. URLler

Bu bölüm aslında web standartları ya da erişilebilirlikle ilgili değil. Ama burada, çünkü, URLlerin oluşturulma şekli bir web sitesinin arama motorları tarafından ne kadar iyi indeksleneceğini ve ziyaretçileri tarafından ne kadar kullanılabilir olduğunu belirler.

Bazı arama motorları sonları sorgu ifadeleri ile (query string) biten URLleri takip etmez. İçeriğini dinamik olarak veritabanlarından oluşturulan web sitelerinde bu tür URLler çok yaygındır ve yaklaşık şöyle görünürler:

http://yourdomain.com/products.asp?item=34627393474632&id=4344

Hem arama motorları hem de insanlar için daha kullanışlı bir URL oluşturmanın en kolay yolu URL sanki bir klasöre bakıyormuş gibi görünecek biçimde değiştirmektir. Böyle yapıldığında yukarıdaki örnek şu şekilde görünür:

http://yourdomain.com/products/item/34627393474632/id/4344/

Web sunucusu bu yeni URLyi yorumlar ve kendi içinde ilk örnekteki haline dönüştürür. Bunun nasıl yapılacağı ile ilgili detaylı dökümanlara erişebilmeniz için bağlantıları bu bölümün sonunda bulabilirisiniz.

Daha kolay ama daha karmaşık bir yöntem ise görünür URLleri yeniden yazmak (rewrite) ve insanlar tarafından okunur kılmaktır:

http://yourdomain.com/products/flowers/tulips/

Bu tür URL kullanmanın avantajları, arama motorları tarafından sitenin daha etkili indekslenmesi, URLlerin insanlar tarafından kolay okunabilmesi ve sunucu tarafında hangi teknolojiyi kullandığınızı gizleyebilmenizdir. URL, .asp, .cf, .cgi or .jsp gibi, sunucuya özgü dosya uzantılarını içermediğinden, bunu yapmanız gerektiğinde sunucu tarafında kullandığınız teknolojiyi değiştirmek de kolay olacaktır.

URLlerinizde sorgu ifadeleri kullanma yöntemini seçerseniz ampersandları, &, HTML karşılıklarına, &amp;, kodlamalısınız. Böyle yapmazsanız bazı tarayıcılar, yapmaları gerektiği gibi ampersandı bir HTML bileşeninin başlangıcı olarak algılar ve eğer hemen ardından gelen metin bir HTML bileşenine denk geliyorsa tarayıcı URLyi dönüştürür ve birçok durumda da sorgu ifadesini bozar.

Bahsedilmeye değer bir başka konu da birçok web sitesi için www alt etki alanı kullanmanın gereksiz oluşu ve http://www.yourdomain.com/ yerine http://yourdomain.com/ şeklinde kullanılması gerektiğidir. Bu konuda daha fazla bilgiye no-www.org adresinden ulaşabilirsiniz. www alt etki alanı kullanın ya da kullanmayın, web sunucunuzda http://www.yourdomain.com/ ve http://yourdomain.com/ adreslerine gelen tüm trafiği aynı URI’a yönlendirmek iyi bir fikirdir.

Daha fazla okuma:

9. Referanslar

Önerilen kitapların, web sitelerinin ve e-posta gruplarının bir listesi.

Kitaplar

CSS

Genel web tasarımı

  • A List Apart

    Özellikle web standartları kullanarak tasarımın getirileri ve teknikleri üzerine odaklanmış, web içeriğinin tasarlanması, geliştirilmesi ve anlamı konusunda makaleler içeren haftalık çevrimiçi dergi.

  • webdesign-L

    Web’i yaratmakla ilgilenenlerin e-posta listesi. Listede en çok konuşulan konular, web tasarımı ve web geliştirme.

HTML

Erişilebilirlik

Web standartları

XHTML

10. Terimler sözlüğü

Erişilebilirlik
Erişilebilir bir web sitesi, donanım ve yazılım olarak ne kullanırlarsa kullansınlar ve sitede ne ile geziniyor olurlarsa olsunlar herkes için erişilebilir sitedir.
CSS (Cascading Style Sheets)
Bir dökümanın nasıl sunulacağını tanımlayan kurallar.
HTML (HyperText Markup Language)
Bir dökümanının yapısını kodlamada kullanılan dil.
Sunum
Bir web sitesinin görünümü (ya da duyuluşu).
Yapı
Bir dökümanın olmazsa olmaz parçaları ve içeriğinin mantıksal kodları.
Kodlama/İşaretleme (Markup)
Kodlayarak/işaretleyerek bir dökümana ve içeriğine yapısını ve anlamını verirsiniz. Web’de kodlama için HTML ve XHTML kullanılır.
Geçerleme
Geçerleme, bir dökümanın yazıldığı dilin kurallarına uyup uymadığını kontrol etmektir. Bir metnin yazım ve dilbilgisi hatalarını kontrol etmeye benzetilebilir.
W3C (World Wide Web Consortium)
Web için belirtimler, kılavuzlar ve araçlar üreten organizasyon.
Web standartları
Web standartları, W3C ve diğer standart oluşumlar tarafından yayınlanan ve web tabanlı içeriğin yaratılması ve çözümlenmesi için kullanılan teknolojilerdir. Bu teknolojiler webde yayınlanan dökümanların gelecekte de kullanılabilir ve olabildiğince erişilebilir olmasını sağlamak için tasarlanmışlardır.
XHTML (Extensible HyperText Markup Language)
XML’in kurallarına uyacak biçimde yeniden formüle edilmiş HTML.
XML (Extensible Markup Language)
HTML gibi görünen ama yazarın uygun elemanlar belirterek veriyi tanımlayabildiği kodlama dili.

Yorumlar, sorular ve öneriler? Lütfen bana ulaşın..

© Copyright 2004 Roger Johansson - Çeviri: Mert Derman a.k.a spinodal

Yazının aslına şu adresten, kaynak sitesindeki Türkçe haline ise bu adresten erişebilrisiniz.

Çeviri hakkında görüş, eleştiri ve düzeltmelerinizi spinodal at gmail nokta com adresine iletebilirsiniz.

Labels: , ,


yazının tamamını okumak için burayı tıklayın...

Güzel Gelişmeler - SWSSY


swssy yarışma


Sunipeyk sitesi, web standartlarına uygun, geçerli kodlar ile site yapımını teşvik etmek amacıyla Web Standartları Site Yarışması düzenliyor. Yarışmanın duyrulduğu sayfada da bağlantısı bulunan ve Mehmet Doğan tarafından yazılmış bir de "Web Standartları Nedir?" yazısı mevcut. Güzel gelişmelerle dönüş yapayım dedim.

spinodal tarafından 14.06.2006 tarihinde yazılmıştır.

Labels: , ,


yazının tamamını okumak için burayı tıklayın...

Lucene ve Memory Problemleri

Bir süredir içinde yuvarlandığım bir konuda Lucene. Lucene Java da geliştirilmiş bir arama motoru belkemiği olarak tanımlanabilir. Arama ve indeksleme işlemlerini yüksek performanslı olarak yapan Apache bünyesinde bulunan bir açık kaynaklı kütüphane. Lucene hakkında yakında daha detaylı bir yazı yazmayı düşünüyorum. Fakat şimdilik yakın zamanda beni uzun süre uğraştıran bir konu hakkında ufak birşeyler yazmak istedim. Lucene gerçekten çok hızlı ve de çok başarılı sonuçlar veren bir kütüphane. Fakat gerçekten dikkatli olunduğunda. Dikkatli olunmadığı zaman işleri cehnneme çeviren bir canavarada dönüşebilmekte. En basitinden sunucunun hafızasını aç bir canavar gibi amansıca sömürebilir :) Ve buda yetmezmiş gibi çılgınlar gibi OutOfMemoryExceptionalarını peşpeşe dizebilir. Maalesef bu köprüden geçen biri olarak söylemeliyimki gerçektende tadılması güzel olan bir deneyim değil.

Arama motorları genelde yüksek işlem gücü yanından büyük hafızalarada ihtiyaç duymaktadır. Fakat büyük hafza diyince de ipin ucunu da kaçırmamak lazım tabii ki :) . Benim geliştirdiğim ortamda yaklaşım 13GB lık bir indeks dosyasından (12 alana göre indekslenmiş) 6 değişkenle arama yapılabilmekte. Bu da gerçekten Lucene için ağır bir işlem gibi. Full text search e yönelik yazılan Lucene i daha çok bir veritabanı araması yapar gibi kullanmak gerektiğim bu projede kompleks bir Query geçmem gerekti. Gerçekten de bazen query süreleri gerektiğinden uzun sürmekte. Bununla ilgili performans çalışmalarım devam ediyor.

Bu yazımda bahsetmek istediğim ise şimdiye kadar kullandığım kadarı ile Lucene içinden çıkarttığım dersler. Lucene kullanmış olanlar IndexSearcher'ı da tanıyordurlar. IndexSearcher denilen yapı sizin arama yaptığınız indeks dosyalarını hafızaya alıp bunların içinde gerekli işlemleri yapan sınıftır. Bu sınıf gerçektende çok dikkat edilerek kullanılması gerekmekte. Çünkü her açılan IndexSearcher hafızada sahip olduğunuz indeks dosyalarının boyutuna göre yer kaplamakta ve de jvm ölmediği sürece bu alanı kesinlikle bırakmamakta. Eğer sunucunuza güveniyorsanız o zaman çoklu IndexSearcher kullanmak belki bi ihtimal olabilir ama yoğun arama yapılacak alanlarda bunun olumsuz bir sonuç ortaya koyacağını söylemeliyim.

Deminde dediğim gibi çıkarmış olduğum birkaç ders var ve bunları şu şekilde sınıflandırabilirim:

1. İhtiyacınız olandan daha fazla searchers/readers açmayın/yaratmayın/kullanmayın

Her IndexSearcher/IndexReader açtığınızda hafızanızdan bir parça daha alacaktır. Static olarak tanımlanmış bir uygulama yapısı içinde sadece bir adet IndexSearcher/IndexReader ihtiyacınızı görecektir. Sadece hafızada paylaşılan ve çoklu bir thread yapısında paylaşılabiilinen bir IndexSearcher/IndexReader yapısına ihtiyacınız var.

2. İşinizin bittiği kaynakları mutlaka kapatın

Araştırmamda en çok hata yapıldığını gördüğüm hatalardan biride işi biten IndexSearcher veya IndexReader ları kullanıcıların kapatmaması durumu. Herşeyi GarbageCollector un yapacağını düşünmemek ve işi bittiğinde bu yapıları kapatmayı unutmamak gerkmektedir.

3. İhtiyacınız olandan daha fazla kolonu sıralamayın.

Her sıralama yaptığınızda sıralama yaptığınız alan için hafızada bir FieldCache dizisi (array) yaratılır. Eğer hafızadan bir miktar kurtarmak istiyorsanız sıralama yapılmasına izin verilen alanların sayısını azaltabilirsiniz. 30 alana göre sıralama yapmak yerine önemli olan daha az alana göre sıra yapmak çok daha mantıklı ve hafızadan kurtarıcı bir yapı olacaktır.

4. RangeQuery, PrefixQuery ve WildCardQuery Hafızadan alan demektir.

Eğer RangeQuery, PrefixQuery ve WildCardQuery yapılarından birini kullanıyorsanız, hele birde TooManyClauses hatası almamak için BooleanQuery.maxClauseCount değeri ile oynadıysanız hafızanızdan büyük bir miktarı bu işlere ayırmayı çoktan kabul etmişsiniz demektir; hafızanızın yoğun ve ağır kullanılmasına hazırlıklı olun. Bunu düşünerek query lerinizi olabildiğince optimize kullanmaya dikkat etmeniz gerekmektedir. eğer "field:a*" gibi bir query hazırladıysanız; Lucene bunu field alanında bulunan ve de a ile başlayan tüm değerler için bir TermQuery oluşturup bunları BooleanQuery altında birleştirecektir. Buda devasa bir query demektir. Devasa bir query ise hafızada büyük bir alanın kullanılması demektir.

5. Kullanmayacağınız alanları ayrı ayrı alanlarda (field) indekslemeyin

İndekslenmiş birçok alanınız var ise bu problemle karşılaşabilirsiniz. FieledNorms yapısı her dökümanın (yada girdinin) her indekslenmiş alanı için 1 byte kaplamaktadır. İndekslenmiş alanın değeri boş bile olsa genede bu alan kaplanacaktır. Internette indeksleme sürecinde bu normların hesaplanmamasını sağlanabileceği hakkında bazı şeyler okudum. Fakat bu konuda hala araştırma düzeyidne olduğum için çok yardımcı olamayacağım. En azından şu an için

Bu sıraladığım problem çözüm önerilerinden en çok baş ağrıtanı 1. sırada yer alan IndexSearcher/IndexReader konusu. OutOfMemory hatalarında ilk bakacağınız yer bu olsun.

Lucene gerçekten çok başarılı bir kütüphane fakat en başta da söylediğim gibi dikkatli kullanılmadığı zaman uykuları da kaçırabilecek bir yapı. Gene başta söylediğim gibi Lucene ile ilgili genel bir yazı yazmak istiyorum ve bunun hazırlıklarına başladım. O zamana kadar herkese iyi aramalar dilerim :)

randomHero tarafından 17.02.2006 tarihinde yazılmıştır.

Labels: , , ,


yazının tamamını okumak için burayı tıklayın...

CruiseControl Lambası

Kendi publisherları, Firefox eklentisi derken CruiseControl.NET için yazılım ekibine build sonuçlarını bildirmenin başka bir yolunu daha öğrendik. Lamba! Evet yanlış duymadınız lamba. (Ferruh Mavituna'nın sitesinden)

Not: Tatildeydim; aslında beynim hala tatilde; artık döndüm. Memleket (Çukurova) sıcak ama güzeldi.

spinodal tarafından 15.08.2005 tarihinde yazılmıştır.

Labels: , , ,


yazının tamamını okumak için burayı tıklayın...

Tablosuz Tasarım - Douglas Bowman

Tablosuz tasarımı anlatmak için Douglas Bowman'ın hazırladığı sayfalar... Daha ne denilsin, daha ne yazılsın...

spinodal tarafından 29.07.2005 tarihinde yazılmıştır.

Labels: ,


yazının tamamını okumak için burayı tıklayın...

CruiseControl için Firefox eklentisi

Diyelim CruiseControl ya da CruiseControl.NET ile otomatik oluşturma sürecinizi ayağa kaldırdınız. Oluşturma işlemlerinin durumlarını izlemek için CruiseControl'de tarayıcınızı CruiseControl.NET'de ise ya tarayıcınızı ya da CCTray arayüzünü kullanıyorsunuz ("yahu daha bunlardan bahsetmedin ki be adam" dediğinizi duyar gibiyim ama bir türlü oturup şu bilgileri biraraya toplayamadım, yazıya dönüştürmedim ki). Firefox kullanıyorsanız bir seçenek daha var... Henüz kullanmadım (biliyorum kullanmadan buraya yazmak pek hoş değil ama çok hoşuma gitti, sabahı bekleyemedim) ama şöyle bir firefox eklentisi varmış...
Bu sabah denedim, hem CruiseControl ile hem de CruiseControl.NET ile sorunsuz çalıştırmak çok kolay. Sadece eklentiyi kurun ve seçeneklerden CruiseControl web adresinizi ekleyin. Bu kadar...

CruiseControl Firefox eklentisinin görünümü


spinodal tarafından 27.07.2005 tarihinde yazılmıştır.

Labels: , , , ,


yazının tamamını okumak için burayı tıklayın...

EntLib Logging bloku için RollingFileSink(ler)

MS Enterprise Library'nin Logging and Instrumentation Application Block'unu kullanıyoruz. Ancak log dosyaları büyüdükçe büyüyor ve bunları yedeklemek sonra silip yenileri için yer açmak gibi işleri elle yapmak gerekiyor. Oturup bunun için bir uzantı (extension) yazalım mı diye düşünürken önce bir bakınalım dedik. Hisham Baz'ın blogunda kendi yazdığı bir Rolling File Sink uzantısı olduğunu okuduk. Okurken başka bir güzel bilgi daha gördük: gotdotnet içinde de böyle bir uzantı yazılmış. Her ikisi de güzel uzantılar ama biz Hisham Baz'ınkini değil gotdotnet'dekini daha uygun bulup kullandık. İkisinin de detaylarına girmiyorum, verdiğim bağlantılardan gidip detaylar incelenebilir. Ama dikkat çekmek istediğim tek nokta var: gotdotnet'dekini kullanırsanız yukarıdaki verdiğim bağlantıdan ulaşılan sayfasındaki bir gönderiyi es geçmeyin. Ne diyor bu gönderi? Kullandığınız işletim sisteminin bölgesel ve dil seçeneği "en-US" değilse hata alacağınızı ve bunu düzeltmek için yapmanız gerekeni beliritiyor bu gönderi. Aslında kullandığınızda açıkça hata almayabilirsiniz. Hatadan dolayı ilgili sink bulunamadığından varsayılan olarak Event Viewer'a logluyor ve ayrıca yine Event Viewer'a bir warning yazıyor. Tüm yapmanız gereken RollingFlatFileSink.cs'de RolloverFile metodunda GetDateTimeFormats'ı en-US cultureinfo ile çağırmak. Zaten bu bahsettiğim gönderide yazıyor ama atlanabilir, o gönderi o sayfadan kalkabilir vs. vs. düşüncesiyle buraya not ediyorum. Dikkatinize...

spinodal tarafından 14.07.2005 tarihinde yazılmıştır.

Labels: , , ,


yazının tamamını okumak için burayı tıklayın...

NAnt ve CruseControl.NET konusunda kitap

Daha önce oluşturma sürecini otomatikleştirmek ve bu süreçte kullanılan ya da kullanılabilecek araçlardan uzun uzun sözeden bir kaç gönderi yazmıştım. Aslında amacım CruiseControl.NET kullanarak bu süreci çalıştırmanın yöntemini anlatmaktı ve henüz CruiseControl.NET'e gelmemiştim. Ondan önce araçlardan, NAnt, Nunit, NMock, TestDriven.NET'den bahsetmiş NDoc, Simian ve benzerlerinden sözetmeye henüz zaman bulamamıştım. CruiseControl.NET ile ilgili yazımı hazırlarken yeni bir çalışmaya girdim. Bu çalışma dahilinde aynı süreci çalıştığım diğer bir ekibin ihtiyacından dolayı Java platformunda gerçekleştirmem gerekiyordu. .NET'de yaptığım çalışmalardan dolayı çok zorlanmadım diyebilirim. Java tarafında yaptığım çalışmaları ve kullandığım araçları da zaman bulur bulmaz yazmayı planıyorum. (plan plan plan :))
Ondan önce .NET tarafında çalışıp da bu konuyla ilgilenenler için bir kitap haberi vermek istiyorum. Kitabın yazarı Marc Holmes, adı ise Expert .NET Delivery Using NAnt and CruseControl.NET. Kitap, benim burada özetlemeye çalıştığım otomatikleştirme sürecini detaylarıyla ve kullanılabilecek araçlarla anlatıyor. Anlatıyor diyorum ama kitabı henüz okumadım. Ama hakkında amazon'da ve slashdot'da bir reviewda yazılanlar olumlu. Bakalım fırsat olursa okuyacağız...

spinodal tarafından 14.07.2005 tarihinde yazılmıştır.

Labels: , , ,


yazının tamamını okumak için burayı tıklayın...

Enterprise Library 1.1 June 2005

Microsoft Enterprise Library'nin yeni sürümü çıktı. Blokların genelinde bazı güncellemeler var. Bazı problemler giderilmiş ve sürüm numarası Haziran 2005 için 1.1 olmuş. Her iki sürümde aynı makinede yanyana kullanılabilir durumda ama kütüphaneleri karışık biçimde, mesela data blokunun 1.0'ını konfigürason blokunun 1.1'i ile kullanamıyorsunuz. Konfigürasyon konsolunda ufak güncellemeler var. Değişikliklerden biri de konfigürasyon blokundaki yeni depolama sağlayıcıları (storage providers): application configuration file storage provider, registry storage provider ve SQL storage provider (adları kendilerini anlatıyor zaten). Loglama blokunda da bazı önemli güncellemeler var. Bunlardan biri flat file sink'in thread safe hale getirilmesi. Data erişim blokunda da DataConnectionFailedEvent ve DataConnectionOpenedEvent sınıfları thraed safe hale getirilmiş ve tabi bunun gibi birkaç güncelleme de mevcut. Detaylar için güncelleme haberinin sayfasına bakabilirsiniz.

spinodal tarafından 09.07.2005 tarihinde yazılmıştır.

Labels: , , ,


yazının tamamını okumak için burayı tıklayın...

iPod 'lara Linux Yüklemek

Linux heryerde demek yanlış değil sanırım son zamanlarda. Çünkü ne zaman yeni bir teknoloji oyuncağı çıksa hemen ona özel bir Linux işletim sistemide peşinden geliyor. Sadece diski ve de ekranı olan herşey için Linux bulabileceğiz yakında :) Şimdi dün akşam denediğim ve başarıyla yüklediğim iPod için olan Linux dağıtımının yüklenmesinden bahsedeceğim.

iPodLinux Projesi Linux 'u iPod ortamına da taşımak için 2003 yılında başlatılan bir proje. Proje kapsamında uClinux projesinin kernelini başarıyla iPod 'a taşınmış. Apple 'ın iPod için açmadığı birçok özellik iPodLinux projesiyle kullanıcılara açılmış ve birçok da özel program yazılmış ve yazılmayada devam ediyor. Şimdi isterseniz adım adım iPod 'a nasıl Linux yükleyeceğimizi görelim.

Öncelikle bu işletim sistemini kendimin 4GB 'lık iPod a kurduğumu belirmek isterim. proje sitesinde de 1G Mini, Photo, and 4G iPod 'lara yüklenebildiğini söylüyor.

Gerekenler:
  • 4G installer

  • Eğer iPod Linux yükleyecekseniz ve tam anlamıyla son sürüm istiyorsanız buradan edinebilirsiniz. (Önerilen bu çünkü bulunan bug 'lar bu şekilde kurtulabilir ve de en son gelişmeleri bu şekilde kullanabilir hale gelebilirsiniz)


  • Çekmiş olduğunuz arşiv dosyası içinde 4 tane linux sürümü bulacaksınız. Bunlar

    -- 2005-05-27-podzilla (or nightly build)
    |__ Desteklenen ses dosyaları gerçek zamanlı olarak çalışır.
    |__ Sessiz video'lar gerçek zamanlı çalışır.

    --ipod-desktop
    |__Contrast problemi
    |__Menulerde dolaşırken klik sesleri yok.

    --mikpodzilla
    |__Ekstradan bir oyun
    |__mp3 dosyalarını çalabilir
    |__Ses modüllerini çalabilir (.mod .xm .s3m .it .mtm etc...)
    |__M4As, M4Ps, etc dosyaları için geçerli bir hareketi yok.

    --viPodzilla
    |__Daha fazla oyun ve uygulama
    |__mp3 ve m4a ses dosyalarını çalabilir.
    |____Dosya yöneticisine gidin -> hp -> iPod_Control -> Select a Folder -> mp3 seçin
    |__m4a dosyaları için geçerli ir haraketi yok.

    Benim kişisel tercihim podzilla oldu ve de şimdi adım adım podzillanın yükleme aşamasına geçelim.

    1- Öncelikle çekmiş olduğunuz arşiv dosyasını daha sonra ulaşabileceğinizi bir yere açın. (Mesela iPodLinux dizini altına açın)
    2- Arşiv dosyasını açmış olduğunuz dizin altında "iPod Linux Installer Modded" dizini bulunmalı. Bu dizini arşivi açmış olduğunuz dizinin dışına ve daha sonra ulaşabileceğiniz bir yere taşıyın.
    3- Şimdi iPod 'unuzu bilgisayarınıza bağlayın ve de "Hard Disk Usage" seçeneğini geçerli kıldığınızı ve de Bilgisayarım (My Computer) 'dan ulaşabiliyor olduğunuzdan emin olun.
    4- Arşivi açmış olduğunuz dizini ( "iPod Linux Installer Modded" dizinini dışarı çıkartmayı unutmadınız dimi? ) iPod 'unuzun ana dizinine kopyalayın.
    5- Eğer arşivin içinden çıkan podzilla dan başka bir sürüm kullanmak istiyorsanız, çekmiş olduğğunuz en son gecelik derlemeyi ismini podzilla olarak değiştirin ve gene iPod 'unuzun ana dizinine kopyalayın.
    6- Gene eğer arşivin içinden çıkan podzilla dan başka bir sürüm kullanmak istiyorsanız iPod 'unuz altına kopyaladığınız dizinin altındaki "start" isimli dosyayı iPod 'unuzun ana dizinine kopyalayınız.
    7- Şimdi bir gözden geçirme yapalım. iPod 'un ana dizininde bulunan dosyaları gözden geçirecek olursak, iPodLinux (veya siz ne isim koyduysanız) dizni, start dosyası ve de podzilla (Apple 'ın kendi dizinleri dışında olanları saydım burada) .
    8- Şimdi en başında acaba neden çıkartıyoruz diye uzun uzun düşünmüş olduğunuz "iPod Linux Installer Modded" klasörünün içine gidin ve de “ipodlinux-installer.exe” dosyasını çalıştırın. Önünüze çok çok kolaylaştırılmış bir arayüz çıkacaktır ve Linux 'u burdan yükleyebileceksiniz.
    9- “Check for Updates.” seçeneğini seçili halde ise seçili değil hale getirin. ve "Next" tuşuna basın.
    10- Şimdi ise hani işletim sisteminin asıl işletim sistemi olarak yüklenmesini istediğinizi seçin. Ben tarafından ve internette bulmuş olduğum birkaç site tarafından daha Apple firmware ini default olarak seçmeniniz öneriliyor.
    11- “Make a Backup” seçeneğinin seçili olduğundan emin olun.
    12- Ekrandaki durum çubuğu dolduğunda next tuşuna basın ve de iPodLinux 'un yüklenmesine başlayın. (Bu seçenek “Make a Backup” seçeneğini seçenler için geçerli. Seçmeyenler bu şıkkı atlayabilir)
    13- İşlem bittiğinde iPod 'unuzu bilgisayardan ayırın.
    14- Apple OS 'i asıl işletim sistemi seçtiyseniz ilk olarak o açılacaktır. Apple logosunu gördükten hemen sonra "Rewind" tuşuna basılıt tutun yada "hold" tuşunu birkaç kere açıp kapatın (bu yazıyı yazarken ben bu 2.yi denemediğimi farkettim. Ama ilk seçenek çalışıyor) . Apple logosundan sonra Tux logosunuda görüceksiniz.
    15- Şimdi ekrandan akan yazılar olucak ve de tataa. Artık Linux yüklü bir iPod 'unuz var. Hepsi bu kadar. Ekranın biraz karanlık olduğunu farkediceksiniz. Işıklı biryere gidip contrast özelliğiyle oynayarak ekranı düzgün bir hale getirebilirsiniz.

    Not: Eğer iPod 'unuzda video seyretmek istiyorsanız, videoları iPod 'unuz altında geçerli bir dizine kopyalayın ve de dosya yöneticisiyle (nam-ı değer filebrowser) video dosyasını seçin. VideoPlayer yeni geliştirilen bir proje olduğu için tüm video formatlarını çalamayabilir. Video Player 'ı buradan bulabilirsiniz.

    Linux 'unuzu iPod 'unuzda güle güle kullanın :)


    randomHero tarafından 08.07.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Ray Kurzweil 'in 2002-2003 Makaleleri

    Ray Kurzweil; optik karakter tanıma (optical character recognition (OCR)), yazıdan-sese sentezi, ses tanıma teknolojileri, ve elektronik müzik klavyeleri konularında günmüzde öncü olan kişidir. Ve Ray Kurzweil 2002-2003 yılları arasında yayınlamış olduğu sanal gerçeklik, yapay zeka, radikal hayat uzatma, bilinçli makinalar, gelecek vaat eden ve tehlikeli teknolojiler, ve gelecek dünyamızın diğer bakış açıları hakkında yazmış olduğu makaleleri toplu halde KurzweilAI sitesinde yayınladı. Gerçekten çok ilginç olan bu makaleler (yaklaşık 30 adet) 7 konu başlığı altında toplanmış. Gerçekten çok ilginç ve gerçekten çok zihin açıcı yazılar. Herkese önerilir.

    Makalelere buradan ulaşabilirsiniz. Ray Kurzweil hakkında daha geniş bilgiye de bu adresteki WiKi sayfasından ulaşabilirsiniz. Ayrıca Kurzweil Technologies Companies sitesinden Ray Kurzweil 'in yaptığı işler hakkında daha geniş bilgi alabilirsiniz.

    İyi okumalar...

    randomHero tarafından 05.07.2005 tarihinde yazılmıştır.

    Labels: ,


    yazının tamamını okumak için burayı tıklayın...

    Türkçe I ve .NET 2.0

    Burada da değindiğimiz hakikaten başağrıtan bir sorun var: "Türkçe I". Microsoft'un .NET 2.0'da String kullanmak üzerine yeni önerilerini içeren bir makalesi yayınlandı. Bu yenilikler için ana nedenlerden birinin bahsettiğimiz "Türkçe I" problemi olması ilginç. Altbaşlıklardan biri şöyle:
    The Motivation: The Turkish-I Problem

    Makaleye şu adresten ulaşabilirsiniz...

    Not: Hayır, hayır ölmedik. Yakında daha seri bir biçimde döneceğiz... :)

    spinodal tarafından 04.07.2005 tarihinde yazılmıştır.

    Labels: ,


    yazının tamamını okumak için burayı tıklayın...

    Web'de tıklamadan gezinebilir miyiz?

    Arayüz içeriğinde gezinmek için farenin düğmelerini tıklamak en iyi yöntem mi? Tıklama alışkanlığımızdan kurtulmamız gerekse bunu ne kadar kolay/zor başarabiliriz? Böyle bir değişim iyi mi olur kötü mü? Tıklamanın yerine geçecek neler yapılabilir? vs. vs. Bu soruları kafaya takan Institute For Interactive Research (?) ekibi dontclick.it isimli bir site hazırlamışlar. Sitede gezinmek için tıklamanız gerekmiyor hatta tıklamamanız gerekiyor. Bence çok ilginç bir çalışma. Gerçi bir yandan web standartları,erişilebilirlik derken bir yandan bunu yazmak garip oldu ama... Bence dikkate değer.

    spinodal tarafından 17.06.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    Web Standartları hakkında Türkçe kaynak

    Bu siteye başlarken “nelerden yazarız?” diye düşünmüştük. Web Standartları konusuna o zamanlarda da meraklıydım helen de meraklıyım. Bu konuda da yazarız diye konuşmuştuk ama şu ana kadar sitede bu konuda ortaya birşey koyamadık. Şöyle bir derdim var: Sürekli bu konuda okuyor, ilgili siteleri takip ediyorum; zaman buldukça okuduklarımı deniyorum, ancak ortaya koyduğum “işte bu siteyi de ben yaptım, tasarımı ve herşeyiyle benim ürünüm ve tümüyle web standartları gözetilerek oluşturuldu” ya da “bu wordpress temasını ben yarattım” diyebileceğim somut bir ürünüm yok. Bir türlü de olamıyor (nedense!). Ben de “tamam o zaman, teorikten devam” dedim ve bence çok güzel bir araya toplanmış bilgi ve bağlantılardan oluşan Roger Johansson’un Developing With Web Standards makalesini Türkçe’ye çevirdim. Böylece bu konuyla ilgilenmek isteyenlere başlangıç olabilecek Türkçe bir döküman ortaya çıkmış oldu. Umarım faydası olur.

    Çeviriye doğrudan sitedeki sayfasından erişebilirsiniz. Ayrıca Roger Johansson da kendi sitesinde makalenin Türkçe çevirisini yayınladı. İkincisi kaynağıyla aynı stilde olduğundan okumaya daha elverişli.

    Çeviri hakkında eleştiri, düzelti veya görüş belirtmekten lütfen çekinmeyin. Sizin katkılarınızla daha doğru bir kaynak olacaktır.

    spinodal tarafından 15.06.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Neden NAnt kullanayım ki?

    NAnt kullanıcıları e-posta listesine birisi, uzun zamandır NAnt kullandığını ve çok mutlu olduğunu ancak çalıştığı kurumdan kendisine neden Visual Studio.NET ile değil de NAnt ile oluşturma yaptığını ve bunu kurumun standardı yapmaya çalıştığını sorduklarında yöneticilerine ne cevap vereceğini bilemediğini yazmış. Sanırım doğru yaptığını biliyor ama nedenini tam açıklayamıyor. Diğer kullanıcıların verdikleri cevapları toparlamaya çalıştım. Aşağıda bulabilirsiniz:


    • Birim testleri çalıştırma ve otomatikleştirme.

    • Her geliştiricinin kendi makinesinde oluşturma yapmasındansa merkezi oluşturma, yani güncel olmayan birşeyleri test etme veya üretim ortamına çıkarma gibi sorunlardan sakınma.

    • Günlük sürüm çıkma işlemini gerçekten günlük yapma.

    • Oluşturma işlemini tek adımda yapma.

    • Oluşturma sürecinin herkes için aynı olması ve birilerinin kafasındaki gizli bir bilgiye bağımlı olmaması.

    • FxCop, NUnit, NCover, Simian, Vil vs. gibi birçok aracı birarada kullanabilme. (NUnit'den sözettik, diğerleri de yolda)

    • VS.NET referansları çözümlemek için proj dosyalarında tüyolu adresler kullanır. Biryerde olduğunu düşündüğü kütüphaneyi bulamadığında hemen hata vermek yerine benzer başka adreslerde arar ve bulursa haberiniz olmaz. Bu yüzden VS.NET ile oluşturma yapmak çok da güvenli değildir.

    • Oluşturma yapılan ortam kurulumun yapılacağı ortam gibi VS.NET'in olmadığı bir yer olmalıdır.

    • Birkaç solution'a bölünmüş büyük bir projede oluşturmanın hepsi için ayrı ayrı ve belirli bir sırayla yapılması gerekir. Bunu dökümante etmeli ya da hep hatırlamalısınız. Oysa NAnt ile...

    • Standart dağıtım, yani tekrarlanabilir, istendiği an yapılabilir ve garantili...

    • Microsoft şimdiye kadar hiç Visual Stuido ile oluşturma yapmamıştır ve yapmayacaktır. Bir Microsoft danışmanının söylediğine göre bunun nedeni Visual Studio'nun kurumsal oluşturma ortamları için tasarlanmamış olmasıdır. Zira Microsoft birçok yönden NAnt'a benzeyen MSBuild'i yazmıştır.

    • Veritabanı oluşturma işlemleri de sql betiklerini çalıştıran NAnt targetları ile yapılabilir.

    • Son olarak, zaten VS.NET oluşturma sürecinin sadece derleme ayağını yapmaktadır. Oluşturma sürecinin derleme dışında bir çok adımı vardır ki bunu da NAnt gibi bir araçla yapabilirsiniz.

    • Bir de şöyle bir kitap var. Pragmatic Project Automation: How to Build, Deploy, and Monitor Java Applications. Gerçi kitap Java'yı ele alıyor ama konu aynı konu.


    • Bence güzel liste oldu ve hayali kahramanımız Selçuk'un diğer hayali kahramanımız Emre'nin "Neden NAnt kullanayım ki?" sorusuna verdiği yanıt pekişmiş oldu.


    Not: Tartışmanın tümü için NAnt kullanıcı forumlarında ilgili başlığa bakabilirsiniz. Toparlamada eksiğim veya yanlışım varsa pardon.

    spinodal tarafından 07.06.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Websphere'da Türkçe Problemi Silsilesi Vol.I

    Bu hatanın gerçekleştiği zaman açıkcası bu tip bir problemden gerçekleşeceği aklıma gelmemişti. Öncelikle problemin ortamını biraz açıklayayım.
    Application Server: WAS 5.1.1.1
    Client Server: WSAD Test Server 5.1
    Server JDK : JDK 1.4.2_04
    Client JDK : JDK 1.4.2_04

    Serverda yüklenmiş EJB projesinin WSAD'da EJBClient jar'ı da client server üzerinde bulunmakta. Herşey güzel ve herşey düzgün giderken birden alınan bir hata moralleri bozar. "Unable to read value from underlying bridge : null" hatanın devamında server makinasının IP si bulunmaktatdır, bu da bağlanmak istediği yerin doğru olduğunu gösteriyor... Fakat server'ın loglarında hiç bir yansıma yok. Yani client server'a ulaşamıyor. Biraz uğraştıktan sonra problemi çözdük. Problem ne serverda ne de client applicationda. Problem server makinanısın network ismi içinde bulunan 'I' harfi. yani meşhur Türkçe karakter problemi... client'ın üzerinde çalıştığı makinada lokal ayarlar türkçeye göre ayarlı. Client networkte IP'den server'ın ismini çözümlüyor. Networkten makinanın ismini büyük harfli şekilde çözümlüyor. Yani isim "IXXXX" gibi birşey oluyor. Daha sonra ise bu ismi küçük harfe dönüştürüyor ve problem gerçekleşmiş oluyor. İsim "ixxxx" yerine "ıxxxx" e dönüşüyor. Ve network de doğal olarak bu ismi tanımıyor.
    Çözüm1: Client makinanın lokal ayarlarını ingilizce olarak ayarlayın.
    Çözüm2: Server makinasının ismi içinde 'I' harfini kullanmayın. (Aynı problem 'i' harfi içinde geçerli)
    Çözüm3: Bu türkçe karakter problemine çözüm bulun :) Hepimiz mutlu olalım...

    randomHero tarafından 25.05.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    NAnt ve dasBlog Türkçe problemli mi?

    Nedir bu i harfinden çektiğimiz arkadaşlar!

    Bugün aldığım ders şu, yeni indirdiğiniz kurduğunuz bir yazılım sizin PC'nizde çalışmıyorsa kesinlikle ilk yapmanız gereken kullandığınız dosyaların adında, içinde, sağında, solunda I-İ sorunu olabilecek bir durum var mı kontrol edin. Maalesef diğer dillerin aksine güzel Türkçemizde ı ve i harflerinin büyük yazımı ters. Bu da bizi her fırsatta ters köşeye yatırıyor. İşte bu azizliğin kurbanı ürünler :

    NAnt : Derleme için oluşturduğunuz fileset copy taskları sanki hiçbirşey yokmuş gibi mi yapıyor? Muhtemelen dosya yolunda ve/veya dosyaadında büyük I kullanmışsınız demektir. Bu harfi düzeltin çalışmaya devam edin.
    Bu bug'ı ve çözüm önerimizi NAnt'ın sitesine post ettik yakın zamanda düzeleceğini de müjdeleyeyim. Sorunun kaynağı ise tüm NAnt'ta dosya yollarının ve adlarının ToLower() yapıldıktan sonra kullanılıyor olması. Bunu ToLower metodlarını diğer override'ı olan ToLower(System.Globalization.CultureInfo.CurrentUICulture) ile değiştirerek çözmek mümkün. Aslında bu FxCop'ta kontrol edilen bir kural, eğer bir metodun CultureInfo verilebilen bir override'ı varsa bunu kullanmanız gerekiyor. Ama FxCop da o kadar çok hata buluyor ki kardeşim yaa :)

    dasBlog : Bu çok daha ilginç bir durum, eğer Internet Explorer'ınızın diller kutusunda(Internet options->Languages) en üst sırada Türkçe yer alıyorsa dasBlog ile hazırlanmış bir blogda hiçbir post göremeyeceksiniz. Bu dasBlog'un sitesindeki öncelikli bug'lardan biri. Nedeni ise dasBlog'un şablonları işlerken şablonların içindeki anahtar sözcükleri Reflection kullanarak bazı nesnelerin üyelerine eşlemesi. Tabi ki tahmin edersiniz, bu üyelerden bazıları i harfiyle başlıyor.(items, itemtitle ...). Fakat bunu çözmek daha zor çünkü bu keywordler upper yaparsanız i ile başlayan hepsi kurtuluyor ancak post başlığı itemtitle bu sefer ikinci i'den takımı yatırıyor ve başlıksız postlarınız oluyor. Bunun için iki duruma iki öneri var;
      1. dasBlog sitelerini ziyaret eden bir Türkseniz explorer'ınızın diller bölümünde ilk sıraya ingilizceyi koyun.

      2. dasBlog sitesi sahibiyseniz ve Türk ziyaretçiler postlarınızı okuyamadığı için başınızı ağrıtıyorsa dasBlog\themes\[yourTheme]\ klasöründeki ItemTemplate.blogtemplate ve DayTemplate.blogtemplate dosyalarının içindeki "item" sözcüklerini "Item" olarak değiştirin.


    Bu konuda Microsoft'un Globalizasyon konusunda teknik liderlerinden Michael Kaplan da aydınlatıcı (ingilizce) bir yazı yazmış. O da Almanca'nın kurbanı...
    Herneyse umarım bu yazı ile siz benim kadar sinir hasarı almadan bu sorunu atlatırsınız.

    NOT : Chemical Brothers geliyooooooor !!!

    bioLogic tarafından 24.05.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    My Google

    Google yine boş durmamış. Geçen gün sözünü ettiğim Arama Geçmişi/My Search History olayından sonra yine Google Hesabı/Google Account ile bütünleşik olarak My Google kavramını geliştirmişler. http://www.google.com/ig veya http://www.google.com.tr/ig adreslerinden ulaşılan ve henüz beta olan bu kavramda Google arama sayfasını kişiselleştirebiliyorsunuz. GMail, Google News, Slashdot, Wired News vs.. gibi 12 adet küçük pencere ekleyebiliyorsunuz arama sayfanıza. Tabii oturum açmanız gerekiyor. Bu işin nereye doğru götürecekler bakalım...

    spinodal tarafından 24.05.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Birim test; NUnit, NMock ve TestDriven.Net

    Emre: Uzun zamandır görünmüyorsun. Neler yaptın bu arada?

    Selçuk: Sana bahsettiğim otomatik oluşturma sürecini yerleştirmeye çalışıyorduk ekip olarak. O zaman da bahsetmiştim, bu işi CruiseControl.NET ile yapıyoruz. Biliyorum detayına girmedim ama gireceğim.

    E: Onun dışında birşeyler yok mu?

    S: Evet var tabi. 25-27 Mayıs tarihlerinde Microsoft Yazılımcılar Zirvesi oldu, duymuşsundur. Oradaydık. Biz açık kaynak kodlu uygulamalar ile otomatik oluşturma süreci ile uğraşırken (ki dünya da birçok ekip de benzer yöntemlerle çalışıyor) Microsoft Visual Studio Team System ile bu işi bir çatı altında toplamış. En geç 2005 Aralık'da çıkacağı söyleniyor. Ama ben Team System çıkana kadar sana sürecin her parçasından tek tek bahsetmiş olurum. Böylece, Team System'i kullanmaya başlarsan onu çok daha verimli kullanabilirsin. Neyse, henüz beta 2 seviyesinde olan Team system'in detaylarından bir ara yine konuşuruz ya da istersen şu adresten gelişmeleri takip edebilirsin. Şimdi, görüşmemizi sen ayarladığına göre sen sor ben anlatayım?

    E: Geçen konuşmamızda sen NAnt'tan sözederken konuşmanın arasında birim test konusu da kısaca geçmişti. Biraz şu birim test olayından bahsetsene.

    S: Öncelikle birim test nedir ondan bahsedelim. Birim test, bir yazılım geliştirici tarafından yazılan ve test edilmekte olan kodun işlevselliğinin çok küçük ve belirli bir alanını deneyen kod parçasıdır. Yani, yazdığın kodun doğru çalıştığından emin olmak için yazdığın kod. Test kelimesi, birim test konusuyla ilk karşılaşan yazılımcılarda (ki ne yazık ki hala oldukça çok sayıdalar) yanlış anlamaya neden olabiliyor. Bunu performans, yük, sistem ya da kullanıcı kabul testleri ile karıştırmamalısın. Birim test sadece yazdığın metodların, onlardan yapmalarını beklediğin şeyi yaptıklarından emin olmak için yazdığın kod parçasıdır. Birim test yazmak, bugların azalmasını, yazılım geliştiren ekibin daha basit ve daha okunur kod yazmasını, refactoring işlemlerinin kolaylaşmasını ve geliştirme ekibi içinde oluşturma sürecinin güven içinde yapılmasını sağlar. Birim test yazma konusunda bir çok framework bulunmakta. Bunların birçoğunun atası Kent Beck tarafından geliştirilen XUnit framework'ü. XUnit framework'ü yanılmıyorsam Smalltalk ile yazılmış ancak Kent Beck daha sonra Erich Gamma ile birlikte onu Java'ya taşımış ve JUnit doğmuş. Ardınan birçok dil için benzer frameworkler yazılmış. İşte bu da bizi .NET için varolan toruna, yani NUnit'e getiriyor. NUnit de XUnit'in torunlarından ama 2.2 sürümüne gelmiş olan bu framework oldukça büyük değişimlerden geçerek .NET altyapısına tamamıyla uyum sağlamış.

    E: Şimdi sen NUnit anlatmaya başlayacaksın ama, benim aklım henüz bu birim test işine yatmadı ki NUnit dinleyeyim. Yanlış anlamadıysam yazdığım kodu yine yazdığım kodla test ediyorum. Bir dakika, bir dakika... Nasıl ya?

    S: Aslında bunu yazılım geliştirme dünyası çok çok uzun yıllardır yapıyor. Hatta nasıl yazılmalı, ne kadar yazılmalı tartışmları biteli bile çok olmuş. Test Driven Development denilen yöntemle daha da ileri gidilerek kod yazmadan önce birim testleri yazman öneriliyor desem bakalım ne diyeceksin. Tamam, tamam. Hepimizin böyle çalışması gerekmiyor. Öncelikle yapılması gereken ortaya çıkacak yazılımın kalitesine karar vermek ve böylece birim test yazma stratejisini belirlemek. Daha sonra birim testlerin gerçek kodun ne kadarını kapsadığında (coverage) yeterli olduğuna karar vermek yeterli olacaktır. Birçok yazılımcı test yazmanın zorluğundan, kodlarının test yazmayı geektirmeyecek kadar basit olduğundan ya da test yazmakla harcayacak zamanı olmadığından dem vurur ve test yazmaktan kaçar. Bu doğal bir tepkidir çünkü farklı bir yöntemle kod yazmaya alışmış biri için birim test yazmaya alışmak çok zorlu bir süreçtir. Yazmaya başladıkça alışacaksın ama sana yol gösterecek birçok kaynak bulmakta zorlanmayacağına da eminim. Benim hoşuma giden bir kaynak Robert C. MArtin'in The Craftsman serisinin ilk birkaç parçasıdır. Neyse şimdi bahsettiğimiz bu birim testleri yazmak için kullandığımız altyapıya yani NUnit'e gelelim.

    E: Evet, zaten olayı anlamaya başlıyorum galiba. Ama ben yine de detaylı bir araştırma yaparım. Google ne güne duruyor? Sen devam et.

    S: Öncelikle download adresinden NUnit'i indirmelisin. Ben sana bunları anlatırken tutarlı sürümü 2.2.0. Nunit'i kullanmanın iki yöntemi var biri komut satırından (nunit-console.exe) diğeri ise grafik kullanıcı arabirimi (nunit-gui.exe) ile. Bizim gibi testleri otomatik oluşturma aşamasında entegrasyon amaçlı kullanacaksan komut satırında çalışanı kullanacaksın demektir. Grafik arayüzlü olanında, testler bir ağaç yapısında görünüyorlar ve istediğin testi seçip çalıştırıyorsun. Herneyse şimdi test yazma işine geçelim. Öncelikle projende nunit.framework.dll kütüphanesine referans vermelisin. Ardından testleri içeren sınıfa [TestFixture] özelliğini (attribute) ekleyeceksin. Tabi bu sınıf public olmalı ve varsayılan constructor'ı bulunmalı. Sonra bu sınıfın içinde test olarak çalışacak metodlarının başına [Test] özelliğini ekleyeceksin. Bu metodlar kesinlikle public void imzalı olmalı ve parametre almamalılar. TestFixture olan bu sınıfta çalışacak testler için bir ortam yaratmak isteyebilirsin. Bunun için her test metodu çalışmadan önce çalışan bir [SetUp] metodu ile testler çalıştıktan sonra çalışacak bir [TearDown] metodu yazabilirsin. Yazdığın test metodlarından bazılarının Exception atmalarını bekliyor olacaksın, o zaman [ExpectedException] özelliğini kullanmalısın. Yine metodun başına [ExpectedException(BekledigimException)] yazmalısın. Bu özellik içine beklenen exception türünü alıyor dikkat edersen. Bu şu anlama geliyor, bu test çalıştığından ExpectedException'a parametre olarak verdiğin hata atılıyorsa test başarılı sonuçlandı, yok öyle bir hata atılmadı ise test başarısız oldu. Ayrıca testlerini [Category("GuzelKategori")] yöntemi ile kategorilere de dahil edebilirsin.

    E: Böyle birşeye neden ihtiyacım olur ki?

    S: Böylece bir TestFixture'ı çalıştırırken içinden bazılarını çalıştırmamayı seçebilirisin. Bunu komut satırında /include ya da /exclude argümanları, grafik arabirimde ise Categories sekmesi aracılığıyla yapabilirsin. Bir Test'in başlangıcında [Ignore("Bu testi atla,cunku su bu")] kullanarak o Test'in çalışmamasını da sağlamak mümkün. Ignore'a verdiğin string sonuçlar raporlanırken bu Test'in neden atlandığını belirtirken kullanılır. Bazen geçici olarak bir veya birkaç test dışındakileri çalıştırmak isteyebilrisin, bu tip durumlarda o kısımları yorum satırına çevirmektense bu yöntemi kullanmak daha makul görünüyor.

    E: ExpectedException durumu hariç bir testin ne zaman başarılı ne zaman başarısız olduğu durumundan bahsetmeyecek misin?

    S: Tabi ya, en elzem kısmı atladım değil mi? İşte bunu Assertion'lar yani teyit komutları aracılığıyla yapıyorsun. Teyit komutları karşılaştırmalar, koşul testleri ve emirler biçiminde üç grupta düşünülebilir. Karşılaştırmalar AreEqual ve AreSame, koşul testleri IsFalse, IsNull, IsNotNull ve IsTrue, emirler ise Fail ve Ignore'dur. Bunları Assert.IsNull(object birObje) gibi kullanıyorsun. Diğer kullanımları için intellisense ve dökümanlardan faydalanabilirsin.

    E: Diğerlerini anladım da AreEqual ile AreSame arasındaki fark ne?

    S: AreSame(object birObje, object digerObje) birObje ile digerObje'nin aynı obje olup olmadığını kontrol ediyor. Yani her iki argümanın da aynı objeye referans olup olmadığını. AreEqual(object beklenen, object gelen) ise beklenen ile gelen objelerin eşitliklerini kontrol ediyor. Örneğin AreEqual(7, 7.0) true döner. İşte hepsi bu kadar. İstersen küçük bir örnek yazayım anlattıklarımaışık tutsun. Şöyle garip bir sınıf olduğunu düşün...

    public class Sicaklik
    {
    private Decimal _selsiyus=27;
    private Decimal _fahrenayt=80;

    public Decimal Selsiyus
    {
    get{return _selsiyus;}
    set{_selsiyus=value;}
    }

    public Decimal Fahrenayt
    {
    get{return _fahrenayt;}
    set{_fahrenayt=value;}
    }

    public void SelsiyustanFahrenaytaDonustur()
    {
    _fahrenayt = ((_selsiyus*9)/5)+32;
    }
    public void FahrenayttanSelsiyusaDonustur()
    {
    _selsiyus = ((_fahrenayt-32)*5)/9;
    }
    }

    Şimdi de testlerine bakalım.

    [TestFixture]
    public class TestEdelim
    {
    public TestEdelim(){}
    private Sicaklik sic;

    [SetUp]
    public void Baslangic()
    {
    sic = new Sicaklik();
    }

    [Test]
    [Category("KategoriOrnegi")]
    public void SelsiyustanFahrenayta()
    {
    sic.Selsiyus = 37;
    sic.SelsiyustanFahrenaytaDonustur();
    Assert.AreEqual(98.6, sic.Fahrenayt,"Fahrenayta dönüştürmede hata!");
    }

    [Test]
    [Category("BirBaskaKategoriOrnegi")]
    public void FahrenayttanSelsiyusa()
    {
    sic.Fahrenayt = 98.6M;
    sic.FahrenayttanSelsiyusaDonustur();
    Assert.AreEqual(37, sic.Selsiyus,"Selsiyusa dönüştürmede hata!");
    }
    }

    Yo yo, dur bir dakika bir şeyi atlıyorum. Bazen test yazmak daha da zor olabilir. Örneğin bazen test edeceğin sınıf birden fazla sayıda alt sistemle etkileşimde olabilir. Birim olarak test edebilmek için sınıfı soyutlaman gerekir. O zaman gereken sınıf bağımlılıklarını yaratmak için taklit nesneler kullanman gerekir. Bu taklit nesneler arayüzleri taklit etmek için kullanılırlar. Yaratılan bu nesnelere İngilizce'de sahte, taklit anlamına gelen Mock deniyor. Bu taklit nesneleri yaratmak için hazır araçlar mevcut. Bunlar, bağımlı olunan sınıfların taklit implemantasyonlarını oluşturan statik araçlar ve taklit implemantasyonları runtime'da oluşturan dinamik araçlar olarak iki grupta düşünülebilir. Dinamik olanları kullanmak daha kolay olduğundan ve fazladan sınıflar oluşturmadıklarından daha çok tercih ediliyorlar. .NET için NMock ve DotNetMock'dan bahsedilebilir. Biz NMock'u kullanıyoruz.

    E: Bir dakika ya. Anlayamadım.

    S: Bir örnek versem daha netleşecek sanırım. Diyelim ki şöyle bir interface'in var:


    public interface IKopek
    {
    string Ad { get; }
    }

    Ve diyelim ki Yakala isimli bir metodu olan Komut isimli bir sınıfın olsun:

    public class Komut
    {
    IKopek kopek;

    public Komut(IKopek kopek)
    {
    this.kopek = kopek;
    }

    public String Yakala()
    {
    return "Yakala " + kopek.Ad;
    }
    }

    Görüdüğün gibi Komut satırı IKopek'e bağımlı. Şimdi öncelikle taklit etmek istediğimiz interface'in ya da sınıfın tipini vererek taklit nesneyi başlatacağız. Daha sonra nasıl davranacağını belirtip taklitin çalışan bir kopyasını yaratacağız. Son olarak da taklit nesnenin Verify() metodunu çağıracağız.

    IMock mockKopek = new DynamicMock(typeof(IKopek)); // taklitini istediğimiz interface budur diyoruz
    mockKopek.ExpectAndReturn("Ad","Çomar"); // davranışını belirtmeden işimize yaramaz
    IKopek kopek = (IKopek)mockKopek.MockInstance; // takliti başlatıyoruz
    mockKopek .Verify();

    Burda bir örneğini gördüğün Expect metodlarından NMock bünyesinde yeteri kadar var. Dolayısı ile taklit nesnenin davranışını detayıyla tanımlayabiliyorsun. Expect(string metodAdi, object[] args), ExpectAndReturn(string metodAdi, object donusDeger, object[] args), ExpectAndThrow(string metodAdi, Exception hata, object[] args) ve ExpectNoCall(string metodAdi).
    Şimdi de bunu bir test içinde nasıl kullandığına bakalım.

    [TestFixture]
    public class KomutTesti
    {
    [Test]
    public void Testtest()
    {
    IMock mockKopek = new DynamicMock(typeof(IKopek));
    mockKopek.ExpectAndReturn("Ad","Çomar");

    Komut komut = new Komut((IKopek) mockKopek.MockInstance);
    Assert.AreEqual("Yakala Çomar", komut.Yakala());

    mockKopek.Verify();
    }
    }


    E: Sanırım NMock olayını anladım. Saol ya. İyi oluyor böyle örnekli felan. Ben NUnit'e dönüp birşey soracam. Bu NUnit'i Visual Studio.NET içinden çalıştırmak mümkün mü?

    S: Bunu soracağını tahmin ediyordum ama beklediğimden geç sordun. Cevabım evet. Visual Studio ile kullanmak için TestDriven.Net isimli Visual Studio.NET eklentisini kurabilirsin. Bu eklentiyi kurduğunda Visual Studio.NET içinde Solution Explorer'da sınıflara sağ tıkladığında açılan menüde Debugger ve NUnit GUI komutlarını içeren Test with... alt menüsü ekleniyor. Bu komutlar aracılığıyla NUnit'i çağırabiliyorsun.

    E: Sağol abi yaa. Bunca bilgiden sonra bana gidip bunları iyice kurcalamak kalıyor. Teşekkürler. Ama bir daha arayı bu kadar uzatmayalım. Kendine iyi bak...

    S: Kal sağlıcakla...


    spinodal tarafından 23.05.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Java'da Yüksek Performanslı Dosya Kopyalama

    Yakın zamanda uğraştığım bir projede Java'da dosyadan dosyaya kopyalamaya işi yapmam gerekti ve internette biraz bakınmaya karar verdim. Genel olarak aşağıdaki gibi benim de klasik olarak düşünceğim şekilde işlemler vardı...



    public static void copyFile(File source, File dest) throws IOException
    {
    if(!dest.exists())
    {
    dest.createNewFile();
    }
    InputStream in = null;
    OutputStream out = null;
    try
    {
    in = new new FileInputStream(source);
    out = new FileOutputStream(dest);
    // Transfer bytes from in to out
    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0)
    {
    out.write(buf, 0, len);
    }
    }
    finally
    {
    if(in != null)
    {
    in.close();
    }
    if(out != null)
    {
    out.close();
    }
    }
    }


    Ama bunda daha iyisi olmalı diye düşünmeye de bir yandan başladım. Bu sırada FileChannel isimli class la karşılaştım ve kullanılabileceğini düşündüm. Ve ortaya yukarıdakinden daha performanslı bir kod parçasını kullanabileceğimle ilgili bir kaynak çıktı. İşte ortaya çıkan kod parçacığı:



    public static void copyFile(File sourceFile, File destFile) throws IOException
    {
    if(!destFile.exists())
    {
    destFile.createNewFile();
    }
    FileChannel source = null;
    FileChannel destination = null;
    try
    {
    source = new FileInputStream(sourceFile).getChannel();
    destination = new FileOutputStream(destFile).getChannel();
    destination.transferFrom(source, 0, source.size());
    }
    finally
    {
    if(source != null)
    {
    source.close();
    }
    if(destination != null)
    {
    destination.close();
    }
    }


    Bu tip küçük kod kolaylıkları ile ilgi yazamaya devam edeceğim... Merakla bekleyiniz..


    randomHero tarafından 10.05.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Eğlence için kod yazanlara

    Microsoft, MSDN içinde, eğlencesine kod yazanlar için Coding4Fun isimli bir site açmış. Amaç eğlence için kod yazanlara .NET 2.0 kullanarak nasıl oyun, sesli ve görüntülü uygulamalar ve diğer kişisel kullanım araçları yazılabileceğini göstermek. Sitede makaleler ve kısa yazılar yer alacak. Örneğin .NET framework ve DirectX kullanarak oyun geliştirmekle ilgili bir makale dizisi başladı: Beginning Game Development. RandomHero'ya duyrulur...

    spinodal tarafından 28.04.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    Eclipse de JUnit ant taskini çalıştırmak...

    Eğer Eclipse içinde entegre şekilde gelen Ant aracı içinden JUnit task'ini çağırmak isterseniz muhtemelen hoşunuza gitmicek bir kötü bir mesajla karşılacaksınız:


    BUILD FAILED:
    [ECLIPSE_DIR]\workspace\[PROJECT_DIR]\build.xml:208:
    Could not create task or type of type: junit.

    Ant could not find the task or a class this task
    relies upon.

    This is common and has a number of causes; the usual
    solutions are to read the manual pages then download
    and
    install needed JAR files, or fix the build file:
    - You have misspelt 'junit'.
    Fix: check your spelling.
    - The task needs an external JAR file to execute
    and this is not found at the right place in the
    classpath.
    Fix: check the documentation for dependencies.
    Fix: declare the task.
    - The task is an Ant optional task and optional.jar is
    absent
    Fix: look for optional.jar in ANT_HOME/lib, download
    if needed
    - The task was not built into optional.jar as
    dependent
    libraries were not found at build time.
    Fix: look in the JAR to verify, then rebuild with the
    needed
    libraries, or download a release version from
    apache.org
    - The build file was written for a later version of
    Ant
    Fix: upgrade to at least the latest release version of
    Ant
    - The task is not an Ant core or optional task
    and needs to be declared using .

    Remember that for JAR files to be visible to Ant tasks
    implemented
    in ANT_HOME/lib, the files must be in the same
    directory or on the
    classpath

    Please neither file bug reports on this problem, nor
    email the
    Ant mailing lists, until all of these causes have been
    explored,
    as this is not an Ant bug.


    JUnit; Ant içinde Optional Tasks diye geçen standart Task'leri dışında daha sonra eklenmiş ekstra task'lerden biridir. Bu hata da Ant'ın bu ekstra taskler için yazılmış olan kodu bulamadığı zaman attığı standart hatadır. Ant bu ekstra task'ler için desteğe sahiptir ama asıl işi yapan kodu içermemektedir. Yani Ant JUnit taskini içinde içerir durumda ama JUnit'in kendisini değil.. (bu da doğal olanı zaten). Eğer Eclipse 3.x kullanıyorsanız ve içinden gelen standart Ant'i kullanıyorsanız, Eclipse içinde JUnit taskinin bulunduğunu /plugins/org.apache.ant_{version}/lib dizini altında, yok eğer başka bir ant sürümü kullanıyorsanız /lib altında ant-junit.jar dosyasının varlığından kontrol edebilirsiniz. Eğer bu dosya bulunuyorsa Ant içinde JUnit taski desteğiyle gelmiş demektir. O zaman tek eksiğiniz JUnit in kendi jar'ı. JUnit'in güncel bir versyonunu burdan yada burdan indirebilirsiniz.
    Şimdi ise sonun çözümüne gelelim. Sorun Ant'ın JUnit'i görmemesi olduğu için Eclipse içinde JUnit jar'ını Ant e göstermemiz gerekiyor. Bunun en basit yoluda Eclipse içinde Window --> Preferences, Ant --> Runtime bölümüne gidip. Classpath sekmesinden Global Entries'e tıklatıp Add External JARs butonuna basarak eklemek.... Deminde söylediğim gibi Eclipse içinde zaten Junit içermekte. /plugins/org.junit_xxx (xxx versyon numarası, Eclise 3.x ile birlikte junit_3.8.1 gelmekte) dizininde junit.jar'ı seçtikten sonra Ant task'iyle ne yapıcağını bilicektir :)


    randomHero tarafından 22.04.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    Oyun Programlamaya Giriş 1

    Etrafta uçuşan bombalar, vızır vızır geçen mermiler arasında yol bulmaya çalışmak, otobanda ters yönde son sürat bir Ferrari kullanmak, sahalara inip inanılmaz goller atmak yada sakin bir göl kıyısında elde olta balık peşinde koşmak. Bu söylediklerim çok mu zor? Peki bombardıman altında ters yönde bir Ferrari'yle son sürat karşı kaleye doğru top sürmek? Daha mı uçuk? Bence sadece hayal gücüyle sınırlı bir dünyanın içinde yapılabilinecek ufak bir iki numaradan ibaret.

    1952 de A.S. Douglas ilk grafik tabanlı TicTacToe'yu yazıldığında sanırım bu kadarını hayal etmemişlerdi. Şimdi ise etrafımız grafik canavarı oyunlarla kaplanmış durumda.Half-Life, Suffering, Doom, F.E.A.R. vs. oynamak için hayal gücü dahili içinde olmayan güçlerde PClere ihtiyaç duymaya başladık. Peki nasıl oluyorda bu 1 ler 0 lar eli kanlı dev yaratıklar olup geceleri peşimizde kabus gibi dolanabiliyorlar? Bu benim de inanılmaz merak ettiğim ve bir şekilde cevap alabilmek için çırpındığım bir soruydu. Ben kim miyim? Ben naçizane bir üniversiteden mezun, programlama ve oyun tutkunu, bu yüzden de oyun programlamaya merak sarmış bir Türk genciyim. Nelerle mi ilgileniyorum? Hafif C, şöle böle C++, Java gibi bişe, biraz ARM7 assembler, azıcık da PHP... Birazda DirectX ve OpenGL le ilgim alakam var. Ne bir DirectX ne de bir OpenGL ustasıyım fakat, şimdiye kadar internette oyun programlama ile ilgili Türkçe adam gibi hiçbir kaynağa rastlayamadım. Bunun sonucunda bende böyle birşeyler yapmak istedim, yapabildiğim kadarıyla.

    Burada oyun programlama, oyun yapısı, oyun motorları, diller, oyun türleri hakkında kısa yazılar yazmaya çalışacağım. Öncelikle yazdıklarımı oyun programlama hakkında birşey bilmeyenler için anlaşılır ama programlama bilmeyen biri için anlaşılamayabilir olacağını baştan söylemek isterim. Sizlerle beraber bende birçok yeni şeyler öğrenirken bunları Türkçe bir kaynaktan duyurmak istediğim için burda olduğumu tekrar hatırlatmak isterim... İsterseniz yavaş yavaş bir giriş yapalım artık.

    Bu yazıda basit olarak içeriden bakınca oyunun ne olduğu ve yapısı hakkında birşeylerle başlayacağız. Oyunlar gerçekten karmaşık ve kompleks birer yazılımlardır. Hatta bazı kitaplara ve internet sitelerine göre en zor yazılan programlardır. Oyunlar tek satırlı, etki-tetiklemeli (event-driven) veya ardışıl mantılkı (sequential logic) programlardan daha çok, gerçek zamanlı ve simülasyon programlarına daha çok benzer. Oyun basit olarak arkada bir mantık çalıtıran ve ekranda yapılan işlemlerin sonuçlarını 30-60 fps ile yansıtan sürekli bir döngüen oluşur. Bu döngüye oyun döngüsü (game loop) denilmektedir. Aslında ekranda görülen herşey bu oyun döndüsü içinde oluşmakta. Yapay zeka, ekran düzenlemeleri, hesaplamalar tamamen bu döngü içinde yapılmakta. Bu yüzden yazılan algoritmaların performansı oyunun perormansını birebir etkilemekte. Oyun döngüsünün yapısına kısaca bir bakalım:

    Basit olarak oyun döngüsü
    Şekil 1. Basit Oyun Döngüsü Yapısı

    Şimdide yukarıdaki grafiği biraz inceleyelim.


    1. Değerleri Sıfırlama ( Initialization ):
      Burada standart herhangi bir programı yazarken yapacağınız işlemler yapılır. Mesela Hafıza ayırma, diskten bilgi yükleme, ilk değerleri yerleştirme vs. vs.


    2. Oyun Döngüsüne Gir:
      Burada kod asıl döngüye, oyun döngüsüne girer. Burada oyundan çıkana kadar oyunun içindeki herşey gerçekleşir.


    3. Oyuncudan Girdi Al:
      Burada oyunu oynayan kimseden girdi alımı, bu girdinin işlenmesi gibi oyun-oyuncu interaktif ilişkisini sağlayacak işlemler gerçekleşir.


    4. Yapay Zeka ve Oyun Mantığını Uygula:
      Burası oyunun asıl bölümlerinden biri hatta en önemlisidir. Oyununuz içindeki oyuncu dışında kontrol edilen karakter ve ortamların yapay zeka algoritmaları, oyunun kuralları ve mantıkları burada işin içine girer. Ve burada genel oyun mantığı çalıştırılmış olur. Bundan sonra bir sonraki görüntünün işlenmesi işlemini geçilir.

    5. Bir Sonraki Ekranı Çözümle:
      Burada daha önce aldığımız kullanıcı girdileri, çalıştırdığımız yapay zeka ve oyun mantığı algoritmalarının sonuçlarını kullanarak ekranda o andan bir sonraki ekran görüntüsünün işlenmesi işlemi gerçekleştirilir. Bu oluşan görüntü yapıldığı anda değil bittikten sonra o an ekranda bulunan görüntüden hemen sonra ekrana gelir. Bu şekilde peşpeşe gelen ekran görüntüleri oyuncu için animasyon ilüzyonu yaratır.


    6. Görüntüyü Senkronize Et:
      Bazı bilgisayarlar oyunun kompleksitesine göre daha yavaş veya daha hızlı çalışabilirler. Ekranda 1000 tane objenin bulunmasıyla 10 tane obje bulunması arasında performans farkı olacaktır. Bu da oyun içinde saniyedeki görüntü sayısının (FPS) değişmesine sebep olur, ve bu bir oyun için çok kabul edilebilir birşey değildir. Bu yüzden oyunun fps’sinin programlayan kimse tarafından düzenlenmesi ve belli seviyelerde tutulması sağlanmalıdır. Bir oyunda minimum kabul edilebilir fps değeri 30fps’dir, 60 fps ise idealdir. 60fps üzerinde bir performansa sahip olmanın pek faydası yoktur çünkü insan beyninin saniyede 60 görüntüden yukarısını işlemekle ilgili problemleri vadır.


    7. Döngü:
      Bu bölüm çok kolaydır, sadece döngünün en başına dönmek yeterlidir.


    8. Kapat:
      Burası oyunun sonu demektir. Oyuncu ana oyun döngüsünden çıkmış ve işletim sistemine geri dönmek için oyuna gerekli komutu vermiştir. Fakat oyunu terketmeden önce yapılması gereken bazı işler vardır. Oyunda alınmış kaynakların bırakılması, hafızanın temizlenmesi, gerekli oyun değerlerinin saklanması ve sistemin temizlenmesi bu işlerin başında gelmektedir.


    Yukarıda yazdıklarımızı isterseniz bir de algoritmik olarak ifade etmeye çalışalım.


    // oyun dongusu durumlarinin tanimlamalari
    #define GAME_INIT // oyun ici degerler yaratiliyor
    #define GAME_MENU // oyun menu modunda,
    #define GAME_START // oyun basliyor
    #define GAME_RUN // oyun calisiyor
    #define GAME_RESTART // oyun yeniden basliyor
    #define GAME_EXIT // oyundan cikis
    // oyun globalleri
    int game_state = GAME_INIT; // oyun ici degeleri yaratma pozisyonunda basla
    int error = 0; // isletim sistemine hatalari dondurmek icin kullanilacak
    void main()
    {
    while(true)
    {
    // oyun dongusunun uygulamasi
    switch(game_state)
    {
    case GAME_INIT:
    {
    // tum kaynaklari ve hafiza alanlarini yarat
    init();
    // menu moduna gec
    game_state = GAME_MENU;
    } break;
    case GAME_MENU:
    {
    // ana menu fonksyonunu cagir ve oyun durumunu degistirmesine izin ver
    game_state = GAME_MENU;
    } break;
    case GAME_START:
    {
    // burada oyun baslamadan onceki son hazirliklar yapilir
    Setup_For_Run();
    // baslama moduna gec
    game_state = GAME_RUN;
    } break;
    case GAME_RUN:
    {
    // burada oyunun tum mantigi bulunnmakta.
    // goruntuyu temizle
    Clear();
    // girdi al
    Get_Input();
    // oyun mantigi ve yapay zekayi uygula
    Do_Logic();
    // bir sonraki ekranin hazirla
    Render_Frame();
    // goruntuyu 30fps+ seviyesinde tutmak icin ayarla
    Wait();
    // bu durumda oyunun durumu sadece oyuncu etkisiyle yada
    // oyunu kazanip kaybetmesine göre degisebilir.
    } break;
    case GAME_RESTART:
    {
    // Bu bolum herseyin temizlendigi ve yeniden yaratildigi alandir.
    // Oyun yeniden baslamadan once degerleri duzelenler
    Fixup();
    // geri ana menuye don
    game_state = MENU;
    } break;
    case GAME_EXIT:
    {
    // bu bolumde tum kaynaklari sil yada bosalt
    Release_And_Clenaup();
    error = 0;
    }
    default: break;
    } // switch bitir
    } // donguyu bitir.
    return (error);
    }


    Yukarıdaki oyun döngüsü mantığına bakılırsa, aslında oyun döngüsünün çok basit bir yapıya sahip olduğunu gösteriyor. Bu yukarıdaki döngü sadece bir while ve bir switch den ibaret bir algoritmaya sahip.

    Bugün çok basit olarak bir oyunun yapısı nedir, nasıl yapılır hakkında bir fikre sahip olmaya çalıştık. Bundan sonraki yazılarda biraz daha koda girmeye başlayacağız. Bir daha ki sefere görüşünceye kadar hoşçakalın.


    randomHero tarafından 22.04.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Google-Search History (Arama Geçmişi)

    "Ya ben bunu Google'da aramıştım ama....? Keşke eski aramalarıma ulaşabilseydim." dediğiniz oluyor muydu bilmiyorum ama Google bu tip bir hizmeti başlatacak. Henüz beta aşamasında olan Search History internete erişebildiğiniz herhangi bir bilgisayardan arama geçmişinize ulaşmanızı ve bu geçmişi yönetebilmenizi sağlayacakmış.

    Hangi aramaları, ne zaman yağptığınızı, sonuçlardan hangilerine tıkladığınızı gösterebilecek. Hatta bu arama geçmişinde de arama yapabileceksiniz. Google'da hergün kaç arama yapıyorum, bu arama sonucuna daha önce tıklamış mıydım ya da en son ne zaman tıklamıştım gibi soruların yanıtlarını bulabileceksiniz. Google'ın arama geçmişi tutma işlemini durdurmasını (pause) sağlayabilecek hatta bazı kayıtları silmesini isteyebileceksiniz. (remove items).

    Gmail, Google Groups, Google Alerts ya da Froogle üyesi iseniz hemen kullanabilirsiniz. Tabii, My Search History doğru çalışabilmek için Javascript'e gereksinim duyuyor. Bu yüzden aşağıdaki tarayıcılarda Javascript'i etkinleştirmeniz gerekecek:

    • Microsoft Internet Explorer 4.0 ve daha yukarısı

    • Firefox

    • Netscape 6.0 ve daha yukarısı

    • Mozilla

    • Safari 1.2 ve daha yukarısı




    spinodal tarafından 21.04.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    EntLib'i Genişletmek 1

    Giriş

    EntLib (Microsoft Enterprise Library ) yayınlanalı iki aydan fazla bir süre oldu. EntLib'i size herbirinde bir eklenti geliştireceğimiz bir yazı dizisiyle daha yakından tanıtmak istiyorum. İlk yazıda Security Block'u LDAP'tan kimlik doğrulama için genişletiyoruz.

    EntLib nedir?

    EntLib kurumsal uygulamalar için Microsoft Patterns & Practices Group ve Avanade tarafından ortaklaşa geliştirilmiş açık kaynaklı bir altyapı kütüphaneleri seti. Yayınlanalı iki aydan fazla bir süre oldu. Aslında EntLib daha önce de aşina olduğumuz çeşitli uygulama bloklarının biriken deneyimlerle geliştirilmiş ve biraraya toparlanmış hali. Bu bloklar;

    • Konfigürasyon bloğu (en alt katman)

    • Şifreleme bloğu

    • Önbellek bloğu

    • Loglama bloğu

    • Hata yönetim bloğu

    • Veri erişim bloğu

    • Güvenlik bloğu (en alt katman)


    Nerdeyse tüm uygulamaların geliştirilmesinde gündeme gelen bu konulara standart, ortak ve genişletilebilir çözümler sunan bu kütüphaneler, yazılım geliştirme sürecini hem disipline ediyor hem de oldukça kolaylaştırıyor.

    Kendi kimlik doğrulama sağlayıcımızı yazmak

    EntLib geliştirilirken kurumların bu kütüphaneleri genişletme ihtiyacı gözönünede tutulmuş ve bazı genişletme noktaları bırakılmış. Kimlik doğrulama da bunlardan biri. Bu yazıda EntLib’in güvenlik uygulama bloğunu kendi Ldap sunucumuzdan kimlik doğrulamak üzere genişleteceğiz. Bunun için yeni bir sınıf kütüphanesi oluşturmamız gerekiyor. Temelde Yapmamız gereken işlem Security kütüphanesi içindeki IAuthenticationProvider adlı arayüzü LDAP bağlantısı ile sağlayan bir sınıf geliştirmek. Arayüzümüz oldukça basit;


    public interface IAuthenticationProvider : IConfigurationProvider
    {
    bool Authenticate(object credentials, out IIdentity identity);
    }


    Ancak, bu arayüzün Configuration bloğundan gelen IConfigurationProvider arayüzünü genişlettiğini görüyoruz. Bu arayüz ise;


    public interface IConfigurationProvider
    {
    string ConfigurationName { get; set; }
    void Initialize(ConfigurationView configurationView);
    }


    Evet sonuçta uymamız gereken arayüz kontratının üç üyesi bulunuyor. Sınıfımızın çatısı şöyle birşey olmalı;


    public class LdapAuthProvider : IAuthenticationProvider
    {
    private string _confName;
    string ConfigurationName
    {
    get{return _confName;}
    set{_confName=value;}
    }
    void Initialize(ConfigurationView configurationView)
    {
    // init.
    }
    bool Authenticate(object credentials, out IIdentity identity)
    {
    //impl.
    }
    }


    Initialize metodunun içerisinde uygulama konfigürasyon yapısından bize ait konfigürasyon bölümünü tespit ediyoruz.


    Logger.Write("Initializing LDAPAuthProvider : "+this.ConfigurationName);
    ArgumentValidation.CheckForNullReference(configurationView,"configurationView");
    ArgumentValidation.CheckExpectedType(configurationView, typeof(SecurityConfigurationView));
    this.securityConfigurationView=(SecurityConfigurationView)configurationView;
    Logger.Write("LDAPAuthProvider : "+this.ConfigurationName+" initialized");


    Daha sonra bu nesneyi kullanarak konfigürasyondan LDAP sunucu adını ve kullanıcıları soruşturacağımız path’i okuyacağız. Dikkat edin, bu bilgileri bu noktada okumuyoruz, çünkü okusaydık uygulama çalıştıktan sonra yapılan değişikliklerden haberdar olamazdık. Oysa ki konfigürasyon bloğu bizim için konfigürasyon dosyalarını sürekli gözlüyor ve değişiklik durumunda yeniden yüklüyor.
    Bu nedenle yapmamız gereken konfigürasyon bilgilerini kendi nesnelerimiz içinde saklamayıp her gerektiğinde – yani Authenticate metodunun başında - konfigürasyon bölümünden okumak. (Tabii bunun performans dezavantajı olacaktır.)


    CustomAuthenticationProviderData config = (CustomAuthenticationProviderData) securityConfigurationView.GetAuthenticationProviderData(ConfigurationName);


    Authenticate metodu ise asıl işimiz olan LDAP bağlantısını kuracağımız ve kullanıcı kimliğini doğrulayacağımız kısım. Metodumuza geçen credentials parametresinin object tipinde olmasının sebebi uygulama tarafından değişik tiplerde kimlik bilgilerinin gönderilebilmesi. Bu da uygulamalar ile kütüphane arasında gevşek bağlı (loosely-coupled) esnek bir ilişki kurulmasını sağlıyor. Herneyse biz girdi olarak Microsoft.Practices.Security aduzayında bulunan NamePasswordCredential tipindeki kimlik bilgilerini kabul edelim.
    Gelen kimlik bilgilerine ilgili kontroller uyguladıktan sonra LDAP sunucusuna bağlanıp kullanıcının adını okumamız gerekiyor.
    Authenticate metodunda dikkatinizi çekebilecek bir diğer nokta da yapılan SecurityAuthentication...Event.Fire çağrıları. Bu çağrılar, güvenlik bloğunun performans sayaçlarına gereken verileri beslemek için.
    Girdi parametrelerinin geçerlemesi için Common kütüphanesinden çıkan ArgumentValidation sınıfının statik metodlarını tavsiye ediyorum.


    //Cast and validate credentials
    ArgumentValidation.CheckForNullReference(credentials,"Credentials");
    ArgumentValidation.CheckExpectedType(credentials,typeof(NamePasswordCredential));
    NamePasswordCredential cred = credentials as NamePasswordCredential;
    ArgumentValidation.CheckForEmptyString(cred.Name, "Credential.Name");


    Konfigürasyon ayarları

    Sıra geldi, konfigürasyon dosyasının düzenlenmesine. Bu işin en kolay kısmı. EntLib kurulumunda gelen konfigürasyon aracı ile bu düzenlemenin tamamı yapılabiliyor. Uygulamanıza ait konfigürasyon dosyasını açın, uygulamaya sağ tuş yapıp New->Security Application Block deyin.
    EntLib Config size yeni bir güvenlik bloğu ve yanında eğer halehazırda kullanmıyorsanız konfigürasyon bloğu yaratır. Authnetication Provider düğümünde tekrar sağ tuş yaparak New->Custom Authentication Provider yaratın. Daha sonra bu düğümü seçin. Custom Authentication Provider'ın TypeName, Extensions ve Name alanlarından oluştuğunu göreceksiniz. TypeName alanında, bizim kimlik doğrulama sınıfımız ı atayın, TypeSelector formunda alt kısımdaki düğme ile kütüphanemizi yükleyip sonra da sınıfımızı seçebilirsiniz. Extensions kolleksiyonunda ise sınıfımızda konfigürasyondan okumaya çalıştığımız 'ldapServer' ve 'Path' adlı birer anahtar yaratarak ilgili değerleri girin. Bunlar 'myldapServer' ve 'ou=People,dc=my,dc=domain' gibi değerler olmalı.

    Evet, böylece geliştirmemizi tamamladık. LDAP'a ilişkin kısımlara değinmeye gerek görmedim. Aşağıda sınıfın kodlarının tamamını veriyorum. Yorum, öneri ve problemlerinizi çekinmeden yazın. Ayrıca faydalanabileceğiniz linkler;


    LDAPAuthProvider sınıfı

    using System;
    using Microsoft.Practices.EnterpriseLibrary.Common;
    using Microsoft.Practices.EnterpriseLibrary.Configuration;
    using Microsoft.Practices.EnterpriseLibrary.Logging;
    using Microsoft.Practices.EnterpriseLibrary.Security;
    using Microsoft.Practices.EnterpriseLibrary.Security.Configuration;
    using Microsoft.Practices.EnterpriseLibrary.Security.Instrumentation;
    using System.DirectoryServices;
    using System.Security.Principal;
    namespace EntLibEx.Security
    {
    ///
    /// LDAPAuthProvider provides authentication functionality against an LDAP server.
    ///

    public class LDAPAuthProvider : ConfigurationProvider, IAuthenticationProvider
    {
    //Configuration parameter names
    private const string LDAP_PARAM = "ldapServer";
    private const string PATH_PARAM = "path";
    private SecurityConfigurationView securityConfigurationView;
    public LDAPAuthProvider(){}
    public bool Authenticate(object credentials, out IIdentity identity)
    {
    identity=null;
    //Cast and validate credentials
    ArgumentValidation.CheckForNullReference(credentials,"Credentials");
    ArgumentValidation.CheckExpectedType(credentials,typeof(NamePasswordCredential));
    NamePasswordCredential cred = credentials as NamePasswordCredential;
    ArgumentValidation.CheckForEmptyString(cred.Name, "Credential.Name");
    //get configuration
    CustomAuthenticationProviderData config = (CustomAuthenticationProviderData)securityConfigurationView.GetAuthenticationProviderData(ConfigurationName);
    SecurityAuthenticationCheckEvent.Fire(cred.Name);
    try
    {
    //LDAP query
    DirectoryEntry de = new DirectoryEntry(
    String.Format("LDAP://{0}/{1}",config.Extensions[LDAP_PARAM], config.Extensions[PATH_PARAM]),
    String.Format("uid={0},{1}", cred.Name, config.Extensions[PATH_PARAM]),
    cred.Password,
    AuthenticationTypes.ServerBind);
    DirectorySearcher ds = new DirectorySearcher(de);
    ds.Filter = String.Format("(uid={0})", cred.Name);
    ds.PropertiesToLoad.AddRange(new string[]{"givenname"});
    SearchResultCollection sr=null;
    sr = ds.FindAll();
    ArgumentValidation.CheckForNullReference(sr,"SearchResultCollection");
    if(sr.Count == 0)
    {
    SecurityAuthenticationFailedEvent.Fire(cred.Name);
    return false;
    }
    identity = new GenericIdentity(de.Properties["givenname"].Value.ToString());
    return true;
    }
    catch(Exception exc)
    {
    SecurityAuthenticationFailedEvent.Fire(cred.Name);
    Logger.Write(String.Format("Authentication of user{0} failed. Cause :{1}",cred.Name,exc.Message));
    return false;
    }
    }
    #region IConfigurationProvider Members
    public override void Initialize(ConfigurationView configurationView)
    {
    Logger.Write("Initializing LDAPAuthProvider : "+this.ConfigurationName);
    ArgumentValidation.CheckForNullReference(configurationView, "configurationView");
    ArgumentValidation.CheckExpectedType(configurationView, typeof(SecurityConfigurationView));
    this.securityConfigurationView = (SecurityConfigurationView)configurationView;
    Logger.Write("LDAPAuthProvider : "+this.ConfigurationName+" initialized");
    }
    #endregion
    }
    }


    NOT : Eğer loglama bloğunu kullanmıyorsanız LdapAuthProvider sınıfındaki loglama satırlarını yoruma çevirmelisiniz.


    bioLogic tarafından 21.04.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    NAnt

    Bu aralar .NET uygulamalarımızı ekipçe geliştirirken kullanabileceğimiz entegrasyon araçları üzerine çalışıyoruz. Bu yüzden bu ve bundan sonraki birkaç gönderide .NET ile uygulama geliştiren kişi ve ekiplerin kullanabilecekleri araçların birkaçından bahsetmek istiyorum. Bunu, okuduğum birçok (İngilizce) kaynaktaki gibi düz bir biçimde yazarak yapmak istemedim. Onun yerine Robert C.Martin'in Craftsman makale serisinden ve Tom DeMarco'nun Deadline kitabından etkilenerek aklıma gelen diyaloglar biçiminde yazma yöntemini kullanmaya karar verdim. İlk gönderi ile başlayalım. Beğenilirse devam edelim.

    İlk olarak kahramanlarımızın konusu oluşturma aracı NAnt olan konuşmalarına kulak verelim.

    Emre: E abi son zamanlarda nelerle uğraşıyorsunuz?
    Selçuk: Şu sıralar NAnt ile uğraşıyoruz. Duymuşsundur.

    Emre: NAnt mı? Hayır, hiç duymadım. Yine sizin şu garip icatlarınızdan biri mi yoksa? Nedir?

    Selçuk: Nant açık kaynak kodlu bir yazılım. Bir oluşturma aracı -build tool. Yani kodların derlenmesi ve kaynak dosyaların kütüphaneler (assembly) biçimine dönüştürülmesi işini yapıyor kısaca.

    Emre: Oluşturma aracı mı? Böyle birşey neden kullanmak isteyeyim ki? Visual Studio kullanılyorum ve "Rebuild Solution" komutunu tıkladığımda bu dediklerini VS.NET benim için yapıyor.

    Selçuk: Diyelim ki oluşturma işini otomatikleştirmek istiyorsun. Aslında istiyorsunuz demek daha doğru olur çünkü geliştirme işini bir ekip olarak yaptığınızı varsayıyorum. Ayrıca oluşturma süreci sadece kodların derlenmesi ve kaynak dosyaların kütüphaneler biçimine dönüştürülmesi demek olmayabilir. İşin içine, Source Control uygulamasından -VSS, ClearCase vb.- kaynak kodun son halini almak, birim testleri çalıştırmak, bu birim testlerin kodun ne kadarını kapsadığının kontrolünü yapmak, kaynak koddan dökümantasyon yaratmak ve oluşturmaya özgü konfigürasyon ayarlarının yapılması vb. adımlar da girebilir. Böyle bir durumda, oluşturma işini, oldukça esnek yapıda olan bu tip bir araçla yapmak isteyebilirsin. Biz de zaten NAnt ile bu yüzden ilgileniyoruz. Kullanmayı düşündüğümüz otomatik integrasyon aracı da CruiseControl.net ama istersen ondan daha sonra söz edelim, çünkü henüz o konuda NAnt kadar çalışmadık. Ha, bu arada NAnt Visual Studio'ya ihtiyaç duymuyor, yani herhangi başka bir kod editörünü kullanıyor olabilirdin.

    Emre: Tam anlamıyla anlayamadım ama ilgimi çekmedi değil. Adı da bir garip, nereden geliyor?

    Selçuk: Aslında NAnt da bir çok açık kaynak kodlu .NET projesi gibi Java dünyasındaki ağabeyini izliyor. Bunun birçok örneğini görebilirsin, örneğin CruiseControl-CruiseControl.Net ve JUnit-NUnit gibi. NAnt, Java geliştiricileri için açık kaynak kodlu frameworkler geliştiren Apache organizasyonunun oluştruma aracı olarak yarattığı Ant'ın .NET versiyonu. Anlamı için ise ant.apache.org sitesine başvurabilirsin.

    Emre: İlginç. Biraz daha bahsetsene şu NAnt'tan.

    Selçuk: Öncelikle NAnt kullanabilmek için şu CLR'lardan birine ihtiyacın var, ya da başka bir deyişle NAnt bu CLR'ları destekliyor demek daha doğru:

    • Microsoft .NET Framework 1.0

    • Microsoft .NET Framework 1.1

    • Microsoft .NET Framework 2.0 Beta 1

    • Mono 1.0.x


    Ayrıca NAnt birkaç başka açık kaynak kodlu kütüphaneye de gereksinim duyuyor. Bunlar Nunit, NDoc ve SharpZipLib. Ama bunlar, NAnt'ı sitesinden indirdiğinde onunla birlikte geliyor endişelenme. Bu adresten ister yalnızca çalıştırılabilir dosyaları ister tüm kaynak kodu indirebilirsin. İndirdiğin zip dosyasını istediğin bir yere aç ve NAnt'ın \bin klasörünü PATH'ine ekle. Beni daha fazla dinlemek istemezsen hemen gidip bunları yapabilir ve en son adım olarak "nant -help" yazarak kendin araştırmaya başlayabilirsin. İndirdiğin zip dosyasının içinden NAnt sitesindeki help sayfalarının kopyalarını içeren bir \doc klasörü de çıkıyor ama ben derim ki gel sen beni dinlemeye devam et.

    Emre: Tabi tabi can kulağıyla dinlemedeyim. Sen devam et.

    Selçuk: Aslında NAnt temel olarak XML formatında hazırlanan .build uzantılı bir dosyayı okuyarak orada belirtilen işleri gerçekleştiriyor. O yüzden ben bu dosyanın hazırlanmasını anlatayım istersen. Çünkü gerisi kolay; sadece komut satırında "nant.exe" yazman yeterli. Nant öncelike o anki dizinde .build uzantılı dosya arıyor. Böyle birden fazla dosya varsa dosya adı vermelisin. Ya da bir üst dizindeki dosyayı kullanması için "nant -buildfile:..\dosyaAdi.build" yazabilirsin. Hatta NAnt'a build dosyasının içinde hangi target'ı çalıştıracağını bile "NAnt targetAdi" biçiminde söyleyebilirsin.

    Emre: Target mı? Haydaa o ne şimdi?

    Selçuk: Haklısın, gel target mevzuuna girelim. Ama önce söylemek istediğim birşey var. Build dosyalarının yapısını anlamak için güzel bir yöntem NAnt'ın kendi build dosyasına (nant.build) bakmak olabilir. Ama uyarayım ürkebilirsin, yeni başlayanlar için biraz karmaşık.
    Evet ne sormuştun. Hımm target dedim ve açıklamadım değil mi? Şimdi... Her NAnt build dosyası bir projeden (project) ve bir veya daha fazla target'dan oluşur ve her target da yine bir veya daha fazla task içerir. Aslında küçük bir örnek yazsam saatlerce anlatmama bedel olacak. Bak şöyle küçük bir örnek yazabiliriz:

    < ?xml version="1.0"?>
    <project name="Meraba Televole" default="build" basedir=".">
    <description>Meraba Televole oluşturma dosyası</description>
    <property name="debug" value="true" overwrite="false" />
    <target name="clean" description="tüm dosyaları silelim">
    <delete file="MerabaTelevole.exe" failonerror="false" />
    <delete file="MerabaTelevole.pdb" failonerror="false" />
    </target>
    <target name="build" description="oluşturalım" depends="clean">
    <csc target="exe" output="MerabaTelevole.exe" debug="${debug}">
    <sources>
    <includes name="MerabaTelevole.cs" />
    </sources>
    </csc>
    </target>
    </project>

    Al işte sana iki target "clean" ve "build". Aslında bu birçok şeyi açığa çıkarıyor değil mi? Ama gel ben anlatmaya devam edeyim. "basedir" özelliği, bu işte dizin adresi hesaplamaları için alınacak referansı belirtiyor. NAnt bu dosyayı ele aldığında, komut satırında belirtilmediyse hangi target'ı çalıştıracağını bilmeli, o yüzden varsayılan bir target "default" özelliğiyle tanımlanıyor. Bir de dosya boyunca kullanılmak istenen değişkenler tanımlanabiliyor. Bunlara "property" deniyor ve örnekteki gibi tanımlanıp "${özellikadı}" biçiminde dosya içinde kullanılıyor. NAnt'ın yerleşik özellikleri (property) de var ama onlara sen dökümanlardan bakarsın.
    Gelelim build target'ındaki "depends" kavramına. Eğer bir target'ın çalıştırılması başka bir target'ın çalıştırılılmış olmasına bağlamak istersen bunu "depends" ile yapıyorsun. Buraya birden fazla target'ı virgülle ayırarak da yazabilirdik. Ayrıca target'a "if" ve "unless" kavramlarını ekleyerek koşullu çalışır duruma da getirbilirsin. "if" içinde verilen önerme true dönüyorsa target çalışır, "unless" içindeki true dönerse o target pas geçilir. Ama gel onun da ayrıntılarına girmeyelim ihtiyaç duyduğunda belgelerden bakabilirsin. Küçük bir örnek de vermeden de geçmeyeyim ama.

    <target name="build-module-A" unless="${file::exists('module-a.dll')}" />

    Gelelim task'lara. Task'lar çalıştırılabilecek kod parçalarıdır. Örnekte "delete" ve "csc" taskları var. Başka örnekler copy, exec, echo, mail, nunit ve zip olabilir. Gördüğün gibi aslında tüm işi bu task'lar yapıyor. Taskların target ve project'den farkı onları task etiketi ile değil kendi isimleri ile etiketliyor oluşumuz. Ayrıca her taskın kendine özgü içiçe geçmiş elemanları var. Örnek olarak copy taskini ele alalım. Bu taskı bir ya da daha çok dosyayı farklı bir yere kopyalamak için kullanabilirsin. Copy taskinin iki içiçe geçmiş bileşeni var. Fileset ve filterchain. Fileset kopyalanacak dosyaları seçmek için filterchain ise dosyayı kopyalandıktan sonra değiştirmek için kullanılıyor. Örneklemek için şunları yazabilirim:

    <copy todir="../yedek/dir">
    <fileset basedir="kaynak_dir">
    <include name="**/*" />
    </fileset>
    <filterchain>
    <replacetokens>
    <token key="FILE" value="yedek" />
    </replacetokens>
    </filterchain>
    </copy>

    Bu task, "kaynak_dir" klasöründeki ve altındaki tüm klasörlerdeki dosyaları "yedek/dir" adresine kopyalar ve dosyalarda @FILE@ geçen yerlere "yedek" yazar. Tasklardan sözetmeye devam edersek bu sohbet çok uzayacak sen iyisi mi tüm taskların listesine belgelerdeki Task Reference'den bak ve işine yarayacağını düşündüklerinin detaylarını oku.
    Gelelim diğer unsurlara. Loggerlar, Listenerler, Expressionlar ve Functionlar. Oluşturma işini izleyebilmek için logger ve listener kullanıyoruz. Adlarından da anlaşıldığı gibi listenerlar belli olaylar sırasında veya sonrasında uyarılırlar. Loggerlar ise standart çıktı ve hata sonuçlarını alıp konsola ya da "-logfile" ile kendilerine gösterilen dosyaya log yazarlar. Xml ve mail loggerlar sık kullanmak isteyebileceğin türden kavramlar. Maillogger'a mail atabilmesi için gerekenleri, xmllogger'a da dosya adı vermen yeterli. "Örnek" der gibi bakıyorsun, al bakalım o zaman:

    NAnt.exe -logger:NAnt.Core.MailLogger
    NAnt.exe -logger:NAnt.Core.XmlLogger -logfile:buildlog.xml

    Task argümanlarında ve koşullu çalıştırmak istediğin taskların koşullarında kullanman için Nant exressionlar da sunuyor. Bunun için yerleşik expression kullanabilirsin. Sayısal, boolean, string ve tarih-zaman değerleri için oldukça çok sayıda yerleşik expression mevcut. Bunlar için de seni NAnt yardım dosyalarına yönlendirmek zorundayım zira programlama ya da script dillerinde rastlayabileceğin birçok ortak expression NAnt'ta da kullanılıyor ve çok fazla sayıda örnek yardım dosyalarında var. Expressionları ${...} biçiminde kullanabiliyorsun. Sen şimdi yine örnek istersin:

    <property name="myprj.basedir" value="c:\" />
    <property name="dosyaadi" value="${path::combine(myprj.basedir, 'surum.txt')}" />

    <if test="${not file::exists(filename) or file::get-length(filename) = 0}">
    <echo message="Sürüm dosyası: ${dosyaadi} yok ya da boş!" />
    </if>

    Expressionlar gibi functionlar da programlama ya da script dillerinde rastlayabileckerinle ortaklıklar sergiliyor. Nant işlevleri ile metinleri, tarih ve saat değerlerini, klasör adreslerini değiştirebilir, o anki oluşturma işleminin detay bilgilerine ulaşabilir ya da dosya ve klasörlerin detaylı özelliklerine erişebilirsin. Functionlar, başlangıç::function-adı(argüman1,..., argümanN) biçiminde kullanılıyor. Örnek olarak string::contains('NAnt','a') verilebilir. Bu arada unutmadan belirteyim, istersen kendi işlevlerini de yazabilirsin. Açıkçası bunu hiç kullanmadık. Unutma ben sadece senin merakını gidermeye, bu ve benzeri araçları kullanmanı sağlamaya çalışıyorum. Bunların ikisini de başarabilirsem senin işin asıl o nokada başlayacak ve yardım dosyaları ile google (adres) bu konuda benden sonraki rehberlerin olacak. Bu arada dinliyorsun değil mi? Yoksa çok mu hızlı gittim?

    Emre: Aslında yakalamakta biraz güçlük çekiyorum. Benim aklıma daha basit şeyler takıldı. Mesela ben bu build dosyalarını VS.NET içinden yazmak istesem sürekli dönüp yardım dosyalarına bakmadan yapmak isterim. VS.NET'in intellisense'inde faydalanabilir miyim?

    Selçuk: E tabi. Öncelikle .build uzantılı dosyanı yarat. Sonra Solution Explorer'dan sağ tıklayıp menüden Open with… komutunu tıkla. Açılan pencerede HTML/XML Editor'u seç ve önce Set As Default'ı sonra da Open'ı tıkla. Böylece bundan böyle VS.NET .build uzantılı dosyalarını HTML/XML Editor'u ile açacak. Şimdi NAnt'ın schema dosyasını (NAnt altında schema klasörü içinde nant.xsd) VS.NET kurulum adresi altında \Common7\Packages\schemas\ klasörü altına kopyala. Sonra .build uzantılı doyanın içeriğine tıklayıp Properties bölmesini açmak için F4'e bas. Burada targetSchema olarak az önce kopyaladığın schema dosyasını seç. Aslında yaptığımız sadece VS.NET'e gerekli schema'yı tanıtmak, artık intellisense build dosyası oluştururken sana yardımcı olacak.

    Emre: İşte şimdi tamamdır. Ben ilk fırsatta örnek bir proje ile NAnt'ı kurcalamaya başlarım. Sana da teşekkür etmem gerek zira bir saattir anlatıyorsun.

    Selçuk: Önemli değil. Sen yeter ki bu araçlarla tanış. Şimdi benim de biraz işim var. Ama sohbetimiz sırasında adı geçen bazı başka araçlar ve kavramlar oldu. Onlardan da sana bahsetmek isterim. Bir ara ikimizin de zamanı olduğunda yine buluşalım.

    Emre: Şimdiden biraz ipucu versen. Nelerden söz edeceğiz?

    Selçuk: Örneğin birim testler konusu geçti az önce. Sana ilk olarak bu konudan yani NUnit'ten bahsetmek istiyorum. Hatta o zaman Nunit'ı Nant ile birlikte kullanmaktan da bahsederiz. Tahmin edeceğin gibi bunun için NAnt'da bir task var. Ama bunlardan o zaman konuşalım olur mu? Şimdi gitmeliyim.

    Emre: E hadi bakalım. Görüşürüz.


    spinodal tarafından 19.04.2005 tarihinde yazılmıştır.

    Labels: , ,


    yazının tamamını okumak için burayı tıklayın...

    Hoşgeldik

    Yazılım işinde çalışıyoruz. İlgi alanlarımız da hep enformatik alanında:

    • .net ve java teknolojileri

    • web standartları ile tasarım

    • oyun programlama

    • yazılım geliştirme süreçleri

    • dijital fotoğraf

    • vb...




    spinodal tarafından 17.04.2005 tarihinde yazılmıştır.

    Labels: , , ,


    yazının tamamını okumak için burayı tıklayın...

    SanalBellek - Neyiz? Ne Değiliz?

    Merhaba...

    Neyiz?

    Yazılım geliştirme çalışanlarıyız. Yazılım geliştirme çalışanları olarak bugüne dek karşılaştığımız -kimisi abuk subuk- zorlukların ve problemlerin çok büyük bir bölümünü internet sayesinde, daha doğrusu bilgilerini internetten dünyayla paylaşan insanların sayesinde çözdük. Bu kaynaktan böylesine beslenirken -sahip olduğumuzca- kendi bilgi ve deneyimlerimizi de internet üzerinden insanlarla paylaşmak iş etiği açısından bir yükümlülüktür diye hissediyoruz. Araştırmacıyız. Kendi işlerimiz için oldukça çok ve çeşitli sayıda teknolojiyi ilgilendiren birçok konuda araştırma yapıyoruz. Bu araştırmaların sonuçlarını, okuduklarımızı ve öğrendiklerimizi bizimle aynı şeyleri araştırmak durumunda olan insanlara hızla erişebilecekleri biçimde sunalım istiyoruz. Hevesliyiz. Ayrıca yorumlarınız aracılığıyla yanlışlarımızı ve eksiklerimizi de öğrenmek istiyoruz. Türküz, öyle milliyetçi falan değiliz ama en azından Türkçe yazalım dedik, ilgilendiğimiz konularda İngilizce kaynak zaten fazlaca var. Hazırız. Özellikle incelenmesini istediğiniz araç ve teknolojileri öneri olarak bize gönderebilirsiniz.

    Ne değiliz?

    Öncelikle, çok iyi birer web tasarımcısı ya da WordPress kullanıcısı değiliz. Bu yüzden henüz taze olan sitede ufak tefek eksiklikler olabilir. Sizin geri beslemeleriniz sayesinde hem görünüm hem içerik düzelecek, güzelleşecek. İkincisi, iyi yazar olduğumuz da söylenemez. Ama şu an için bildiklerimizi paylaşmanın yöntemi yazmak, elimizden geleni yapacağız. Son olarak tüm zamanımız boş değil, çalışıyoruz. Bu da belki bazen uzun aralara sebep olabilecek. Bu konuda da elimizden geleni yapacağız.

    Bakalım, hep birlikte göreceğiz...

    spinodal, bioLogic ve randomHero tarafından 16.04.2005 tarihinde yazılmıştır.

    Labels: , , , ,


    yazının tamamını okumak için burayı tıklayın...