Monthly Archives: Ocak 2015

Genel

__getattr__ vs. __getattribute__

__getattr__ Kullanımı:
__getattr__, uygulamada bir sınıfın varolmayan bir özelliğine ulaşılmak istendiğinde çağırılen bir magic metoddur.

class Order(object):
    def __init__(self, order_id=None, amount=None, currency=None, *args, **kwargs):
        self.order_id = None
        self.amount = amount
        self.currency = currency

    def __getattr__(self, attr):
        print "%s is called" % attr


order = Order(order_id='00001', amount=100, currency='TRL')
print order.amount
print order.original_amount


Çıktı:

100
original_amount is called
None

__getattribute__ Kullanımı:
__getattribute__, uygulamada bir sınıfın herhangibir özelliğine ulaşılmak istendiğinde çağırılen bir magic metoddur.

class Order(object):
    def __init__(self, order_id=None, amount=None, currency=None, *args, **kwargs):
        self.order_id = None
        self.amount = amount
        self.currency = currency

    def __getattribute__(self, attr):
        print "%s is called" % attr


order = Order(order_id='00001', amount=100, currency='TRL')
print order.amount
print order.original_amount

Çıktı:

amount is called
None
original_amount is called
None
Genel

Symfony2 Kullanıcıları İçin Twig Eklentisi Geliştirme

Bu yazıda Symfony2 ile bundle olarak gelen TWIG template motoru için basitce nasıl eklenti geliştirebileceğimizi inceleyeceğiz.

Eklentiler Ne İşe Yarar ?

TWIG Eklentileri template içerisinde özel olarak geliştirdiğiniz fonksiyonlar, filtreler ve global değişkenleri kullanabilmenize olanak sağlar.

Ne Zaman Eklentiye İhtiyaç Duyulur ?

Eklentiler sıklıkla önyüzde göstermek istediğiniz bilgiler, template context’ ine değişken gönderek yapmak zorunda olduğunuz kontrolleri ve bundan kaynaklanan kod tekrarlarını önlemek için kullanılır. Aşağıda twig eklentisi kullanımına örnek durumlardan biri görülmektedir.

Örnek Durum:

Ekrana fiyat bastırmamız gereken her durumda sistem kurunu çekip önyüzde göstermemiz gerekiyor.

Hatalı Çözüm 1:

Hardcoded olarak kuru template’de belirtir, kur değişiminde tüm templateleri güncelleriz :)

...
<div class="product-price">
	{{ product.price }} <span class="currency">TL</span>
</div>
...

Hatalı Çözüm 2:

İlgili controller aksiyonunda sistem kurunu çeker, template context’ine iletiriz. Ancak bu işlemi fiyat geçen her aksiyonda yapmamız gerekir.
company/CatalogBundle/Controller/ProductController.php:

	&lt;?php
	class ProductController extends Controlller
	{
		//...
		public function detailAction($productId)
		{
			//...
			// $product = ...
			// $configuration = ...
			//..
			$currencySymbol = $configuration->system->currencySymbol;
			return $this->render('CompanyCatalogBundle:Product:detail.html.twig', array(
				'product' => $product,
				'currencySymbol' = $currencySymbol
			));
		}
		//...
	}

company/CatalogBundle/Resources/views/Product/detail.html.twig:

...
<div class="product-price">
	{{ product.price }} <span class="currency">{{ currencySymbol }}</span>
</div>
...

Eklenti Kullanarak Gerçekleştirebileceğiniz Doğru Çözüm:

Aşağıda gördüğünüz üzere kendi geliştirdiğimiz twig eklentisindeki price filtresini kullanarak ekrana “25.00 TL” şeklinde biçimlendirilmiş ve güncel sistem kurunu içeren bir çıktı basmak son derece basit.

...
<div class="product-price">
	{{ product.price | price }} 
</div>
...

TWIG Eklentisi Geliştirmek

TWIG Eklentileri, aşağıdaki arayüzden görebildiğiniz üzere template tarafında kullanabileceğiniz fonksiyonlar, global değişkenler ve filtreler içerebilmektedir.

interface Twig_ExtensionInterface
{
    /**
     * Initializes the runtime environment.
     *
     * This is where you can load some file that contains filter functions for instance.
     *
     * @param Twig_Environment $environment The current Twig_Environment instance
     */
    function initRuntime(Twig_Environment $environment);

    /**
     * Returns the token parser instances to add to the existing list.
     *
     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
     */
    function getTokenParsers();

    /**
     * Returns the node visitor instances to add to the existing list.
     *
     * @return array An array of Twig_NodeVisitorInterface instances
     */
    function getNodeVisitors();

    /**
     * Returns a list of filters to add to the existing list.
     *
     * @return array An array of filters
     */
    function getFilters();

    /**
     * Returns a list of tests to add to the existing list.
     *
     * @return array An array of tests
     */
    function getTests();

    /**
     * Returns a list of functions to add to the existing list.
     *
     * @return array An array of functions
     */
    function getFunctions();

    /**
     * Returns a list of operators to add to the existing list.
     *
     * @return array An array of operators
     */
    function getOperators();

    /**
     * Returns a list of global variables to add to the existing list.
     *
     * @return array An array of global variables
     */
    function getGlobals();

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    function getName();
}

Kullanıcılar tarafından geliştirilecek olan eklentiler, Twig’in bu arayüzü uyarlayan Twig_Extension sınıfını extend eden bir sınıf şeklindedir. Yapılacak geliştirmeye bağlı olarak arayüzdeki ilgili metodlar ezilerek template tarafında kullanacağımız fonksiyon, filtre veya global değişken ile ilgili geliştirmeyi yapabiliriz.

Örnek twig eklentisi sınıfı:

&lt;php
class CatalogExtension extends \Twig_Extension
{
	public function getFilters()
	{
		return array(
			//...
		);
	}
}

Arayüzde görülen her bir metod, filtre, fonksiyon veya global değişkenin adını ve çalıştıracağı callback ile ilgili bilgileri içeren bir dizi dönmelidir.
Company/CatalogBundle/Twig/Extension/CatalogExtension.php:

&lt;php
namespace Company\CatalogBundle\Twig\Extension;

class CatalogExtension extends \Twig_Extension
{
	public function getName()
	{
		return 'catalog_extension';
	}

	public function getFilters()
	{
		return array(
			new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
		);
	}

	public function priceFilter($price)
	{
		//..
		// $configuration = ...
		$currencySymbol = $configuration->system->currencySymbol;
		return sprintf("%s <span class="currency">%s</span>"
			number_format($price, 2, ".", ","),
			currencySymbol);
	}
}

Eklentimizi kullanabilmek için servis olarak kaydediyoruz.
Company\CatalogBundle\Resources\config\services.yml:

services:
	comapny.catalog.twig.extension.catalog:
		class: Company\CatalogBundle\Twig\Extension\CatalogExtension
        tags:
            - { name: twig.extension }

Son olarak geliştirdiğimiz eklentideki filtreyi nasıl kullandığımızı tekrar hatırlayalım.

...
<div class="product-price">
	{{ product.price | price }} 
</div>
...

Diğer kullanım şekilleri ile ilgili detaylı bilgi için bu sayfayı ziyaret edebilirsiniz.