प्रविष्टि
इतना समय पहले नहीं, मुझे ई-मेल द्वारा आगे भेजने के लिए पॉवरशेल स्क्रिप्ट से विभिन्न HTML रिपोर्टों को प्रस्तुत करने का काम मिला था। तैयार समाधानों की खोज ने बहुत कुछ नहीं दिया। कोई रेजर को जोड़ता है, कोई अपने स्वयं के मालिकाना जटिल
बाइक इंजन को।
आवश्यकताओं की एक मामूली सूची इस प्रकार थी:
- कोड अलग-अलग फ़ाइलों में होना चाहिए।
- दृश्य के अंदर, PowerShell में नेस्टिंग और कोड सम्मिलन के लिए समर्थन होना चाहिए।
- यह अतिरिक्त सेटिंग्स के बिना PowerShell 2.0 के साथ किसी भी होस्ट पर काम करना चाहिए।
चूंकि कुछ भी नहीं पाया जा सकता था, एक साधारण (और एक ही समय में शक्तिशाली) रेंडरिंग इंजन क्लासिक एस्प की शैली में लागू किया गया था।

कार्यान्वयन का विवरण
समस्या का अध्ययन (जैसे PowerShell स्वयं), मैंने स्ट्रिंग्स के अंदर PowerShell अभिव्यक्तियों की गणना के लिए वाक्यविन्यास को देखा। उदाहरण के लिए, अभिव्यक्ति
" $($env:COMPUTERNAME)"
रनटाइम पर व्याख्या की जाएगी और आउटपुट में हमें
MYCOMPUTER
जैसा कुछ
MYCOMPUTER
।
यह, वास्तव में, अपने सरलतम रूप में अस्थायी है। यह आपको काफी जटिल विचार प्रस्तुत करने की अनुमति देता है:
$Model = @{} $Model.Title = 'Hello, this is a test' $Model.Clients = @('Ivan', 'Sergiy', 'John') $html = "<h1> $($Model.Title) </h1> <div class=""test""> <ul> $( foreach($client in $Model.Clients) {" <li> $( $client ) </li> "}) </ul> </div>" $html
जैसा कि आप देख सकते हैं, पॉवरशेल पार्सर आपको स्ट्रिंग्स में $ () में संलग्न कोड के नेस्टेड आवेषण का उपयोग करने की अनुमति देता है, जो शाखाओं और छोरों को लागू करने के लिए बहुत सुविधाजनक है।
इस विधि का उपयोग पहले से ही छोटे कार्यों के लिए किया जा सकता है, हालांकि इसके नुकसान भी हैं:
- स्क्रिप्ट कोड में दृश्य कोड निहित होता है, न कि एक अलग फ़ाइल में।
- नेस्टेड विचारों का उपयोग करने का कोई तरीका नहीं है।
- वाक्यविन्यास थोड़ा अस्पष्ट है, और अक्सर एक लापता ब्रैकेट या उद्धरण चिह्न के कारण, आपको सब कुछ कठिन जांचना होगा।
- पाठ आवेषण में
"
रूप में ""
दोहरे उद्धरण चिह्न को एनकोड करना आवश्यक है।
पहले दो कमियां काफी सरलता से हल हो गई हैं - टेम्पलेट को सबफ़ोल्डर में एक अलग फ़ाइल में स्थानांतरित किया गया है, और मॉडल को रेंडर करने के लिए एक फ़ंक्शन लिखा गया है:
function RenderViewNativePowerShell( [Parameter(Mandatory=$true)][string] $viewName, [Parameter(Mandatory=$true)][Object] $model ) { $viewFileName = Resolve-Path ('Views\' + $viewName) $templateContent = Get-Content $viewFileName | Out-String return $ExecutionContext.InvokeCommand.ExpandString('"' + $templateContent + '"') }
तब इसे इस तरह कहा जा सकता है:
RenderViewNativePowerShell 'Test_ps.html' $Model
नेस्टेड विचारों का समर्थन कर रहे हैं। यह वही है जो test_ps.html जैसा दिखता है:
$( RenderViewNativePowerShell 'header_ps.html' $Model ) <div class=""test""> <ul> $( foreach($client in $Model.Clients) {" <li> $( $client ) </li> "}) </ul> </div>
यह कुछ के लिए पर्याप्त लग सकता है, लेकिन मैंने शेष कमियों को दूर करने का फैसला किया - एएसपी कोष्ठक का उपयोग करने के लिए स्विच करें <% ...%>, क्योंकि इस वाक्यविन्यास का समर्थन कई पाठ संपादकों में किया जाता है, और पृष्ठ लेआउट बहुत अधिक पठनीय लगता है।
इसलिए, कार्यान्वयन का मुख्य विचार काफी सरल है: सभी ब्रैकेट को अपने पावरशेल समकक्ष $ (...) के साथ सभी ब्रैकेट <% ...%> ले और बदलें। कुछ कठिनाई यह थी कि प्रतिस्थापन नेस्टेड विचारों को ध्यान में रखने के लिए अस्पष्ट होना चाहिए, क्योंकि उन्हें "..." ब्लॉक में होना चाहिए।
कुछ पीड़ा के बाद, ऐसा कार्य हुआ:
function RenderView( [Parameter(Mandatory=$true)][string] $viewName, [Parameter(Mandatory=$true)][Object] $model ) { $viewFileName = Resolve-Path ("Views\" + $viewName) $templateContent = Get-Content $viewFileName | Out-String $rx = New-Object System.Text.RegularExpressions.Regex('(<%.*?%>)', [System.Text.RegularExpressions.RegexOptions]::Singleline) $res = @() $splitted = $rx.split($templateContent); foreach($part in $splitted) { if ($part.StartsWith('<%') -and $part.EndsWith('%>')) #transform <%...%> blocks { $expr = $part.Substring(2, $part.Length-4) #remove <%%> quotes $normExpr = $expr.Replace('`n','').Replace('`r','').Trim(); $startClosure = '$(' $endClosure = ')' if ($normExpr.endswith('{')) { $endClosure = '"' } if ($normExpr.startsWith('}')) { $startClosure = '"' } $res += @($startClosure + $expr + $endClosure) } else #encode text blocks { $expr = $part.Replace('"', '""'); $res += @($expr) } } $viewExpr = $res -join '' return $ExecutionContext.InvokeCommand.ExpandString('"' + $viewExpr + '"') }
अपने PowerShell समकक्षों के साथ <%%> के आवश्यक प्रतिस्थापन के अलावा, पाठ ब्लॉकों में "द्वारा" का प्रतिस्थापन भी किया जाता है।
परिणामस्वरूप, विजुअल स्टूडियो में हमारा विचार बहुत अच्छा लगता है:

निष्कर्ष में, यह ध्यान रखना है कि कुछ परीक्षणों और उदाहरणों के साथ स्रोत कोड
GitHub पर उपलब्ध
है ।