Tuesday, February 24, 2009

Cozunurluluk Ayari

Javascript kullanarak degisik cozunurlukteki ekranlar icin goruntuyu degistirmeniz gerekiyorsa, Javascript screen objesini kullanarak bunu yapabilirsiniz. Diyelim ki bir uygulamayi 1280x800 cozunurluluk icin yazdiniz, ama 1024x768 ekranda soldaki bosluk kismini sifira indirerek ekrandaki gorsel elementleri gorus alanina sigdirmak istiyorsunuz. O zaman once HTML kodunuzu alttaki gibi degistirin;
<html>
<head>
<script src="resolution.js"></script>
</head>
<body onload="styleSwitcher();">
...
</body>
</html>

body icinde yapilan Javascript cagrisi sayesinde bu sayfa her yuklendiginde styleSwitcher() fonksiyonu cagirilacaktir. Bu fonksiyonun kodu resolution.js dosyasi icinde.

Bu Javascript fonksiyonu, ustteki sayfa yuklendiginde screen objesi uzerinden hangi cozunurlukte oldugunu kontrol edecek. Eger daha 1024x768'te isek, o zaman gerekli CSS elementlerinin boyutlarini degistirerek konumlandirmalari degistirecek.

function styleSwitcher(){

var width = screen.availWidth;
if (width == 768 ){
var theDiv = document.getElementById('div1');
if (theDiv != null) theDiv.style.marginLeft = "0%";
...
}

Burada div1 kodundaki elementin margin-left boyutunu degistirdik ve sifira indirdik.

Fonksiyon icinde "her tarayiciya ozel" ayarlamalar da yapabilirsiniz. Tarayici ismine erismek icin navigator.appName cagrisi yeterli; Bu cagridan mesela IE icin geriye Microsoft Internet Explorer kelimesi geriye gelecek. Biz butun sitemizi standartlari takip eden Firefox'a gore yapiyoruz ve IE'nin uyumsuzluklarini yamamak icin ustteki gibi cagrilarla (ve daha once belirttigimiz CSS numarasi ile) gerekli ekleri yapiyoruz.

var browser=navigator.appName;

if (browser == "Microsoft Internet Explorer") {
var theDiv = document.getElementById('div2');
if (theDiv != null) theDiv.style.left = "440";
...
}

Monday, February 16, 2009

Tim Bray ile Roportaj

Sun Microsystems'den Jim Bray ile uzunca bir roportaj.. 2009 itibariyle Web programlama dunyasinin durumu, bu alandaki diller, yeni teknolojiler, cloud kavrami ve gidilen yonun tartisildigi guzel bir soylesi.

Javascript, FQL ve Facebook Connect

Bir onceki yazidaki videoyu seyrettiyseniz, FB baglantisi yapmak icin sadece Javascript cagrilari yapmanin yeterli oldugunu gormussunuzdur. Aslinda tum Facebook API cagrilarini pur Javascript bazli, yani client/browser/tarayici temelli olarak yapabilirsiniz. Servis tarafi kodlamasina gerek yok.
Ama veriler servis tarafina gerekiyorse, o zaman bir cozum, FB cagrilarini hala JS ile yapmaya devam etmek, ve veriler elde edilince bu verileri Ajax ile (yani Javascript'ten EJB'ye cagri yaparak) servise aktarmak uygun bir yontem olabilir. Bizim uygulamamiz icin sectigimiz yon bu olacaktir. Diger alternatifler "servis tarafinin da" Facebook API cagrilari yapabilmesidir, ki zaten ilk FB Connect yazisinda tarif edilen bu tur bir arayuzdur. Beni burada tek rahatsiz eden durum, Facebook sirketinin servis tarafi Java API'yi desteklemeyi birakmis olmasi; Bu yuzden Google Code uzerindeki kod bazinin bakimi FB sirketi disindaki insanlar ustlenmis. Bu onemli olmayabilir, fakat akilda tutulmasi gereken bir faktordur.
Bu yazinin hedefine gelelim; Burada gorecegimiz ornek bir sayfadan FB'ye baglanmak ve arkadaslarimizin listesini, onlarin bilgilerinden bazi ogeleri alip ekrana basmak. Arkadaslarinizin bilgilerine erismek icin guzel bir yontem FQL adli SQL'i temel almis bir sorgulama dili kullanmak. Evet: FB Javascript API kullanarak, resmen SQL isletebiliyorsunuz. Facebook ortami uygulamaniz icin adeta bir database'e donusuyor. Bu hakikaten guclu bir ozellik.
Arkadas bilgilerini almak icin gereken script soyle;
<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function()
{
FB.Facebook.init("[YOUR APP KEY HERE]", "xd_receiver.htm");
FB.Facebook.get_sessionState().waitUntilReady(function()
{
  window.alert("Session is ready");

  var uid = FB.Facebook.apiClient.get_session().uid ;
  var sql = "SELECT name, birthday FROM user " +
            "WHERE uid IN (SELECT uid2 FROM friend " +
            "WHERE uid1 = "+uid+")";
  FB.Facebook.apiClient.fql_query(sql, function(result, ex) {
      var userName= result[0]['name'];
      alert(userName);
      var bday = result[0]['birthday'];
      alert(bday);
      var bday = result[1]['birthday'];
      alert(bday);
      var bday = result[2]['birthday'];
      alert(bday);

  });
});
});
</script>
Bu sayfa, size ozel FB sifreniz girilmemis ise, onu girmeniz icin sayfa aciyor, sonra gereken bilgileri aliyor. Dikkat: ustte [YOUR APP KEY HERE] diyen yere kendi uygulama kodunuzu girin. Bunun nasil yapilacagini bu yazida gormustuk.
FB'de kullanici bilgileri USER tablosunda tutuluyor, kullanici kimlikleri uzerinden iki kullanici arasinda "arkadaslik" ise FRIEND tablosun uzerinde tutuluyor. USER tablosunun semasi surada.
Ustteki kodda sadece listedeki birkac kullaniciyi gezdik. Istenirse for ile hepsi gezilebilir. Ayrica bilgiler message box ile veriliyor, bu bilgi Ajax ile servis tarafina aktarilabilir.
Ornek kod

