टहनी या स्थिरांक के लिए एक सरल प्लगइन

टहनी एक उत्कृष्ट टेम्पलेट इंजन है और, दूसरों के विपरीत जो मैंने सामना किया है, मुझे समय के साथ यह अधिक से अधिक पसंद है। टहनी के कई फायदे हैं, और उनमें से एक विस्तार है।

कुछ समय के लिए, एक छोटी सी समस्या ने चुपचाप मेरा जीवन खराब कर दिया, जिसके लिए आलस्य समय बर्बाद कर रहा था। हाल ही में, मैंने अभी भी खुद को मजबूर किया है और मुझे लगता है कि इसका एक समाधान ट्विग में प्लगइन्स के बारे में एक छोटे से लेख के लिए अच्छी तरह से अनुकूल होगा।

यह समस्या स्वयं टेम्प्लेट के अंदर स्थिरांक में है। ऐसे कार्य हैं जब टेम्पलेट में कुछ पहचानकर्ताओं पर सिलाई करना आवश्यक होता है। उन्हें संख्याओं में रखना बहुत अच्छा नहीं है, लेकिन अगर उनके लिए स्थिरांक हैं, तो यह एक पाप है कि constant फ़ंक्शन का उपयोग न करें। लेकिन तथ्य यह है कि टेम्पलेट से संकलन के बाद, यह अभी भी रनटाइम में गणना की जाती है।

और हम क्या कर सकते हैं? रिफैक्टरिंग के मद्देनजर, हम एक स्थिरांक को मार देते हैं या उसका नाम बदल देते हैं, और टेम्पलेट के बारे में भूल जाते हैं। और IDE भूल जाते हैं, यहां तक ​​कि vaunted PHPStorm। हम टेम्प्लेट के हमारे पूरे पहाड़ को तैनात करने से पहले सफलतापूर्वक संकलित करते हैं, इसे सर्वर पर बिखेरते हैं। कुछ भी नहीं गिरा, सब कुछ बस बहुत अच्छी तरह से काम नहीं करता है, और समान Vorings की एक बड़ी शीट हमारे सिर पर आती है। बुरा? घृणित!

समाधान? टेम्पलेट संकलन की प्रक्रिया में स्थिरांक को हल करें, अनुपस्थित व्यक्ति - शपथ।

उन लोगों के लिए जो टहनी से परिचित नहीं हैं या बहुत परिचित नहीं हैं, हम बताएंगे (बहुत संक्षेप में) कि प्रत्येक टेम्पलेट को प्लगइन्स द्वारा पार्स किया गया है (यहां तक ​​कि प्लगइन्स का उपयोग करके टेम्पलेट इंजन में बुनियादी सुविधाओं को लागू किया जाता है), इसे संसाधित किया जाता है और इसे एक फास्फेट क्लास में संकलित किया जाता है, जो तब display विधि display करता है। उदाहरण के लिए, इस टेम्पलेट कोड को लें, बस हमारे स्थिरांक के साथ:

 {% if usertype == constant('Users::TYPE_TROLL') %} ,  ! {% else %} ! {% endif %} 

पैटर्न को वस्तुओं के अपेक्षाकृत बड़े पेड़ में क्रमबद्ध किया जाएगा।

यहाँ हमारे टेम्पलेट के प्रतिनिधित्व का एक छोटा, लेकिन अभी भी बढ़िया प्रिंट_आर आउटपुट है
 [body] => Twig_Node_Body Object ( [nodes:protected] => Array ( [0] => Twig_Node_If Object ( [nodes:protected] => Array ( [tests] => Twig_Node Object ( [nodes:protected] => Array ( [0] => Twig_Node_Expression_Binary_Equal Object ( [nodes:protected] => Array ( [left] => Twig_Node_Expression_Name Object ( [attributes:protected] => Array ( [name] => usertype ) ) [right] => Twig_Node_Expression_Function Object ( [nodes:protected] => Array ( [arguments] => Twig_Node Object ( [nodes:protected] => Array ( [0] => Twig_Node_Expression_Constant Object ( [attributes:protected] => Array ( [value] => Users::TYPE_TROLL ) ) ) ) ) [attributes:protected] => Array ( [name] => constant ) ) ) ) [1] => Twig_Node_Text Object ( [attributes:protected] => Array ( [data] => ,  ! ) ) ) ) [else] => Twig_Node_Text Object ( [attributes:protected] => Array ( [data] => ! ) ) ) ) ) ) 

