Yeoman ve Polymer ile web uygulamaları oluşturma

Modern araçlarla web uygulamalarınızın iskeletini oluşturma

Giriş

Merhaba. Web uygulaması yazan herkes, üretkenliği korumanın ne kadar önemli olduğunu bilir. Doğru şablonu bulma, geliştirme ve test iş akışı oluşturma, tüm kaynaklarınızı sadeleştirme ve sıkıştırma gibi sıkıcı görevlerle uğraşmak zorunda kaldığınızda bu durum zorlayıcı olabilir.

Neyse ki modern ön uç araçları, bu işlemlerin çoğunu otomatikleştirmenize yardımcı olarak muhteşem bir uygulama yazmaya odaklanmanızı sağlar. Bu makalede, Web Bileşenleri kullanarak uygulama geliştirmek için polyfill'ler ve şekerlerden oluşan bir kitaplık olan Polymer'ı kullanarak uygulama oluşturmayı kolaylaştırmak amacıyla web uygulamalarına yönelik bir araç iş akışı olan Yeoman'ı nasıl kullanacağınız gösterilmektedir.

Yeoman

Yo, Grunt ve Bower ile tanışın

Yeoman, üretkenliğinizi artırmak için üç araç sunan, şapkalı bir adamdır:

  • yo, daha önce bahsettiğim sıkıcı görevlerden bazılarını gerçekleştirmek için kullanılabilecek, oluşturucu adı verilen çerçeveye özgü iskelelerden oluşan bir ekosistem sunan bir iskele aracıdır.
  • grunt, Yeoman ekibi ve grunt-contrib tarafından seçilen görevlerin yardımıyla projenizi oluşturmak, önizlemek ve test etmek için kullanılır.
  • bower, bağımlılık yönetimi için kullanılır. Böylece, komut dosyalarınızı manuel olarak indirip yönetmeniz gerekmez.

Yeoman, yalnızca bir veya iki komutla uygulamanız (veya Modeller gibi ayrı parçalar) için ortak metin kodu yazabilir, Sass'ınızı derleyebilir, CSS, JS, HTML ve resimlerinizi küçültüp birleştirebilir ve mevcut dizininizde basit bir web sunucusu başlatabilir. Ayrıca birim testlerinizi ve daha fazlasını çalıştırabilir.

Oluşturucuları Node Packaged Modules'dan (npm) yükleyebilirsiniz. Şu anda 220'den fazla oluşturucu mevcuttur ve bunların çoğu açık kaynak topluluğu tarafından yazılmıştır. Popüler oluşturucular arasında generator-angular, generator-backbone ve generator-ember bulunur.

Yeoman ana sayfası

Node.js'nin yeni bir sürümünü yükledikten sonra terminalinizi açıp şu komutu çalıştırın:

$ npm install -g yo

İşte bu kadar. Artık Yo, Grunt ve Bower'a sahipsiniz ve bunları doğrudan komut satırından çalıştırabilirsiniz. yo komutunu çalıştırmanın sonucu şu şekildedir:

Yeoman kurulumu

Polymer oluşturucu

Daha önce de belirttiğim gibi Polymer, modern tarayıcılarda web bileşenlerinin kullanılmasını sağlayan bir polyfill ve sugar kitaplığıdır. Proje, geliştiricilerin geleceğin platformunu kullanarak uygulamalar oluşturmasına ve W3C'yi, devam eden spesifikasyonların daha da iyileştirilebileceği yerler hakkında bilgilendirmesine olanak tanır.

Polymer oluşturucu ana sayfası

generator-polymer, Yeoman kullanarak Polymer uygulamalarının iskeletini oluşturmanıza yardımcı olan yeni bir oluşturucudur. Bu oluşturucu, komut satırı aracılığıyla Polymer (özel) öğelerini kolayca oluşturup özelleştirmenize ve HTML içe aktarma işlemlerini kullanarak içe aktarmanıza olanak tanır. Bu sayede, ortak metin kodunu sizin yerinize yazarak zamandan tasarruf etmenizi sağlar.

Ardından, aşağıdaki komutu çalıştırarak Polymer'in oluşturucusunu yükleyin:

$ npm install generator-polymer -g