xd_receiver.htm


   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">


    cross domain receiver page

   



friends.htm

  FQL Friend Demo
    
 

    FQL Friend Demo
 
  Login flow example, with simple API call example
  Login Button:

 
 
 
 
 
  
 



FB Connect Video

Video surada:

http://www.facebook.com/video/video.php?v=630563174283

Sunday, February 15, 2009

Facebook Connect

Web sitemize giris yapan kullanicilarin ismini kendi veri tabanimizda tutmak istemiyor, ve potansiyel kullanicilarin Facebook'ta tuttugu bilgilerini (profil, arkadas listesi gibi) kendi sitemize almak istiyorsak, Facebook Connect bize bu ozellikleri sunuyor. Ucuncu parti siteler uzerinden kullanici girisi kavrami son zamanlarda oldukca ses getiren bir uygulama oldu. Bu alanda buyuk bir yaris var. Google'in Friend Connect yaklasimi var, MySpace ayni sekilde. Biz uzerinde calistigimiz uygulama icin Facebook'u sectik, ileride diger secenekleri de dahil etmeye baslayabiliriz.

FB Connect ile sitemizdeki "giris (login)" dugmesi artik FB login'i olacak; yani ve dugme kontrolu bir sure Facebook'a aktarak Facebook login'i yapacak ve gereken bilgileri bizim programimiza aktaracak. Java uzerinden FB Connect yapmak icin guzel bir ornek Java ile yazilmis "Random Friend" uygulamasi. Ornekte ne yazik ki gerekli jar dosyalari yok; Bu dosyalari biz ekleyerek, kodlari bir war dizini haline getirdik. Bizim versiyonumuzu suradan indirebilirsiniz. Bu programi Amazon EC2'daki bir makina uzerinde kurmayi ogrenecegiz.

Niye EC2 kullandik? Cunku Facebook'un baglanti sirasinda bizden hem veri almasi hem de bize veri gondermesi gerekiyor. Gonderebilmek icin tercihen firewall arkasinda olmayan, statik IP adresi ve ismi olan bir makina ile iletisim halinde olmali.

