मैं काफी समय से PHP का विकास कर रहा था, और इस दौरान मैंने सीखा कि इस भाषा का लाभ कैसे उठाया जाए और जब भी संभव हो, इसकी कमियों से बचें। लेकिन जो मुझे PHP के बारे में कभी पसंद नहीं आया, वह है इसका बिल्ट-इन टेम्पलेट इंजन। "<? Php ...?>" वर्ण और क्रिया भाषा निर्माण की प्रचुरता हड़ताली है, टेम्पलेट में मनमाने ढंग से PHP कोड का उपयोग करने की क्षमता तर्क और प्रस्तुति के पृथक्करण के सिद्धांत में योगदान नहीं करती है।
इसलिए, मैं वैकल्पिक टेम्पलेट इंजन के अस्तित्व के लिए भाग्य (और विकास समुदाय, निश्चित रूप से) के लिए आभारी हूं, एक ही कार्यक्षमता के साथ बहुत अधिक सुखद सिंटैक्स। खैर, और चूंकि हमारे उच्च प्रौद्योगिकी केंद्र में PHP प्रोजेक्ट्स के अधिकांश सिम्फनी 2 फ्रेमवर्क पर विकसित किए जा रहे हैं, ट्विग हमारा पसंदीदा टेम्पलेट इंजन बन गया है। उपरोक्त फायदे के अलावा, यह असीमित रूप से विस्तार योग्य भी है, जो अक्सर काम में मदद करता है।
लेकिन जीवन में अक्सर आश्चर्य होता है। तो हाल ही में एक छोटी लेकिन बल्कि दिलचस्प परियोजना मुझ पर गिर गई, जिस पर काम करना था ... बिट्रिक्स! सौभाग्य से, मुझे पहले से ही बिट्रिक्स के साथ काम करना था, लेकिन यह बहुत समय पहले
(और सच नहीं था) , इसलिए मैंने अपने नए अनुभव से अपने पिछले अनुभव को देखने के अवसर के रूप में प्रोजेक्ट लिया, संचित ज्ञान और कौशल को थोड़ा अलग संदर्भ में लागू किया।
और पहली चीज जो मैं करना चाहता था, वह थी "ट्विगी" ताकि देशी टेंपलेटिंग के साथ पीड़ा न हो।
यहाँ क्या यह आया है।
सौभाग्य से, Bitrix आपको किसी भी टेम्पलेट आउटपुट का उपयोग करने की अनुमति देता है। हालाँकि, केवल घटक टेम्पलेट्स के लिए, साइट टेम्पलेट अभी भी PHP में बनाए जाते हैं। टेम्पलेट इंजन कनेक्ट करने के लिए, आपको एक वैश्विक फ़ंक्शन (हां, यह बिट्रिक्स, बेबी) घोषित करने की आवश्यकता है, जो टेम्पलेट को प्रस्तुत करेगा। एक समारोह इस तरह लग सकता है:
function renderTwigTemplate($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { echo TwigTemplateEngine::renderTemplate($templateFile, array( 'params' => $arParams, 'result' => $arResult, 'langMessages' => $arLangMessages, 'template' => $template, 'templateFolder' => $templateFolder, 'parentTemplateFolder' => $parentTemplateFolder, )); }
इसके अलावा, फ़ंक्शन को टेम्पलेट फ़ाइल के विस्तार के साथ
$arCustomTemplateEngines
वैश्विक सरणी में पंजीकृत होना चाहिए:
global $arCustomTemplateEngines; $arCustomTemplateEngines["twig"] = array( "templateExt" => array("twig"), "function" => "renderTwigTemplate" );
नतीजतन, अगर
टेम्पलेट नाम की एक फ़ाइल। घटक के टेम्पलेट निर्देशिका में स्थित है, तो
renderTwigTemplate()
रेंडरिंग फ़ंक्शन को कॉल किया जाएगा, जिसके इनपुट पर सभी आवश्यक डेटा स्थानांतरित किए जाएंगे: टेम्पलेट फ़ाइल का नाम और पथ, घटक को कॉल करने के लिए पैरामीटर, घटक के निष्पादन का परिणाम, और। इस टेम्पलेट के लिए भाषा स्थिरांक।
जैसा कि यह निकला, एक अप्रिय विशेषता है: यदि
टेम्पलेट टेम्पलेट में डाइरेक्टरी
.wig और
template.php फाइलें एक साथ हैं, तो PHP टेम्प्लेट का उपयोग किया जाएगा। इसलिए, यह एक या दूसरे टेम्पलेट इंजन को कनेक्ट / डिस्कनेक्ट करते समय टेम्प्लेट के प्रकार के एक सुंदर निहित प्रतिस्थापन का एहसास करने के लिए काम नहीं करेगा।
रेंडरिंग फ़ंक्शन पंजीकृत होने के बाद, यह इंजन को खुद को इनिशियलाइज़ और कॉन्फ़िगर करने के लिए रहता है। ट्विग के मामले में, आपको इसके ऑटोलैडर को प्रोजेक्ट से कनेक्ट करने की आवश्यकता है, टेम्प्लेट निर्देशिका को पथ निर्दिष्ट करें और कॉन्फ़िगरेशन पैरामीटर सेट करें (उनमें से सबसे महत्वपूर्ण डीबग मोड और टेम्पलेट कैश को स्टोर करने के तरीके का उपयोग कर रहे हैं)। इसके अलावा, यदि आवश्यक हो, तो आप आवश्यक एक्सटेंशन जोड़ सकते हैं। यह सब इस तरह लग सकता है:
class TwigTemplateEngine { private static $twigEnvironment; public static function initialize($templateRootPath, $cacheStoragePath) { Twig_Autoloader::register(); $debugModeOptionValue = COption::GetOptionString("htc.twigintegrationmodule", "debug_mode"); $debugMode = ($debugModeOptionValue == "Y") ? true : false; $loader = new Twig_Loader_Filesystem($templateRootPath); self::$twigEnvironment = new Twig_Environment($loader, array( 'autoescape' => false, 'cache' => $cacheStoragePath, 'debug' => $debugMode )); self::addExtensions(); global $arCustomTemplateEngines; $arCustomTemplateEngines["twig"] = array( "templateExt" => array("twig"), "function" => "renderTwigTemplate" ); } private static function addExtensions() { self::$twigEnvironment->addExtension(new Twig_Extension_Debug()); self::$twigEnvironment->addExtension(new BitrixTwigExtension()); } public static function renderTemplate($templateFile, array $context) { return self::$twigEnvironment->render($templateFile, $context); } public static function clearCacheFiles() { self::$twigEnvironment->clearCacheFiles(); } }
इस मामले में स्थिर तरीकों और वर्ग गुणों का उपयोग बिट्रिक्स की वास्तुकला के कारण होता है: इसमें सेवा वस्तुओं को रखने के लिए एक तंत्र नहीं है, इसी तरह, उदाहरण के लिए, Symfony2 से सेवा कंटेनर में।
टेम्पलेट इंजन का
इनिशियलाइज़ेशन इनिशियलाइज़ () विधि में किया जाता है। मैं ध्यान देता हूं कि हमारे मामले में, Twig कनेक्शन एक अलग Bitrix मॉड्यूल में समझाया गया है। यह, सबसे पहले, हमें विभिन्न परियोजनाओं पर कार्यक्षमता का आसानी से उपयोग करने का अवसर दिया, और दूसरी बात, इसने हमें सीएमएस प्रशासनिक इंटरफ़ेस के माध्यम से कुछ कॉन्फ़िगरेशन पैरामीटर सेट करने की अनुमति दी। विशेष रूप से, डीबगिंग मोड को
डीबग_मोड विकल्प के मूल्य के आधार पर सक्षम किया
जाता है, जिसका नियंत्रण
बिट्रिक्स व्यवस्थापक पैनल में मॉड्यूल सेटिंग पृष्ठ पर रखा गया है।
चूंकि हम कॉन्फ़िगरेशन मापदंडों के बारे में बात कर रहे हैं, इसलिए मैं अपने आप को एक छोटे गीतात्मक विषयांतर की अनुमति दूंगा ट्विग का सिद्धांत इस प्रकार है: जब आप पहली बार टेम्पलेट का उपयोग करते हैं, तो यह PHP कोड में संकलित होता है, जिसे बाद में सभी कॉल पर निष्पादित किया जाता है। उत्पन्न कोड वाली फ़ाइलों को टेम्पलेट कैश कहा जाता है और
कैश विकल्प में निर्दिष्ट निर्देशिका में रखा जाता है। टेम्पलेट के स्रोत कोड को बदलते समय, स्वाभाविक रूप से, कैश को अमान्य करने की आवश्यकता होती है। नई कार्यक्षमता जारी करते समय आमतौर पर उपयोग किया जाने वाला सबसे आसान तरीका कैश डायरेक्टरी को पूरी तरह से साफ़ करना है, जिसे
Twig_Environment::clearCacheFiles()
पद्धति से लागू किया जाता है (हमारा मॉड्यूल इस विधि के लिए एक आवरण लागू करता है जो आपको प्रशासनिक इंटरफ़ेस में एक बटन क्लिक करके कैश साफ़ करने की अनुमति देता है)। इसके अलावा, अपने स्रोत कोड को बदलते समय
ट्विग स्वचालित रूप से एक विशिष्ट टेम्पलेट के कैश को फिर से बना सकता है: ऐसा करने के लिए,
auto_reload विकल्प को सही पर सेट करें। लेकिन आमतौर पर यह दृष्टिकोण केवल विकास मोड में आवश्यक होता है, इसलिए
ऑटो_रलोड के बजाय आप
डिबग विकल्प सेट कर सकते हैं, जो कैश के साथ काम करते समय एक ही प्रभाव होगा, और आपको ट्विग डीबगिंग सुविधाओं का उपयोग करने की अनुमति भी देगा।
वैसे, Twig टेम्पलेट कैश किसी भी तरह से जुड़ा नहीं है और बिट्रिक्स टेम्पलेट कैश के साथ संघर्ष नहीं करता है, क्योंकि पहले मामले में PHP कोड कैश किया जाता है, और दूसरे मामले में घटक के काम और एचटीएमएल अप के परिणामस्वरूप प्राप्त डेटा।
बिट्रिक्स के संदर्भ में,
ऑटोस्कोप विकल्प को झूठा सेट करना महत्वपूर्ण था, क्योंकि पहले से ही परिरक्षित डेटा को रेंडरिंग फ़ंक्शन में स्थानांतरित किया जाता है।
आरंभिक विधि को मॉड्यूल कनेक्शन फ़ाइल में कहा जाता है:
CModule::AddAutoloadClasses( 'htc.twigintegrationmodule', array( 'TwigTemplateEngine' => 'classes/general/templating/TwigTemplateEngine.php', 'BitrixTwigExtension' => 'classes/general/templating/BitrixTwigExtension.php', 'Twig_Autoloader' => 'vendor/Twig/Autoloader.php', ) );
जैसा कि आप इस कोड से देख सकते हैं, कैश निर्देशिका में पथ को मॉड्यूल सेटिंग पेज पर भी कॉन्फ़िगर किया जा सकता है।
तो, टेम्पलेट इंजन पंजीकृत और कॉन्फ़िगर किया गया है, इसका उपयोग शुरू करने का समय है। और यहाँ, हमेशा की तरह, बिना नुकसान के।
सबसे पहले, अक्सर बिट्रिक्स घटकों के टेम्पलेट्स में कुछ बिट्रिक्स कार्यों, साथ ही वैश्विक वस्तुओं (क्या करना है, सीएमएस वास्तुकला की लागत) का उपयोग करना आवश्यक है। सौभाग्य से, ट्विग, जैसा कि मैंने पहले ही नोट किया है, आपको अपने स्वयं के एक्सटेंशन बनाने की अनुमति देता है जिसमें आप अतिरिक्त टैग, फ़िल्टर, फ़ंक्शन आदि का वर्णन कर सकते हैं। इसलिए,
BitrixTwigExtension
को
टेम्प्लेट में बिट्रिक्स एपीआई तक पहुंच प्रदान करने के लिए विकसित किया गया था। उसी समय, हमने डेवलपर्स में टेम्पलेट्स में व्यावसायिक तर्क को लागू करने की इच्छा से बचाने के लिए उपलब्ध एपीआई का एक न्यूनतम सेट छोड़ने की कोशिश की।
फिर, यह समझने के लंबे प्रयासों के बाद कि भाषा कांस्टेंट टेम्पलेट में क्यों नहीं पास किए गए हैं, और फिर सीएमएस कर्नेल कोड का अध्ययन कर रहे हैं, यह स्पष्ट हो गया कि भाषा टेम्पलेट फ़ाइल का विस्तार सहित टेम्पलेट के समान ही नाम होना चाहिए। इसका मतलब है कि PHP फ़ाइल शेष रहने के दौरान
टेम्पलेट .wig
टेम्पलेट भाषा फ़ाइल को भी
टेम्पलेट का नाम दिया जाना चाहिए। खैर, अजीब व्यवहार, लेकिन, जैसा कि यह निकला, आप बिट्रिक्स के डेवलपर्स से यह उम्मीद नहीं कर सकते।
सबसे अप्रिय बात यह थी कि ट्विग टेम्प्लेट का उपयोग करते समय,
कंपोनेंट_पिलॉग ने काम नहीं किया था (बिट्रिक्स में टेम्पलेट रेंडर करने का अंतिम चरण, जो आपको किसी भी क्रिया को करने की अनुमति देता है कि क्या टेम्प्लेट कैश किया गया है या नहीं)। फिर से, कर्नेल कोड का अध्ययन - और एक और आश्चर्य:
Components_epilog केवल देशी टेम्पलेट्स से जोड़ता है! शायद, मुझे अभी तक बिट्रिक्स में अधिक विवादास्पद निर्णय नहीं मिला है। इस स्थिति को ठीक करने का एकमात्र तरीका टेम्पलेट को रेंडर करने के बाद मैन्युअल रूप से घटक_पिलॉग को कॉल करना है:
function renderTwigTemplate($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { echo TwigTemplateEngine::renderTemplate($templateFile, array( 'params' => $arParams, 'result' => $arResult, 'langMessages' => $arLangMessages, 'template' => $template, 'templateFolder' => $templateFolder, 'parentTemplateFolder' => $parentTemplateFolder, )); $component_epilog = $templateFolder . "/component_epilog.php"; if(file_exists($_SERVER["DOCUMENT_ROOT"].$component_epilog)) { $component = $template->__component; $component->SetTemplateEpilog(array( "epilogFile" => $component_epilog, "templateName" => $template->__name, "templateFile" => $template->__file, "templateFolder" => $template->__folder, "templateData" => false, )); } }
सुधारों के बाद, हमें आखिरकार एक बहुत ही उपयोगी समाधान मिल गया, जिसने मेरे जीवन को सरल बना दिया (परियोजना जिसने इसे शुरू किया था, उसे सफलतापूर्वक लागू किया गया) और मेरे सहयोगियों को भी ट्विग की सादगी और संक्षिप्तता पसंद थी।
और, बेशक, हम मदद नहीं कर सकते थे लेकिन हमारे मजदूरों के परिणाम को साझा करते थे। मॉड्यूल अजीब नाम
Twigrix के तहत
बिट्रिक्स मार्केटप्लेस में स्थित है, यह बिल्कुल मुफ्त है और सभी रुचि के लिए डाउनलोड के लिए उपलब्ध है। और सोर्स कोड को
जीथब पर देखा जा सकता है। हमें पूरी उम्मीद है कि Twigrix कठोर Bitrix डेवलपर्स के कठोर रोजमर्रा के जीवन को थोड़ा सा शोभा देगा।