Bu kadar basit. Artık uygulamanız Web Bileşeni süper güçlerine sahip.

Yeni kurulan jeneratörümüzde erişebileceğiniz birkaç özel parça var:

  • polymer:element, yeni bağımsız Polymer öğeleri oluşturmak için kullanılır. Örneğin: yo polymer:element carousel
  • polymer:app, ilk index.html dosyanızı, projeniz için derleme zamanı yapılandırmasını içeren bir Gruntfile.js dosyasını, Grunt görevlerini ve proje için önerilen klasör yapısını oluşturmak amacıyla kullanılır. Ayrıca projenizin stilleri için Sass Bootstrap kullanma seçeneği de sunulur.

Polymer uygulaması oluşturalım

Bazı özel Polymer öğelerini ve yeni oluşturucumuzu kullanarak basit bir blog oluşturacağız.

Polymer uygulaması

Başlamak için terminale gidin, yeni bir dizin oluşturun ve mkdir my-new-project && cd $_ komutunu kullanarak bu dizine geçin. Artık aşağıdaki komutu çalıştırarak Polymer uygulamanızı başlatabilirsiniz:

$ yo polymer
Polymer uygulaması oluşturma

Bu komut, Bower'dan Polymer'ın en yeni sürümünü alır ve iş akışınız için bir index.html, dizin yapısı ve Grunt görevleri oluşturur. Uygulamanın hazırlanmasını beklerken bir kahve içmeye ne dersiniz?

Şimdi, uygulamanın nasıl göründüğünü önizlemek için grunt server komutunu çalıştırabiliriz:

Grunt sunucusu

Sunucu, LiveReload'u destekler. Yani bir metin düzenleyiciyi başlatabilir, özel bir öğeyi düzenleyebilirsiniz. Tarayıcı, kaydetme işlemi sırasında yeniden yüklenir. Bu sayede uygulamanızın mevcut durumunu gerçek zamanlı olarak görebilirsiniz.

Şimdi bir blog yayınını temsil edecek yeni bir Polymer öğesi oluşturalım.

$ yo polymer:element post
Gönderi oluşturma öğesi

Yeoman bize, bir kurucu eklemek isteyip istemediğimiz veya yayın öğesini index.html içine eklemek için HTML içe aktarma kullanıp kullanmayacağımız gibi birkaç soru sorar. Şimdilik ilk iki seçenek için "Hayır"ı seçelim ve üçüncü seçeneği boş bırakalım.

$ yo polymer:element post

[?] Would you like to include constructor=''? No

[?] Import to your index.html using HTML imports? No

[?] Import other elements into this one? (e.g 'another_element.html' or leave blank)

    create app/elements/post.html

Bu işlem, /elements dizininde post.html adında yeni bir Polymer öğesi oluşturur:

<polymer-element name="post-element"  attributes="">

    <template>

    <style>
        @host { :scope {display: block;} }
    </style>

    <span>I'm <b>post-element</b>. This is my Shadow DOM.</span>

    </template>

    <script>

    Polymer('post-element', {

        //applyAuthorStyles: true,

        //resetStyleInheritance: true,

        created: function() { },

        enteredView: function() { },

        leftView: function() { },

        attributeChanged: function(attrName, oldVal, newVal) { }

    });

    </script>

</polymer-element>

Şunları içerir:

Gerçek bir veri kaynağıyla çalışma

Blogumuzda yeni yayınların yazılıp okunabileceği bir yer olması gerekir. Gerçek bir veri hizmetiyle çalışmayı göstermek için Google Apps Spreadsheets API'yi kullanacağız. Bu sayede, Google Dokümanlar kullanılarak oluşturulan tüm e-tabloların içeriğini kolayca okuyabiliriz.

