मैं Happstack, चोरी, और वेब मार्गों, का उपयोग करते हुए एक आवेदन सर्वर लिखने की कोशिश कर रहा हूँ, लेकिन पता लगाना splices पहुँच मानों से ही शुरू नहीं है यह बताने के लिए कि कैसे परेशानी हो रही हूँ मेरे आवेदन के मोनैड ढेर।का उपयोग करते हुए मान नहीं टेम्पलेट्स
- पैरामीटर वेब मार्गों के माध्यम से URL पथ से निकाला:
दो स्थितियों में, जहां इस आता हैं। उचित हैंडलर को अनुरोध करते समय ये एक प्रकार-सुरक्षित यूआरएल पर पैटर्न-मिलान से आते हैं।
- सत्र जानकारी। यदि अनुरोध एक नए सत्र के लिए है, तो मैं अनुरोध में कुकी से सत्र पहचानकर्ता नहीं पढ़ सकता (क्योंकि ऐसी कोई कुकी अभी तक मौजूद नहीं है), और यदि आवश्यक हो तो मैं एक नया सत्र बनाने के लिए स्प्लिसेस का उपयोग नहीं कर सकता, तब से यदि एक से अधिक स्प्लिस इसे करने की कोशिश करता है, तो मैं एक ही अनुरोध के लिए कई नए सत्र तैयार करता हूं। लेकिन अगर मैं वेब-रूट सामग्री दर्ज करने से पहले सत्र बनाता हूं, तो सत्र मोनैड के बाहर सत्र मौजूद है।/
- /भाज्य/nn
- के भाज्य आउटपुट/str आउटपुट रिवर्स str:
निम्न नमूना कार्यक्रम निम्न URL की सेवा करने की कोशिश करता है पर विचार करें पीछे की ओर
चूंकि क्वेरी स्ट्रिंग के बजाय यूआरएल पथ में पैरामीटर दिखाई देता है, इसलिए यह सर्वरपार्टट मोनैड से आने के बजाय वेब-रूट्स के माध्यम से निकाला जाता है। वहां से, पैरामीटर को कहीं भी रखने का कोई स्पष्ट तरीका नहीं है जहां स्प्लिस इसे देख सकते हैं, क्योंकि उनके पास केवल एप्लिकेशन मोनैड तक पहुंच है।
इकाई ढेर पर कहीं एक ReaderT चिपके की स्पष्ट समाधान दो समस्याएं हैं:
- एक ReaderT होने ऊपर ServerPartT इकाई ढेर के Happstack भागों छुपाता है, के बाद से ReaderT ServerMonad, FilterMonad को लागू नहीं करता है, इत्यादि
- यह मानता है कि मैं जिन सभी पृष्ठों की सेवा कर रहा हूं, वे एक ही प्रकार के पैरामीटर लेते हैं, लेकिन इस उदाहरण में, फैक्टोरियल एक इंट चाहता है लेकिन रिवर्स स्ट्रिंग चाहता है। लेकिन दोनों पेज हैंडलरों के लिए एक ही टेम्पलेट डायरेक्टरी का उपयोग करने के लिए, रीडर को उसी प्रकार के मूल्य को ले जाने की आवश्यकता होगी।
स्नैप दस्तावेज़ों पर ध्यान देने से, ऐसा लगता है कि स्नैप हैंडल पैरामीटर को प्रभावी ढंग से क्वेरी स्ट्रिंग में कॉपी करके यूआरएल पथ में पैरामीटर हैंडल करता है, जो समस्या को दूर करता है। लेकिन यह हैप्स्टैक और वेब-रूट्स के साथ एक विकल्प नहीं है, और इसके अलावा, एक ही मान निर्दिष्ट करने के लिए यूआरएल के दो अलग-अलग तरीकों से मुझे सुरक्षा के अनुसार एक बुरा विचार माना जाता है।
तो, क्या गैर-अनुप्रयोग-मोनैड अनुरोध डेटा को विभाजित करने के लिए एक "उचित" तरीका है, या क्या मुझे हेस्ट को त्यागने और ब्लेज़-एचटीएमएल जैसे कुछ उपयोग करने की आवश्यकता है, जहां यह कोई मुद्दा नहीं है? मुझे लगता है कि मुझे कुछ स्पष्ट याद आ रहा है, लेकिन यह पता नहीं लगा सकता कि यह क्या हो सकता है।
उदाहरण कोड:
{-# LANGUAGE TemplateHaskell #-}
import Prelude hiding ((.))
import Control.Category ((.))
import Happstack.Server (Response, ServerPartT, nullConf, ok, simpleHTTP)
import Happstack.Server.Heist (render)
import Text.Boomerang.TH (derivePrinterParsers)
import Text.Templating.Heist (Splice, bindSplices, emptyTemplateState, getParamNode)
import Text.Templating.Heist.TemplateDirectory (TemplateDirectory, newTemplateDirectory')
import Web.Routes (RouteT, Site, runRouteT)
import Web.Routes.Boomerang (Router, anyString, boomerangSite, int, lit, (<>), (</>))
import Web.Routes.Happstack (implSite)
import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T
import qualified Text.XmlHtml as X
data Sitemap = Factorial Int
| Reverse String
$(derivePrinterParsers ''Sitemap)
-- Conversion between type-safe URLs and URL strings.
sitemap :: Router Sitemap
sitemap = rFactorial . (lit "factorial" </> int)
<> rReverse . (lit "reverse" </> anyString)
-- Serve a page for each type-safe URL.
route :: TemplateDirectory (RouteT Sitemap (ServerPartT IO)) -> Sitemap -> RouteT Sitemap (ServerPartT IO) Response
route templates url = case url of
Factorial _num -> render templates (C.pack "factorial") >>= ok
Reverse _str -> render templates (C.pack "reverse") >>= ok
site :: TemplateDirectory (RouteT Sitemap (ServerPartT IO)) -> Site Sitemap (ServerPartT IO Response)
site templates = boomerangSite (runRouteT $ route templates) sitemap
-- <factorial>n</factorial> --> n!
factorialSplice :: (Monad m) => Splice m
factorialSplice = do input <- getParamNode
let n = read . T.unpack $ X.nodeText input :: Int
return [X.TextNode . T.pack . show $ product [1 .. n]]
-- <reverse>text</reverse> --> reversed text
reverseSplice :: (Monad m) => Splice m
reverseSplice = do input <- getParamNode
return [X.TextNode . T.reverse $ X.nodeText input]
main :: IO()
main = do templates <- newTemplateDirectory' path . bindSplices splices $ emptyTemplateState path
simpleHTTP nullConf $ implSite "http://localhost:8000" "" $ site templates
where splices = [(T.pack "factorial", factorialSplice), (T.pack "reverse", reverseSplice)]
path = "."
भाज्य।TPL:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Factorial</title>
</head>
<body>
<p>The factorial of 6 is <factorial>6</factorial>.</p>
<p>The factorial of ??? is ???.</p>
</body>
</html>
reverse.tpl:
func :: a -> m b
क्योंकि हास्केल शुद्ध है और एक मजबूत स्थिर प्रकार प्रणाली है, डेटा में इस्तेमाल किया:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Reverse</title>
</head>
<body>
<p>The reverse of "<tt>hello world</tt>" is "<tt><reverse>hello world</reverse></tt>".</p>
<p>The reverse of "<tt>???</tt>" is "<tt>???</tt>".</p>
</body>
</html>
मैं यहाँ पर स्नैप' rendWithSplices 'पर कस्टम happstack रूपों का उपयोग किया है 'ऐप टेम्पलेटस्टेट' टाइप करने के लिए 'फ़ंक्शन'। –