úÎ&Ã%Ä     <Chooses a template from an STGroup, or errors if not found. "Render that template using attrs. If a template k/Jv pair is repeated, it appears twice. (Perhaps a clue to buggy behavior?) 4Repeated keys could be eliminated by running clean: ] clean = nubBy (\(a1,b1) (a2,b2) -> a1 == a2) . sortBy (\(a1,b1) (a2,b2) -> a1 `compare` a2) 5The ToSElem type is probably either String or [String] RHelper function to calculate a map of directory groups from a top-level directory -Each directory gives rise to its own groups. jGroups are independent; groups from higher in the directory structure do not have access to groups lower. The top group has key "."l (mnemonic, current directory), other groups have key names of subdirectories, including the starting ., eg "./ templates/path/to/subdir"  Non-strict. I'bm pretty sure this is wrong. Based on default directoryGroup function in HStringTemplate package 2Strict directoryGroups, which is the right thing. I'Gm this does the same thing as directoryGroup (modulo IO strictness), ; which uses an applicative idiom that melts my brain. % Not a direct translation, but it'+s easier for me to understand when written j Important change: readFile is strict. If it is left lazy, appkiller.sh causes happstutorial to crash B when in dynamicTemplateReload mode. (See HAppS GoogleGroup.) M I think this needs to be fixed in HStringTemplate distribution as well. > This should be fixed in HSTringTemplate package as well. JdirectoryGroup helper function for more flexibility, and rewritten to use E do notation rather than applicative style that melted my brain. ]ignoreTemplate specifies a filter for templates that should be skipped, eg backup files etc. DerrorTemplate specifies a filter which will cause function to fail. A directoryGroupHAppS = directoryGroupNew' ignoret badTmplVarName 4 where ignoret f = not . null . filter (=='#') $ f The STGroup can'%t be shown in a useful way because it'Ps a function type, but you can at least show the directories via Data.Map.keys. # example: getTG "./baselayout" ts' < example: renderTemplateDirGroup ts' "./baselayout" "base"  3 render1 [("name","Bill")] "Hi, my name is $name$" H render1 attribs tmpl = render . setManyAttrib attribs . newSTMP $ tmpl           HStringTemplateHelpers-0.0.10Text.StringTemplate.Helpers STDirGroupsrenderTemplateGroupdirectoryGroups'directoryGroupsOlddirectoryGroupsdirectoryGroupNew' dirgroupKeyslookupDirgroupgetTemplateGrouprenderTemplateDirGroupbadTmplVarNamerender1readTmplTuples readTmplDef readTmplMrenderTemplateGroupSdirectoryGroupNew<$$>safeRead