Şimdi bu ayarı yapalım:

  1. Tarayıcınızda (bu adımlar için Chrome önerilir) bu Google Dokümanlar e-tablosunu açın. Aşağıdaki alanlarda örnek yayın verileri bulunur:

    • Kimlik
    • Başlık
    • Yazar
    • İçerik
    • Tarih
    • Anahtar kelimeler
    • E-posta (yazarın)
    • Kısa ad (gönderinizin kısa ad URL'si için)
  2. Dosya menüsüne gidin ve e-tablonun kendi kopyanızı oluşturmak için Kopya oluştur'u seçin. İçeriği dilediğiniz zaman düzenleyebilir, yayın ekleyebilir veya kaldırabilirsiniz.

  3. Dosya menüsüne tekrar gidin ve Web'de yayınla'yı seçin.

  4. Yayınlamaya başla'yı tıklayın.

  5. Yayınlanan verilerin bağlantısını alın bölümünde, son metin kutusundan sağlanan URL'nin anahtar kısmını kopyalayın. Şu şekilde görünür: https://docs.google.com/spreadsheet/ccc?key=0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc#gid=0

  6. Anahtarı, aşağıdaki URL'de your-key-goes-here yazan yere yapıştırın: https://spreadsheets.google.com/feeds/list/your-key-goes-here/od6/public/values?alt=json-in-script&callback=. Yukarıdaki anahtarı kullanan bir örnek şu şekilde görünebilir: https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc/od6/public/values?alt=json-in-script.

  7. URL'yi tarayıcınıza yapıştırıp blog içeriğinizin JSON sürümünü görüntüleyebilirsiniz. URL'yi not edin ve daha sonra ekranda göstermek için üzerinde iterasyon yapmanız gerekeceğinden bu verilerin biçimini incelemek için biraz zaman ayırın.

Tarayıcınızdaki JSON çıkışı biraz göz korkutucu görünebilir ancak endişelenmeyin. Yalnızca yayınlarınızla ilgili verilerle ilgileniyoruz.

Google Spreadsheets API, blog e-tablonuzdaki her alanı özel bir ön ek post.gsx$ ile çıkarır. Örneğin: post.gsx$title.$t, post.gsx$author.$t, post.gsx$content.$t vb. JSON çıkışımızdaki her "satır" üzerinde iterasyon yaptığımızda, her yayın için alakalı değerleri geri almak üzere bu alanlara referans veririz.

Artık yeni oluşturulan yayın öğenizi düzenleyerek işaretleme bölümlerini e-tablonuzdaki verilere bağlayabilirsiniz. Bunun için, daha önce oluşturduğumuz yayın başlığı, yazar, içerik ve diğer alanları okuyacak bir post özelliği ekleriz. selected özelliği (daha sonra dolduracağız), yalnızca kullanıcı doğru kısa URL'ye gittiğinde bir yayını göstermek için kullanılır.

<polymer-element name="post-element" attributes="post selected">

    <template>

    <style>
        @host { :scope {display: block;} }
    </style>

        <div class="col-lg-4">

            <template if="[[post.gsx$slug.$t === selected]]">

            <h2>
                <a href="#[[post.gsx$slug.$t]]">
                [[post.gsx$title.$t  ]]
                </a>
            </h2>

            <p>By [[post.gsx$author.$t]]</p>

            <p>[[post.gsx$content.$t]]</p>

            <p>Published on: [[post.gsx$date.$t]]</p>

            <small>Keywords: [[post.gsx$keywords.$t]]</small>

            </template>

        </div>

    </template>

    <script>

    Polymer('post-element', {

        created: function() { },

        enteredView: function() { },

        leftView: function() { },

        attributeChanged: function(attrName, oldVal, newVal) { }

    });

    </script>

</polymer-element>

Şimdi yo polymer:element blog komutunu çalıştırarak hem yayın koleksiyonunu hem de blogunuzun düzenini içeren bir blog öğesi oluşturalım.

$ yo polymer:element blog

[?] Would you like to include constructor=''? No

[?] Import to your index.html using HTML imports? Yes

[?] Import other elements into this one? (e.g 'another_element.html' or leave blank) post.html

    create app/elements/blog.html

Bu kez, sayfada görünmesini istediğimiz için HTML içe aktarmalarını kullanarak blogu index.html dosyasına aktarırız. Özellikle üçüncü istem için, dahil etmek istediğimiz öğe olarak post.html değerini belirtiyoruz.

Önceki gibi yeni bir öğe dosyası oluşturulur (blog.html) ve /elements dizinine eklenir. Bu kez post.html içe aktarılır ve şablon etiketine <post-element> eklenir:

<link rel="import" href="post.html">

<polymer-element name="blog-element"  attributes="">

    <template>

    <style>
        @host { :scope {display: block;} }
    </style>

    <span>I'm <b>blog-element</b>. This is my Shadow DOM.</span>

        <post-element></post-element>

    </template>

    <script>

    Polymer('blog-element', {

        //applyAuthorStyles: true,

        //resetStyleInheritance: true,

        created: function() { },

        enteredView: function() { },

        leftView: function() { },

        attributeChanged: function(attrName, oldVal, newVal) { }

    });

    </script>

</polymer-element>

Blog öğesinin dizinimize HTML içe aktarmaları (HTML belgelerini diğer HTML belgelerine dahil etmenin ve yeniden kullanmanın bir yolu) kullanılarak içe aktarılmasını istediğimiz için, belgeye doğru şekilde eklendiğini de doğrulayabiliriz <head>:

<!doctype html>
    <head>

        <meta charset="utf-8">

        <meta http-equiv="X-UA-Compatible" content="IE=edge">

        <title></title>

        <meta name="description" content="">

        <meta name="viewport" content="width=device-width">

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

        <!-- build:js scripts/vendor/modernizr.js -->

        <script src="bower_components/modernizr/modernizr.js"></script>

        <!-- endbuild -->

        <!-- Place your HTML imports here -->

        <link rel="import" href="elements/blog.html">

    </head>

    <body>

        <div class="container">

            <div class="hero-unit" style="width:90%">

                <blog-element></blog-element>

            </div>

        </div>

        <script>
        document.addEventListener('WebComponentsReady', function() {
            // Perform some behaviour
        });
        </script>

        <!-- build:js scripts/vendor.js -->

        <script src="bower_components/polymer/polymer.min.js"></script>

        <!-- endbuild -->

</body>

</html>

Güzel.

Bower kullanarak bağımlılık ekleme

Şimdi, posts.json dosyasını okumak için Polymer JSONP yardımcı öğesini kullanacak şekilde öğemizi düzenleyelim. Bağdaştırıcıyı, depoyu git ile klonlayarak veya bower install polymer-elements komutunu çalıştırıp Bower aracılığıyla polymer-elements paketini yükleyerek edinebilirsiniz.

Bower bağımlılıkları

Yardımcı programı aldıktan sonra, blog.html öğenize aşağıdaki gibi bir içe aktarma işlemi olarak eklemeniz gerekir:

<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">

Ardından, bunun etiketini ekleyin ve daha önceki blog yayınları e-tablomuza url değerini girip sonuna &callback= ekleyin:

<polymer-jsonp auto url="https://spreadsheets.google.com/feeds/list/your-key-value/od6/public/values?alt=json-in-script&callback=" response="[[posts]]"></polymer-jsonp>

Bu işlem tamamlandıktan sonra, e-tablomuz okunduktan sonra üzerinde iterasyon yapacak şablonlar ekleyebiliriz. İlkinde, bir yayının kısa URL'sine yönlendiren bağlantılı başlığın yer aldığı bir içindekiler tablosu oluşturulur.

<!-- Table of contents -->

<ul>

    <template repeat="[[post in posts.feed.entry]]">

    <li><a href="#[[post.gsx$slug.$t]]">[[post.gsx$title.$t]]</a></li>

    </template>

</ul>

İkincisi, bulunan her giriş için bir post-element örneği oluşturur ve yayın içeriğini buna göre iletir. Tek bir e-tablo satırının yayın içeriğini temsil eden bir post özelliği ve bir rotayla dolduracağımız selected özelliğini ilettiğimizi görebilirsiniz.

<!-- Post content -->

<template repeat="[[post in posts.feed.entry]]">

    <post-element post="[[post]]" selected="[[route]]"></post-element>

</template>

Şablonumuzda kullanılan repeat özelliği, sağlandığında yayınlarımızın dizi koleksiyonundaki her öğe için [[ bindings ]] içeren bir örnek oluşturur ve bunu korur.

Polymer uygulaması

Şimdi geçerli [[route]]'un doldurulması için hile yapıp URL karması her değiştiğinde [[route]]'a bağlanan Flatiron director adlı bir kitaplığı kullanacağız.

Neyse ki bunun için kullanabileceğimiz bir Polymer öğesi (more-elements paketinin bir parçası) var. /elements dizinine kopyalandıktan sonra, <flatiron-director route="[[route]]" autoHash></flatiron-director> ile referans verebilir, bağlamak istediğimiz özellik olarak route değerini belirtebilir ve karma değişikliklerinin değerini otomatik olarak okumasını (autoHash) söyleyebiliriz.

Tüm bunları bir araya getirdiğimizde şu sonuca ulaşırız:

    <link rel="import" href="post.html">

    <link rel="import" href="polymer-jsonp/polymer-jsonp.html">

    <link rel="import" href="flatiron-director/flatiron-director.html">

    <polymer-element name="blog-element"  attributes="">

      <template>

        <style>
          @host { :scope {display: block;} }
        </style>

        <div class="row">

          <h1><a href="/#">My Polymer Blog</a></h1>

          <flatiron-director route="[[route]]" autoHash></flatiron-director>

          <h2>Posts</h2>

          <!-- Table of contents -->

          <ul>

            <template repeat="[[post in posts.feed.entry]]">

              <li><a href="#[[post.gsx$slug.$t]]">[[post.gsx$title.$t]]</a></li>

            </template>

          </ul>

          <!-- Post content -->

          <template repeat="[[post in posts.feed.entry]]">

            <post-element post="[[post]]" selected="[[route]]"></post-element>

          </template>

        </div>

        <polymer-jsonp auto url="https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdHVQUGd2M2Q0MEZnRms3c3dDQWQ3V1E/od6/public/values?alt=json-in-script&callback=" response="[[posts]]"></polymer-jsonp>

      </template>

      <script>

        Polymer('blog-element', {

          created: function() {},

          enteredView: function() { },

          leftView: function() { },

          attributeChanged: function(attrName, oldVal, newVal) { }

        });

      </script>

    </polymer-element>
Polymer Uygulaması

Harika! Artık JSON'dan veri okuyan ve Yeoman ile iskeleti oluşturulmuş iki Polymer öğesi kullanan basit bir blogumuz var.

Üçüncü taraf öğelerle çalışma

Web Bileşenleri'ni çevreleyen öğe ekosistemi, son zamanlarda customelements.io gibi bileşen galerisi sitelerinin ortaya çıkmasıyla büyümeye başladı. Topluluk tarafından oluşturulan öğelere baktığımda gravatar profillerini getiren bir öğe buldum. Bu öğeyi alıp blog sitemize ekleyebiliriz.

Özel öğeler ana sayfası

Gravatar öğesi kaynaklarını /elements dizininize kopyalayın, HTML içe aktarma işlemleri aracılığıyla post.html dosyasına ekleyin ve ardından öğesini şablonunuza ekleyerek e-tablomuzdaki e-posta alanını kullanıcı adının kaynağı olarak iletin. İşte bu kadar!

<link rel="import" href="gravatar-element/src/gravatar.html">

<polymer-element name="post-element" attributes="post selected">

    <template>

    <style>
        @host { :scope {display: block;} }
    </style>

        <div class="col-lg-4">

            <template if="[[post.gsx$slug.$t === selected]]">

            <h2><a href="#[[post.gsx$slug.$t]]">[[post.gsx$title.$t]]</a></h2>

            <p>By [[post.gsx$author.$t]]</p>

            <gravatar-element username="[[post.gsx$email.$t]]" size="100"></gravatar-element>

            <p>[[post.gsx$content.$t]]</p>

            <p>[[post.gsx$date.$t]]</p>

            <small>Keywords: [[post.gsx$keywords.$t]]</small>

            </template>

        </div>

    </template>

    <script>

    Polymer('post-element', {

        created: function() { },

        enteredView: function() { },

        leftView: function() { },

        attributeChanged: function(attrName, oldVal, newVal) { }

    });

    </script>

</polymer-element>

Bunun bize ne sağladığına bir bakalım:

Özel öğeler içeren Polymer uygulaması

Çok güzel.

Nispeten kısa bir sürede, ortak metin kodu yazma, bağımlılıkları manuel olarak indirme veya yerel sunucu ya da derleme iş akışı oluşturma konusunda endişelenmeden birkaç web bileşeninden oluşan basit bir uygulama oluşturduk.

Uygulamanızı optimize etme

Yeoman iş akışı, Grunt adlı başka bir açık kaynak projeyi içerir. Grunt, uygulamanızın optimize edilmiş bir sürümünü oluşturmak için derlemeye özgü bir dizi görevi (bir Gruntfile'da tanımlanır) çalıştırabilen bir görev çalıştırıcıdır. grunt komutunu tek başına çalıştırmak, oluşturucunun linting, test ve derleme için ayarladığı bir default görevini yürütür:

grunt.registerTask('default', [

    'jshint',

    'test',

    'build'

]);

Yukarıdaki jshint görevi, tercihlerinizi öğrenmek için .jshintrc dosyanızı kontrol eder ve ardından projenizdeki tüm JavaScript dosyalarında çalıştırır. JSHint ile ilgili seçeneklerinizin tam listesini görmek için belgelere göz atın.

test görevi şuna benzer ve uygulamanızı, önerdiğimiz test çerçevesi olan Mocha için oluşturup sunabilir. Ayrıca testlerinizi sizin için yürütür:

grunt.registerTask('test', [

    'clean:server',

    'createDefaultTemplate',

    'jst',

    'compass',

    'connect:test',

    'mocha'

]);

Bu örnekteki uygulamamız oldukça basit olduğundan test yazma işlemini ayrı bir alıştırma olarak size bırakacağız. Derleme sürecimizin işlemesi gereken birkaç şey daha var. Bu nedenle, Gruntfile.js dosyamızda tanımlanan grunt build görevinin ne yapacağına bir göz atalım:

grunt.registerTask('build', [

    'clean:dist',    // Clears out your .tmp/ and dist/ folders

    'compass:dist',  // Compiles your Sassiness

    'useminPrepare', // Looks for <!-- special blocks --> in your HTML

    'imagemin',      // Optimizes your images!

    'htmlmin',       // Minifies your HTML files

    'concat',        // Task used to concatenate your JS and CSS

    'cssmin',        // Minifies your CSS files

    'uglify',        // Task used to minify your JS

    'copy',          // Copies files from .tmp/ and app/ into dist/

    'usemin'         // Updates the references in your HTML with the new files

]);

grunt build komutunu çalıştırdığınızda uygulamanızın üretime hazır bir sürümü oluşturulur ve gönderilmeye hazır hale gelir. Birlikte deneyelim.

Grunt derlemesi

Başarılı aktarım

Takılırsanız polymer-blog'un önceden oluşturulmuş bir sürümünü https://github.com/addyosmani/polymer-blog adresinden inceleyebilirsiniz.

Sizi bekleyen başka neler var?

Web Bileşenleri ve bunlarla ilgili araçlar hâlâ gelişim aşamasındadır.

Şu anda, Vulcanize (Polymer projesinin bir aracı) gibi projeler aracılığıyla daha iyi yükleme performansı için HTML içe aktarmalarının nasıl birleştirilebileceğini ve bileşen ekosisteminin Bower gibi bir paket yöneticisiyle nasıl çalışabileceğini inceliyoruz.

Bu sorulara daha iyi yanıtlar bulduğumuzda sizi bilgilendireceğiz. Ancak önümüzde heyecan verici bir süreç var.

Bower ile Polymer'i bağımsız olarak yükleme

Polymer'e daha hafif bir başlangıç yapmak isterseniz aşağıdaki komutu çalıştırarak doğrudan Bower'dan bağımsız olarak yükleyebilirsiniz:

bower install polymer

Bu işlem, paketi bower_components dizininize ekler. Ardından, uygulama dizininizde manuel olarak referans verebilir ve geleceğe damganızı vurabilirsiniz.

Ne düşünüyorsunuz?

Artık Yeoman ile Web Bileşenleri'ni kullanarak bir Polymer uygulamasının iskeletini nasıl oluşturacağınızı biliyorsunuz. Oluşturucuyla ilgili geri bildiriminiz varsa lütfen yorumlarda bize bildirin, hata bildiriminde bulunun veya Yeoman Issue Tracker'da yayınlayın. Üreticiyi geliştirebilmemiz için kullanımınıza ve geri bildirimlerinize ihtiyacımız var. Bu nedenle, üreticinin daha iyi yapmasını istediğiniz başka bir şey varsa lütfen bize bildirin. :)