Amazon EC2 uzerinde bir makina yaratin. Hangi imaji kullanacagiz? Uzerinde Ubuntu Linux Server, JBoss, ve Apache iceren imaji kullanacagiz. Bu imajin kodu ami-4ea34727; Imaj hakkinda detayli bilgiler.

Makina yaratildiktan sonra ec2-describe-instances ile ismine bakin. Facebook'ta bir "uygulama" yaratirken bu isim lazim olacak . Her ne kadar gercek uygulama Facebook disinda isleyecek olsa bile, yine de FB'nin alisveris yapabilmesi icin FB uzerinde de bir uygulama yaratmis olmak lazim. Uygulama yaratma sayfasindan gerekli bilgileri giriyoruz. Callback URL yazan yere uygulamamizin tam ismini giriyoruz: http://ec2-filan-falan.amazonaws.com/randomfriendfacebook gibi.

Simdi verdigimiz zip dosyasini EC2'deki makinamiza scp ile kopyalayin. Unzip edin.

Facebook'ta uygulama yaratirken "API Key" adli bir kimlik yaratilmis olmali. Bu bilgiyi alin, ve connect.jsp ve showfriend.jsp dosyalarinda FB.Facebook.init cagrisina gecilmis olan kimligin yerine koyun.

Bu degistirilmis war dizinini imajinizda JBoss'un oldugu yere kopyalayin. Bu yer /var/local/jboss/jboss-4.2.2.GA/server/default/deploy olacak.

JBoss makinasini run.sh ile baslatin, arka plana atin.

Simdi Apache'yi baslatmamiz gerekecek (post 80 uzerinden 8080'e aktarma yapsin diye, yoksa baska taklalar atmamiz gerekecek; baska hicbir sey yapmaniza gerek yok, bu imaj zaten gerekli mod_jk ayarlarini yapmis).

/var/local/http/bin'de bin/apachectl start isletin.

Bitti! Artik http://ec2-vs.amazonaws.com/randomfriendfacebook/connect.jsp ile uygulamaniza baglanabilirsiniz. Burada Connect dugmesine basin, ve FB uzerinden login ettirilip showfriend.jsp sayfasina yonlendirildiginizi goreceksiniz. Bu sayfada arkadas listenizden rasgele birisi resmi ile beraber gosterilecektir.

Bu ornek tabii ki cok basit. Bundan sonraki orneklerimiz JSP degil, Servlet ya da EJB bazli olacak.

Amazon EC2 ile Barindirma

Amazon.com sirketi, kitap vb. seyler satmanin yaninda, bir suredir barindirma (hosting) servisi veriyor. Amazon.com Internet dunyasinin artik en eski e-ticaret sitelerinden, ve kendi e-ticaret islerini surdurebilmek icin satis yapan sitelerinin de devasa boyutlarda olmasi gerekliydi. Bu olcekte bir siteyi bu kadar uzun sure idare ederken, kendilerine sagladiklari servisi disaridaki son kullanilara da saglama gibi bir fikre erismis olmalilar.

Bu bizim gibi IT programcilari icin iyi haber. Amazon EC2 barindirma servisi, komut satirindan yazabileceginiz birkac satir sayesinde Amazon altyapisi icinde istediginiz sayida ve donanimda "sanal makinayi" yaratabilmenizi sagliyor. Bu makinalar bildigimiz araclar ssh ve scp kullanarak erisilebiliyor, ve bu makinalara giris yapinca yine alisageldigimiz Linux ya da Windows islemlerini yapabiliyoruz. Bu makinalara yeni programlar kurabiliyor, dosya kopyalayip, silebiliyor, program isletebiliyoruz. Makinalarin her birine root erisimimiz oluyor.