इसे अतिरिक्त रूप से संसाधित किया जाता है [हमें यहां पच्चीकारी करने की आवश्यकता है] और परिणामस्वरूप इसे ऐसी फ़ाइल (थोड़ा छोटा संस्करण) में संकलित किया जाता है:

 class __TwigTemplate_long_long_hash extends Twig_Template { protected function doDisplay(array $context, array $blocks = array()) { if (((isset($context["usertype"]) ? $context["usertype"] : null) == twig_constant("Users::TYPE_TROLL"))) { echo ",  !"; } else { echo "!"; } } } 

यहाँ $context इस टेम्पलेट के इनपुट के लिए चर का एक गुच्छा में मिला है। मुझे उम्मीद है कि सब कुछ स्पष्ट है और कुछ भी स्पष्ट करने की आवश्यकता नहीं है। twig_constant फ़ंक्शन व्यावहारिक रूप से मानक constant से भिन्न नहीं होता है और रनटाइम में हल होता है।

अपनी आँखों से समस्या को देखने के लिए, हम कोड से स्थिरांक को हटाते हैं और रेंडर पर पकड़ते हैं:
PHP Warning: constant(): Couldn't find constant Users::TYPE_TROLL in vendor/twig/twig/lib/Twig/Extension/Core.php on line 1387

यह संकलित संस्करण में twig_constant कॉल है जिसे हमें निरंतर मूल्य के साथ बदलने की आवश्यकता है।

एक्सटेंशन के लिए, टेम्पलेट इंजन Twig_Extension वर्ग प्रदान करता है, जिससे हम अपने एक्सटेंशन को प्राप्त करते हैं। विस्तार टेम्पलेट इंजन को फ़ंक्शंस, फ़िल्टर, और अन्य बकवास के सेट के साथ प्रदान कर सकता है जिसे आप विशेष विधियों के माध्यम से सोच सकते हैं जो आप स्वयं Twig_ExtensionInterface इंटरफ़ेस में पा सकते हैं। हम getNodeVisitors विधि में रुचि रखते हैं, जो वस्तुओं के एक सरणी को लौटाता है जिसके माध्यम से संकलित टेम्पलेट ट्री के सभी तत्वों को संकलित करने से पहले पारित किया जाएगा।

 class Template_Extensions_ConstEvaluator extends Twig_Extension { public function getNodeVisitors() { return [ new Template_Extensions_NodeVisitor_ConstEvaluator() ]; } public function getName() { return 'const_evaluator'; } } 

संकलन करने से पहले, हमें केवल सभी नोड्स के माध्यम से जाने की जरूरत है, उनके बीच सामान्य पाठ तर्क के साथ निरंतर फ़ंक्शन ढूंढें और इसे इसके मूल्य में बदल दें, या कसम खाएं कि ऐसा कोई निरंतर नहीं है।

यह हमारा नोड विज़िटर बताता है:

 class Template_Extensions_NodeVisitor_ConstEvaluator implements Twig_NodeVisitorInterface { public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) { //  -   constant  1  if ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name') && 1 === $node->count() ) { //    $args = $node->getNode('arguments'); if ($args instanceof Twig_Node && 1 === $args->count() ) { $constNode = $args->getNode(0); // 1   if ($constNode instanceof Twig_Node_Expression_Constant && null !== $value = $constNode->getAttribute('value') ) { if (null === $constantEvaluated = constant($value)) { //     -  throw new Twig_Error( sprintf( "Can't evaluate constant('%s')", $value ) ); } //  ,        //       :] return new Twig_Node_Expression_Constant($constantEvaluated, $node->getLine()); } } } //  ,  ,  ,     return $node; } public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { return $node; } } 

इसी तरह हमने अपने टेम्पलेट ट्री का लगभग एक तिहाई हिस्सा सामान्य मूल्य के साथ बदल दिया।

बस मामले में, मैं आपको दिखाता हूँ कि संकलित संस्करण में क्या हुआ
 class __TwigTemplate_long_long_hash extends Twig_Template { protected function doDisplay(array $context, array $blocks = array()) { if (((isset($context["usertype"]) ? $context["usertype"] : null) == 2)) { echo ",  !"; } else { echo "!"; } } } 

सरल, रोचक, उपयोगी।

उम्मीद है कि यह किसी को टहनी में खोदने के लिए प्रेरित करेगा और इसे कार्यों और फिल्टर के अलावा किसी अन्य चीज़ के साथ विस्तारित करने की कोशिश करेगा। किसी भी आलोचना को सुनने के लिए तैयार हैं, और यहां तक ​​कि सुबह सवालों के जवाब भी। Diskas!

Source: https://habr.com/ru/post/In200614/


All Articles