From 1222fffdc24abe1427f96b7c879c3bb555f5f0b1 Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Fri, 30 Mar 2012 16:30:24 +0300
Subject: [PATCH 1/7] added cookbook entry on using Twig Extension

---
 cookbook/templating/twig_extension.rst | 102 +++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 cookbook/templating/twig_extension.rst

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
new file mode 100644
index 00000000000..d632d5da664
--- /dev/null
+++ b/cookbook/templating/twig_extension.rst
@@ -0,0 +1,102 @@
+.. index::
+   single: Twig extensions
+   
+How to write a custom Twig extension
+============================================
+
+The main motivation for writing an extension is to move often used code into a reusable class like adding support for internationalization. 
+An extension can define tags, filters, tests, operators, global variables, functions, and node visitors.
+
+Creating an extension also makes for a better separation of code that is executed at compilation time and code needed at runtime. As such, it makes your code faster.
+
+.. tip::
+
+    Before writing your own extensions, have a look at the `Twig official extension repository`_.
+    
+Create the extension class
+--------------------------    
+
+To get your custom functionality you must first create a Twig Extension class. 
+As an example we will create a price filter to format a given number into price.
+
+   .. code-block:: php
+
+        <?php
+        
+        // src/Acme/DemoBundle/Twig/AcmeExtension.php
+
+        namespace Acme\DemoBundle\Twig;
+
+        use Twig_Extension;
+        use Twig_Filter_Method;
+        use Twig_Function_Method;
+
+        class AcmeExtension extends Twig_Extension
+        {
+            public function getFilters()
+            {
+                return array(
+                    'price' => new Twig_Filter_Method($this, 'priceFilter'),
+                );
+            }
+            
+            public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
+            {
+                $price = number_format($number, $decimals, $decPoint, $thousandsSep);
+                $price = '$' . $price;
+
+                return $price;
+            }
+
+            public function getName()
+            {
+                return 'acme_extension';
+            }
+        }
+     
+Register extension as a service
+-------------------------------
+
+Now you must let Service Container know about your newly created Twig Extension:
+
+.. configuration-block::
+
+    .. code-block:: xml
+        
+        <!-- src/Acme/DemoBundle/Resources/config/services.xml -->
+        <services>
+            <service id="acme.twig.acme_extension" class="Acme\DemoBundle\Twig\AcmeExtension">
+                <tag name="twig.extension" />
+            </service>
+        </services>
+
+    .. code-block:: yaml
+        
+        # src/Acme/DemoBundle/Resources/config/services.yml
+        services:
+            acme.twig.acme_extension:
+                class: Acme\DemoBundle\Twig\AcmeExtension
+                tags:
+                    - { name: twig.extension }
+
+    .. code-block:: php
+
+        // src/Acme/DemoBundle/Resources/config/services.php
+        use Symfony\Component\DependencyInjection\Definition;
+
+        $acmeDefinition = new Definition('\Acme\DemoBundle\Twig\AcmeExtension');
+        $acmeDefinition->addTag('twig.extension');
+        $container->setDefinition('acme.twig.acme_extension', $acmeDefinition);
+                
+                
+Using the custom extension
+---------------------------
+
+Using your newly created Twig Extension is no different than any other:
+
+.. code-block:: html+jinja
+
+    {# outputs $5,500.00 #}
+    {{ '5500' | price }}
+     
+.. _`Twig official extension repository`: http://github.com/fabpot/Twig-extensions
\ No newline at end of file

From 3970ba8704665b7773af32a50d33848655dac22b Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Fri, 30 Mar 2012 17:03:33 +0300
Subject: [PATCH 2/7] fixes for issues mentioned in comments by @weaverryan and
 @stof

---
 cookbook/templating/twig_extension.rst | 90 +++++++++++++++-----------
 1 file changed, 54 insertions(+), 36 deletions(-)

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
index d632d5da664..9aa5bdf4940 100644
--- a/cookbook/templating/twig_extension.rst
+++ b/cookbook/templating/twig_extension.rst
@@ -2,12 +2,16 @@
    single: Twig extensions
    
 How to write a custom Twig extension
-============================================
+====================================
 
-The main motivation for writing an extension is to move often used code into a reusable class like adding support for internationalization. 
-An extension can define tags, filters, tests, operators, global variables, functions, and node visitors.
+The main motivation for writing an extension is to move often used code
+into a reusable class like adding support for internationalization. 
+An extension can define tags, filters, tests, operators, global variables,
+functions, and node visitors.
 
-Creating an extension also makes for a better separation of code that is executed at compilation time and code needed at runtime. As such, it makes your code faster.
+Creating an extension also makes for a better separation of code that is
+executed at compilation time and code needed at runtime. As such, it makes
+your code faster.
 
 .. tip::
 
@@ -17,42 +21,42 @@ Create the extension class
 --------------------------    
 
 To get your custom functionality you must first create a Twig Extension class. 
-As an example we will create a price filter to format a given number into price.
+As an example we will create a price filter to format a given number into price::
 
-   .. code-block:: php
+    // src/Acme/DemoBundle/Twig/AcmeExtension.php
 
-        <?php
-        
-        // src/Acme/DemoBundle/Twig/AcmeExtension.php
+    namespace Acme\DemoBundle\Twig;
 
-        namespace Acme\DemoBundle\Twig;
+    use Twig_Extension;
+    use Twig_Filter_Method;
+    use Twig_Function_Method;
 
-        use Twig_Extension;
-        use Twig_Filter_Method;
-        use Twig_Function_Method;
+    class AcmeExtension extends Twig_Extension
+    {
+        public function getFilters()
+        {
+            return array(
+                'price' => new Twig_Filter_Method($this, 'priceFilter'),
+            );
+        }
+        
+        public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
+        {
+            $price = number_format($number, $decimals, $decPoint, $thousandsSep);
+            $price = '$' . $price;
+
+            return $price;
+        }
 
-        class AcmeExtension extends Twig_Extension
+        public function getName()
         {
-            public function getFilters()
-            {
-                return array(
-                    'price' => new Twig_Filter_Method($this, 'priceFilter'),
-                );
-            }
-            
-            public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
-            {
-                $price = number_format($number, $decimals, $decPoint, $thousandsSep);
-                $price = '$' . $price;
-
-                return $price;
-            }
-
-            public function getName()
-            {
-                return 'acme_extension';
-            }
+            return 'acme_extension';
         }
+    }
+    
+.. tip::
+
+    Along with custom filters, you can also add custom `functions` and register `global variables`.    
      
 Register extension as a service
 -------------------------------
@@ -87,10 +91,16 @@ Now you must let Service Container know about your newly created Twig Extension:
         $acmeDefinition = new Definition('\Acme\DemoBundle\Twig\AcmeExtension');
         $acmeDefinition->addTag('twig.extension');
         $container->setDefinition('acme.twig.acme_extension', $acmeDefinition);
-                
+         
+.. note::
+
+   Keep in mind that Twig Extensions are not lazily loaded. This means that 
+   there's a higher chance that you'll get a **CircularReferenceException**
+   or a **ScopeWideningInjectionException** if any services 
+   (or your Twig Extension in this case) are dependent on the request service.
                 
 Using the custom extension
----------------------------
+--------------------------
 
 Using your newly created Twig Extension is no different than any other:
 
@@ -98,5 +108,13 @@ Using your newly created Twig Extension is no different than any other:
 
     {# outputs $5,500.00 #}
     {{ '5500' | price }}
+    
+Learning further
+----------------
+    
+For a more in-depth look into Twig Extensions, please take a look at the `Twig extensions documentation`_.
      
-.. _`Twig official extension repository`: http://github.com/fabpot/Twig-extensions
\ No newline at end of file
+.. _`Twig official extension repository`: http://github.com/fabpot/Twig-extensions
+.. _`Twig extensions documentation`: http://twig.sensiolabs.org/doc/extensions.html
+.. _`global variables`: http://twig.sensiolabs.org/doc/extensions.html#globals
+.. _`functions`: http://twig.sensiolabs.org/doc/extensions.html#functions
\ No newline at end of file

From 36335c7a68e7424f45cdda22a5bedd71624dd595 Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Fri, 30 Mar 2012 17:12:18 +0300
Subject: [PATCH 3/7] passing arguments to filter example

---
 cookbook/templating/twig_extension.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
index 9aa5bdf4940..61bf5a7df7a 100644
--- a/cookbook/templating/twig_extension.rst
+++ b/cookbook/templating/twig_extension.rst
@@ -109,6 +109,13 @@ Using your newly created Twig Extension is no different than any other:
     {# outputs $5,500.00 #}
     {{ '5500' | price }}
     
+Passing other arguments to your filter:
+
+.. code-block:: html+jinja
+    
+    {# outputs $5500,2516 #}
+    {{ '5500.25155' | price(4, ',', '') }}
+    
 Learning further
 ----------------
     

From c04b3e99631296c2f70aa5291c736a5c81ddaca3 Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Fri, 30 Mar 2012 17:16:20 +0300
Subject: [PATCH 4/7] remove html tags from code-block example since there's
 only twig in there

---
 cookbook/templating/twig_extension.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
index 61bf5a7df7a..e1dd0e54488 100644
--- a/cookbook/templating/twig_extension.rst
+++ b/cookbook/templating/twig_extension.rst
@@ -104,14 +104,14 @@ Using the custom extension
 
 Using your newly created Twig Extension is no different than any other:
 
-.. code-block:: html+jinja
+.. code-block:: jinja
 
     {# outputs $5,500.00 #}
     {{ '5500' | price }}
     
 Passing other arguments to your filter:
 
-.. code-block:: html+jinja
+.. code-block:: jinja
     
     {# outputs $5500,2516 #}
     {{ '5500.25155' | price(4, ',', '') }}

From 15439181f2ad7db1cdf68e523f0bdff0df27094f Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Fri, 30 Mar 2012 17:23:34 +0300
Subject: [PATCH 5/7] updated index/map to represent this cookbook entry, added
 it to Templating page reference

---
 book/templating.rst  | 1 +
 cookbook/index.rst   | 1 +
 cookbook/map.rst.inc | 1 +
 3 files changed, 3 insertions(+)

diff --git a/book/templating.rst b/book/templating.rst
index 3b005642ea5..d6f184e94f8 100644
--- a/book/templating.rst
+++ b/book/templating.rst
@@ -1334,6 +1334,7 @@ Learn more from the Cookbook
 
 * :doc:`/cookbook/templating/PHP`
 * :doc:`/cookbook/controller/error_pages`
+* :doc:`/cookbook/templating/twig_extension`
 
 .. _`Twig`: http://twig.sensiolabs.org
 .. _`KnpBundles.com`: http://knpbundles.com
diff --git a/cookbook/index.rst b/cookbook/index.rst
index 7e2da2c062f..7e84001f325 100644
--- a/cookbook/index.rst
+++ b/cookbook/index.rst
@@ -71,6 +71,7 @@ Cookbook
 
     templating/global_variables
     templating/PHP
+    templating/twig_extension
 
     logging/monolog
     logging/monolog_email
diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc
index 301ad1ea01f..f65a331dbcd 100644
--- a/cookbook/map.rst.inc
+++ b/cookbook/map.rst.inc
@@ -92,6 +92,7 @@
 
   * :doc:`/cookbook/templating/global_variables`
   * :doc:`/cookbook/templating/PHP`
+  * :doc:`/cookbook/templating/twig_extension`
 
 * **Logging**
 

From a6a60ff01da90cc1fe55e1d4201282f96945d1e2 Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Tue, 3 Apr 2012 09:49:22 +0300
Subject: [PATCH 6/7] capitalize nouns in titles

---
 cookbook/templating/twig_extension.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
index e1dd0e54488..7b9cbfe024d 100644
--- a/cookbook/templating/twig_extension.rst
+++ b/cookbook/templating/twig_extension.rst
@@ -1,7 +1,7 @@
 .. index::
    single: Twig extensions
    
-How to write a custom Twig extension
+How to write a custom Twig Extension
 ====================================
 
 The main motivation for writing an extension is to move often used code
@@ -17,7 +17,7 @@ your code faster.
 
     Before writing your own extensions, have a look at the `Twig official extension repository`_.
     
-Create the extension class
+Create the Extension Class
 --------------------------    
 
 To get your custom functionality you must first create a Twig Extension class. 
@@ -58,7 +58,7 @@ As an example we will create a price filter to format a given number into price:
 
     Along with custom filters, you can also add custom `functions` and register `global variables`.    
      
-Register extension as a service
+Register an Extension as a Service
 -------------------------------
 
 Now you must let Service Container know about your newly created Twig Extension:
@@ -99,7 +99,7 @@ Now you must let Service Container know about your newly created Twig Extension:
    or a **ScopeWideningInjectionException** if any services 
    (or your Twig Extension in this case) are dependent on the request service.
                 
-Using the custom extension
+Using the custom Extension
 --------------------------
 
 Using your newly created Twig Extension is no different than any other:

From 61a5042868f7e66cdaca2be6bdeed0a94564d818 Mon Sep 17 00:00:00 2001
From: Roman Marintsenko <inoryy@gmail.com>
Date: Tue, 3 Apr 2012 10:41:22 +0300
Subject: [PATCH 7/7] added a reference to scopes documentation

---
 cookbook/templating/twig_extension.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cookbook/templating/twig_extension.rst b/cookbook/templating/twig_extension.rst
index 7b9cbfe024d..6f105f4dfbc 100644
--- a/cookbook/templating/twig_extension.rst
+++ b/cookbook/templating/twig_extension.rst
@@ -98,6 +98,7 @@ Now you must let Service Container know about your newly created Twig Extension:
    there's a higher chance that you'll get a **CircularReferenceException**
    or a **ScopeWideningInjectionException** if any services 
    (or your Twig Extension in this case) are dependent on the request service.
+   For more information take a look at :doc:`/cookbook/service_container/scopes`.
                 
 Using the custom Extension
 --------------------------