EC2 servisinde bir makinayi yaratmak icin oncelikle bir "imaj" gerekli. EC2 portfoyunde belli imajlar var, bu imajlar onceden baskalari tarafindan hazirlanmis (yazilim baglaminda) makina kurulum "tipleri". Mesela bir imaj Redhat Fedora Linux isletim sistemi uzerinde MySQL ve Apache programlarini iceren bir "paket" olabiliyor. Biz komut satirindan bir makinayi yaratirken her zaman bir imaj ismi veriyoruz, ve makina yaratilinca uzerinde imajin parcasi olan programlar hazir halde bizi bekliyor oluyor. Bir makinayi sifirdan alip (scp ile disaridan istedigimiz programlari aktararak kendi imajimizi kendimiz de yaratabiliriz, fakat bu uzun sureli bir islem olurdu tabii. Ayrica hazir bir imajdan baslayarak, kendi eklerimizi yaparak bize ozel bambaska bir imaji da yaratabiliyoruz. Bu imaji baskalari ile paylasmak ta mumkun, ve baskalari bu imaj uzerinden kendi sanal makinalari yarattiklarinda ayni programlari goruyor oluyorlar.

Tahmin edilebilecegi uzere, imajlar oldukca buyuk boyutlarda olacak, bu yuzden Amazon bu imajlari kendi dosyalama sistemi icinde muhafaza ediyor. Imajlari lokal bilgiyariniza indirmenize gerek kalmiyor. Amazon dosyalama servisinin ismi S3.

Odeme nasil yapiliyor? EC2 uzerinde yarattiginiz bilgisayarlar ne kadar sure kullanimda ise o sure karsiliginda bir "kira" oduyorsunuz. Mesela ufak boyutlarda bir sanal bilgisayar her saat icin $0.10. Ayrica bu makinadan gelen/giden veriye bakarak bir takim bedeller var. Su sayfadan tahmini kullanim verilerini girerek aylik odeyeceginiz bedeli hesaplayan bir araci bulabilirsiniz.

Amazon EC2'yi kullanmaya baslamak icin kredi kart bilginizi girmeniz gerekiyor; kullaniminizi baz alarak Amazon otomatik olarak bedeli kartinizdan kesiyor.

Bazi komutlar (komutlari nereden indirilip kullanmak icin cevre degiskenlerini nasil set etmeniz gerektigini suradan bulabilirsiniz):

Yarattiginiz makinalara bir anahtar cifti (key pair) yaratmaniz lazim; bu ec2-add-keypair [isim] ile. Buradan gelen verileri bir dosyaya kaydedin, ve artik bir makinayi yaratip, erisirken hep bu dosyayi referans edeceksiniz. Mesela bundan sonra id_rsa-gsg-keypair isimli dosyayi referans alalim.

Bir makinayi ami-4ea34727 imajini baz alarak yaratmak ve baslatmak icin

ec2-run-instances ami-4ea34727 -k id_rsa-gsg-keypair

Baslatmis oldugunuz tum makinalari gormek icin

ec2-describe-instances

Ustteki komuttan makinanizin host adresi ve instance kimligi gibi bilgileri alabilirsiniz. Instance bilgisi "i-" ile baslayan bir kimlik olacak. Bu kimligi bu makinaya referans etmek icin kullanabilirsiniz. Mesela makinayi durdurmak icin;

ec2-terminate-instances [kimlik]

Makinaniza ssh ile baglanmak icin ssh -i id_rsa-gsg-keypair root@[makina ismi]. Makina ismini yukarida bahsedilen listeden alin.

Dosya kopyalamak icin

scp -i id_rsa-gsg-keypair [dosya] root@[makina]

Ben su sekilde bir Unix alias yarattim; isleri rahatlastiriyor.

alias inst='ec2-describe-instances'
alias escp='scp -i id_rsa-gsg-keypair '
alias essh='ssh -i id_rsa-gsg-keypair '

Daha fazla bilgiyi baslangic (getting started) dokumanlarindan alabilirsiniz. Bu dokumandaki ilk ornegi harfi harfine takip edin. Iyi bir baslangic saglayacaktir.

Sunday, February 8, 2009

Alternatif Combobox

Standard HTML birimlerinden olan select..options birimlerinin ne yazik ki bazi problemleri var; Oncelikle IE 6 uzerinde bu select etiketlerini stillemek, yani CSS ile bazi goruntu ogelerini degistirmek mumkun degil. Bunlardan biri border degisimi mesela, siz CSS'e hangi komutu
koyarsaniz koyun, IE 6 uzerinde select o garip uc boyutumsu golgeli sInIrlI goruntuyu kaybedemiyor.


Bu sebeple klasik select..option yerine, CSS/DHTML/Javascript bazli alternatif bir Combobox kullanmak daha yerinde olacak. Bu alternatif kodlar <div> temelli olacak ve bu kodlar Javascript bazli event'leri kullanarak bir normal combobox isleyisini taklit edecekler. Bu birimler direk en temel DHTML ogeleri ile is yaptigi icin, onun herhangi bir gorsel ogesi ile oynamak serbest olabilecek.


Peki hangi paketi kullanmak en iyisi? Etrafta pek cok Javascript bazli combobox kodu var. Hem combobox hem de diger veri giris ogelerinin alternatifleri icin su sayfa faydali olabilir. Benim buldugum ayri bir paket dhtmlxcombo adinda bir pakettir. Bu paket, duz HTML temelli olan select'i alip onu combolastiriyor, ya da sadece bos bir <div> blogunu da alip combo haline getirebiliyor.


Bu kutuphaneyi kullanarak yazdigimiz ornek kodlari altta bulabilirsiniz. Onemli noktalardan biri combo'nun asagi gosteren ok imajini bulabilmesi icin <script> tagi icinde window.dhx_globalImgPath="/imaj/dizin/ismi"; ile ok imajinin yerini vermeniz. test.html icinde bunu gorebilirsiniz.

Dosyalar

dhtmlxcombo.js ve dhtmlxcommon.js ustteki kaynaklardan indirilebilir, ayrica bir blank.gif ve combo_select.gif lazim.

dhtmlxcombo.css

.dhx_combo_img{
    position:absolute;
    top:0px;
    right:0px;
    width:17px;
    height:20px;
}

.dhx_combo_option_img{
    position:relative;
    top:1px;
    margin-left:2px;
    left:0px;
    width:18px; height:18px;
}
.dhx_combo_input{
    color:#333333;
    font-family: Arial;
    font-size: 9pt;
    border:0px;
    padding:2px 2px 2px 2px;
    position:absolute;
    top:0px;
}
.dhx_combo_box{
    position:relative;
    text-align:left;
    border:1px solid #C3BBB6;
    height:20px;
    _height:22px;
    overflow:hidden;
    background-color: white;
}

.dhx_combo_list{
    position:absolute;
    z-index:230;
    overflow-y:auto;
    overflow-x:hidden;
    border:1px solid black;
    height:100px;
    font-family: Arial;
    font-size: 9pt;
    background-color: white;
}


.dhx_combo_list div{
    cursor:default;
    padding:2px 2px 2px 2px;
}
.dhx_selected_option{
    background-color:navy;
    color:white;
}


.dhx_combo_img_rtl{
    position:absolute;
    top:0px;
    left:1px;
    width:17px;
    height:20px;
}
.dhx_combo_option_img_rtl{
    float:right;
    margin-right :0px;
    width:18px; height:18px;
}

.dhx_combo_list_rtl{
    direction: rtl;
    unicode-bidi : bidi-override;
    position:absolute;
    z-index:230;
    overflow-y:auto;
    overflow-x:hidden;
    border:1px solid black;
    height:100px;
    font-family: Arial;
    font-size: 9pt;
    background-color: white;
}
.dhx_combo_list_rtl div{
    direction: rtl;
    unicode-bidi : bidi-override;
}
.dhx_combo_list_rtl div div{
    float :right !important;
    cursor:default;
    padding:2px 2px 2px 2px;
}
.dhx_combo_list_rtl div img{
    float :right !important;
}
.dhx_combo_list_rtl div input{
    float :right !important;
}

test.html

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script  src="dhtmlxcommon.js"></script>
    <script  src="dhtmlxcombo.js"></script>
    <link rel="STYLESHEET" type="text/css" href="dhtmlxcombo.css">
    <script>
      window.dhx_globalImgPath="/home/burak/";
    </script>
  </head>

  <body>

    <div id="combo_zone2" style="width:200px; height:30px;"></div>
    <script>
      var z=new dhtmlXCombo("combo_zone2","alfa3",200);
      z.addOption([[1,1111],[2,2222],[3,3333],[4,4444],[5,5555]]);
    </script>


  </body>


</html>