panda 2008.10.26 → 2008.10.27
raw patch · 22 files changed
+234/−181 lines, 22 filesdep +data-defaultdep ~mps
Dependencies added: data-default
Dependency ranges changed: mps
Files
- changelog.markdown +7/−0
- panda.cabal +11/−9
- readme.markdown +1/−1
- src/Panda/Config/Global.hs +84/−49
- src/Panda/Controller/Application.hs +32/−36
- src/Panda/Helper/Env.hs +2/−0
- src/Panda/Helper/Helper.hs +2/−17
- src/Panda/Helper/StateHelper.hs +1/−1
- src/Panda/Model/Comment.hs +4/−2
- src/Panda/Type/Extension.hs +2/−2
- src/Panda/Type/Pager.hs +8/−2
- src/Panda/Type/Reader.hs +5/−2
- src/Panda/Type/Sidebar.hs +0/−20
- src/Panda/Type/State.hs +10/−6
- src/Panda/Type/StaticWidget.hs +20/−0
- src/Panda/Type/Theme.hs +28/−25
- src/Panda/View/Control/Post.hs +1/−1
- src/Panda/View/Widget/Footer.hs +6/−1
- src/Panda/View/Widget/RSS.hs +7/−4
- src/Panda/View/Widget/SearchBar.hs +1/−1
- src/Panda/View/Widget/Sidebar.hs +1/−1
- src/Panda/View/Widget/Template.hs +1/−1
changelog.markdown view
@@ -1,3 +1,10 @@+2008.10.27+-----------++### Feature++* Customizable footer+ 2008.10.26 -----------
panda.cabal view
@@ -1,5 +1,5 @@ Name: panda-Version: 2008.10.26+Version: 2008.10.27 Build-type: Simple Synopsis: A simple static blog engine Description: A simple static blog engine@@ -14,9 +14,11 @@ data-files: readme.markdown, changelog.markdown library- build-depends: base, cgi, network, haskell98, old-locale, old-time, directory, filepath, containers, mps >= 2008.10.15, parsedate >= 3000.0.0, rss >= 3000.0.1, xhtml, kibro >= 0.4.1, utf8-string >= 0.3.1, pandoc >= 0.46, MissingH, parsec >= 2, gravatar >= 0.3+ build-depends: base, cgi, network, haskell98, old-locale, old-time, directory, filepath, containers, mps >= 2008.10.25, parsedate >= 3000.0.0, rss >= 3000.0.1, xhtml, kibro >= 0.4.1, utf8-string >= 0.3.1, pandoc >= 0.46, MissingH, parsec >= 2, gravatar >= 0.3, data-default >= 0.2 hs-source-dirs: src/- exposed-modules: Panda+ exposed-modules: + Main+ Panda.Config.Global Panda.Controller.Application@@ -32,12 +34,13 @@ Panda.Model.Static Panda.Model.Tag + Panda.Type.Extension Panda.Type.Pager Panda.Type.Reader- Panda.Type.Sidebar Panda.Type.State+ Panda.Type.StaticWidget Panda.Type.Theme- Panda.Type.Extension+ Panda.View.Atom.Comment Panda.View.Atom.Post@@ -51,16 +54,15 @@ Panda.View.Control.Static Panda.View.Control.Tag - Panda.View.Widget.Helper Panda.View.Widget.Body Panda.View.Widget.Footer Panda.View.Widget.Head Panda.View.Widget.Header+ Panda.View.Widget.Helper Panda.View.Widget.Navigation Panda.View.Widget.RSS Panda.View.Widget.SearchBar Panda.View.Widget.Sidebar Panda.View.Widget.Template- - Main- ++ Panda
readme.markdown view
@@ -1,4 +1,4 @@ ## Panda: a simple blog engine in Haskell * [Panda homepage](http://www.haskell.org/haskellwiki/Panda)-* [doc](doc/readme)+* Documentation: inside `doc`
src/Panda/Config/Global.hs view
@@ -8,70 +8,105 @@ import Control.Arrow ((>>>), (&&&), (***)) import Data.Maybe import System.Directory+import Data.Default import Panda.Type.Reader-import Panda.Type.Sidebar-import Panda.Type.Theme+import Panda.Type.StaticWidget+import Panda.Type.Theme ( to_theme ) import Panda.Type.Extension -db_id = "db"-flat_id = "."-post_id = "blog"-config_id = "config"-tag_id = "tag"-comment_id = "comment"-sidebar_id = "sidebar"-theme_id = "theme" -db_uri = db_id-flat_uri = db_uri / flat_id+db_id = "db"+flat_id = "."+post_id = "blog"+config_id = "config"+tag_id = "tag"+comment_id = "comment"+sidebar_id = "sidebar"+theme_id = "theme"+config_file_id = "site.txt" -config_uri = flat_uri / config_id / "site.txt"-sidebar_uri = flat_uri / config_id / sidebar_id-post_uri = flat_uri / post_id-tag_uri = flat_uri / tag_id-comment_uri = flat_uri / comment_id-theme_uri = flat_uri / config_id / theme_id+db_uri = db_id+flat_uri = db_uri / flat_id +config_uri = flat_uri / config_id / config_file_id+sidebar_uri = flat_uri / config_id / sidebar_id+footer_uri = flat_uri / config_id+post_uri = flat_uri / post_id+tag_uri = flat_uri / tag_id+comment_uri = flat_uri / comment_id+theme_uri = flat_uri / config_id / theme_id +data ConfigData = + BlogTitle+ | BlogSubtitle+ | HostName+ | AuthorEmail+ | PerPage+ | Navigation+ | Root+ | Sidebar+ | Footer+ | Favicon+ | AnalyticsAccountId+ | Extensions+ | Theme+ | PostDateFormat+ | CommentDateFormat+ | UrlDateFormat+ | UrlDateMatcher+ | UrlTitleSubs+ | UrlDateTitleSeperator+ | Cut+ | SummaryForRoot+ | SummaryForTag+ | SummaryForRss+ deriving (Show)+ -- unsafe, must restart server after changing config file, sorry about that ... -- but these configs are read only, and keep the view pure, so no monad headaches involved. -user_config = parse_config config_uri+user_config = parse_config config_uri+for' x d = user_config.lookup (x.show_data) .fromMaybe d+for_int' x d = for' x d .read :: Int+for_list' x d = for' x d .parse_list+for x = for' x (x.show_data) -config_for' s d = user_config.lookup s .fromMaybe d-config_for s = config_for' s s+blog_title = for BlogTitle+blog_subtitle = for BlogSubtitle+host_name = for HostName+author_email = for AuthorEmail -blog_title = config_for "blog_title"-blog_subtitle = config_for "blog_subtitle"-host_name = config_for "host_name"-author_email = config_for "author_email" +per_page = for_int' PerPage "7"+navigation = for_list' Navigation "About" .("Home" :) -per_page = config_for' "per_page" "7" .read :: Int-navigation = config_for' "navigation" "About" .parse_list.("Home" :)+panda_url = "http://www.haskell.org/haskellwiki/Panda" -panda_url = "http://github.com/nfjinjing/panda" root | user_root.belongs_to ["/", ""] = "/" | otherwise = user_root.("/" /).remove_trailing_slash- where user_root = config_for' "root" "/"+ where user_root = for' Root "/" -default_reader = Markdown+default_reader = def -sidebar = config_for "sidebar" .parse_list .map (sidebar_uri /).select (to_utf8 >>> doesFileExist >>> purify )- .map (read_sidebar_item default_reader >>> purify)- -favicon = config_for' "favicon" "/favicon.ico"+load_widget = read_static_widget default_reader >>> purify+sidebar = for_list' Sidebar "" .map (sidebar_uri /).select (to_utf8 >>> doesFileExist >>> purify )+ .map load_widget +footer = for Footer + .(footer_uri / ) + .(\x -> if x.to_utf8.doesFileExist.purify then Just $ load_widget x else Nothing)+ +favicon = for' Favicon "/favicon.ico" -- extensions-analytics_account_id = config_for "analytics_account_id"-extensions = config_for' "extensions" "search, comment, analytics" .parse_list .to_extensions+analytics_account_id = for AnalyticsAccountId+extensions = for_list' Extensions "search, comment, analytics" .read_data_list :: [Extension] -- theme-default_theme = blank_theme-user_theme_name = config_for "theme"-user_theme_uri = (theme_uri / user_theme_name) ++ ".txt"+default_theme = def+user_theme_name = for Theme+user_theme_uri = (theme_uri / user_theme_name) ++ ".txt" theme = if user_theme_uri.doesFileExist.purify then parse_config user_theme_uri .(("name", user_theme_name) : ) .to_theme@@ -79,19 +114,19 @@ -- custom as_l s = "[" ++ s ++ "]"-post_date_format = config_for' "post_date_format" "%y-%m-%d"-comment_date_format = config_for' "comment_date_format" "%y-%m-%d %T"-url_date_format = config_for' "url_date_format" "%y-%m-%d"-url_date_matcher = config_for' "url_date_matcher" "\\d{2}-\\d{2}-\\d{2}"-url_title_subs = config_for' "url_title_subs" "" .as_l .read :: [(String, String)]-url_date_title_seperator = config_for' "url_date_title_seperator" " "+post_date_format = for' PostDateFormat "%y-%m-%d"+comment_date_format = for' CommentDateFormat "%y-%m-%d %T"+url_date_format = for' UrlDateFormat "%y-%m-%d"+url_date_matcher = for' UrlDateMatcher "\\d{2}-\\d{2}-\\d{2}"+url_title_subs = for' UrlTitleSubs "" .as_l .read :: [(String, String)]+url_date_title_seperator = for' UrlDateTitleSeperator " " -- summary-cut = config_for' "cut" "✂-----" .to_utf8+cut = for' Cut "✂-----" .to_utf8 parse_boolean = belongs_to ["true", "1", "y", "yes", "yeah"]-summary_for_root = config_for "summary_for_root" .parse_boolean-summary_for_tag = config_for "summary_for_tag" .parse_boolean-summary_for_rss = config_for "summary_for_rss" .parse_boolean+summary_for_root = for SummaryForRoot .parse_boolean+summary_for_tag = for SummaryForTag .parse_boolean+summary_for_rss = for SummaryForRss .parse_boolean
src/Panda/Controller/Application.hs view
@@ -13,7 +13,7 @@ -- env import Panda.Helper.Env hiding (tag, uri)-import Panda.Helper.StateHelper+import Panda.Helper.StateHelper hiding (only_for) import Prelude hiding ((.), (/), (^), id) import qualified Panda.Type.State as S import qualified Panda.Config.Global as G@@ -36,42 +36,39 @@ -- helpers -- liftIO: move to an (u)pper level monad-u = liftIO-blog_regex = G.url_date_matcher--init_post tags x = do- x.Tag.fill_tag tags.Comment.fill_comment_size.u--tag_list = Tag.list.u+u = liftIO+blog_regex = G.url_date_matcher+init_post tags x = x.Tag.fill_tag tags.Comment.fill_comment_size.u+tag_list = Tag.list.u -- main controller pages = - [ ("$" ,index )- , ("(\\?.+)?$" ,index )- , ("rss.xml$" ,index_feed )- , (blog_regex ,blog )- , ("static/." ,static )- , ("tag/.*/rss.xml$" ,tag_feed )- , ("tag/." ,tag )- , ("search" ,route_for_extension Search $ search )- , ("comment/create" ,route_for_extension Comment $ comment_create )+ [ ("$" ,index )+ , ("(\\?.+)?$" ,index )+ , ("rss.xml$" ,index_feed )+ , (blog_regex ,blog )+ , ("static/." ,static )+ , ("tag/.*/rss.xml$" ,tag_feed )+ , ("tag/." ,tag )+ , ("search" ,only_for Search $ search )+ , ("comment/create" ,only_for Comment $ comment_create ) ] .map_fst ((G.root /) >>> ("^" ++)) ++- [ ("^" ++ G.root ++ "$" ,index )- , ("^" ++ G.root ++ "?" ,index )+ [ ("^" ++ G.root ++ "$" ,index )+ , ("^" ++ G.root ++ "?" ,index ) ] -route_for_extension ext x = if has_extension ext then x else not_found+only_for ext x = if has_extension ext then x else not_found index = do posts <- Post.list.u p <- paginate posts tags <- tag_list let nav = if p.Pager.current == 1 then home_nav else no_navigation- let state = S.empty { S.uid = G.post_id, S.pager = p, S.tags = tags, S.nav_location = nav }+ let state = def { S.uid = G.post_id, S.pager = p, S.tags = tags, S.nav_location = nav } posts.mapM (init_post tags) ^ PostV.list state >>= output_html @@ -86,7 +83,7 @@ tags <- tag_list test_data <- S.mk_human_test .u- let state = S.empty { S.uid = id, S.tags = tags, S.resource_title = blog.resource_title, S.human_test_data = test_data }+ let state = def { S.uid = id, S.tags = tags, S.resource_title = blog.resource_title, S.human_test_data = test_data } blog.(init_post tags) ^ PostV.view state comments >>= output_html @@ -97,7 +94,7 @@ let nav_id = static_page.Static.uid.id_to_resource let nav = if nav_id.belongs_to G.navigation then nav_id else no_navigation- let state = S.empty { S.uid = id, S.tags = tags, S.nav_location = nav, S.resource_title = static_page.resource_title }+ let state = def { S.uid = id, S.tags = tags, S.nav_location = nav, S.resource_title = static_page.resource_title } StaticV.view state static_page .output_html tag = do@@ -109,7 +106,7 @@ Just post_set -> do posts <- post_set.to_list.rsort.mapM (Post.get) .u >>= mapM (init_post tags) p <- paginate posts- let state = S.empty { S.uid = id, S.pager = p, S.tags = tags, S.resource_title = tag_name.Tag.resource_title_from_name }+ let state = def { S.uid = id, S.pager = p, S.tags = tags, S.resource_title = tag_name.Tag.resource_title_from_name } posts.TagV.view state.output_html tag_feed = do@@ -129,7 +126,7 @@ p <- paginate posts tags <- tag_list query <- uri- let state = S.empty { S.uid = query, S.pager = p, S.tags = tags, S.resource_title = query }+ let state = def { S.uid = query, S.pager = p, S.tags = tags, S.resource_title = query } posts.mapM (init_post tags) >>= \x -> x.SearchV.view state s.output_html @@ -149,20 +146,19 @@ get_input_data = show_data >>> get_input check_human = do- x <- [Comment.LeftNumber, Comment.RightNumber, Comment.Operator, Comment.HumanHack].mapM get_input_data ^ map fromJust- let [l, r, op, h] = x+ [l, r, op, h] <- [Comment.LeftNumber, Comment.RightNumber, Comment.Operator, Comment.HumanHack].mapM get_input_data ^ map fromJust return $ S.simple_eval (l.read) (r.read) (op.S.read_op) .is (h.read) -- create helper, should be refactored to some common aspect check_create =- [ validate Comment.Author ( length >>> (> 0))- , validate Comment.AuthorLink ( const True)- , validate Comment.Body ( length >>> (> 0))- , validate Comment.EmptyField ( empty )- , validate Comment.LeftNumber ( belongs_to (S.nums.map show))- , validate Comment.RightNumber ( belongs_to (S.nums.map show))- , validate Comment.Operator ( belongs_to (S.ops.map S.display_op))- , validate Comment.HumanHack ( belongs_to (S.nums.map show))+ [ validate Comment.Author ( length >>> (> 0))+ , validate Comment.AuthorLink ( const True)+ , validate Comment.Body ( length >>> (> 0))+ , validate Comment.EmptyField ( empty )+ , validate Comment.LeftNumber ( belongs_to (S.nums.map show))+ , validate Comment.RightNumber ( belongs_to (S.nums.map show))+ , validate Comment.Operator ( belongs_to (S.ops.map S.display_op))+ , validate Comment.HumanHack ( belongs_to (S.nums.map show)) , check_human ] .sequence ^ and @@ -171,4 +167,4 @@ maybe_s <- get_input_data s case maybe_s of Nothing -> return False- Just v -> return $ f v+ Just v -> return $ f v
src/Panda/Helper/Env.hs view
@@ -18,6 +18,7 @@ , module System.Time , module System.Directory , module Data.Foldable+ , module Data.Default ) where import MPS hiding (base, col, sub, date)@@ -36,3 +37,4 @@ import System.Time import System.Directory import Data.Foldable (find)+import Data.Default
src/Panda/Helper/Helper.hs view
@@ -14,7 +14,7 @@ import Text.XHtml.Strict import Control.Monad hiding (join) import Data.Maybe-import Panda.Type.Pager as Pager hiding (empty)+import Panda.Type.Pager as Pager import MPS hiding (date) import Prelude hiding ((.), (/), (^), id, readFile, writeFile) import Char@@ -23,14 +23,12 @@ import Panda.Type.Reader import System.FilePath.Posix hiding ((<.>)) import System.Time+import Data.Default (/) = (</>) infixl 5 / -(^) = (<.>)-infixl 9 ^- -- global parse_config_io s = readFile s ^ (\x -> x.filter_comment.lines.map strip .map (split "\\s*=\\s*") .map fill_snd_blank .map tuple2) where fill_snd_blank [x] = [x,""]@@ -106,18 +104,7 @@ -- generic--starts_with _ [] = False-starts_with (x:xs) (y:ys) | x == y = starts_with xs ys- | otherwise = False--ends_with x y = starts_with (x.reverse) (y.reverse)--capitalize (x:xs) = [x].upper ++ xs.lower-camel_case = split "_" >>> map capitalize >>> join'-snake_case = gsub "\\B[A-Z]" "_\\&" >>> lower show_data = show >>> snake_case- -- class class DataRenderer a where@@ -134,5 +121,3 @@ class Addressable a where uri :: a -> String--
src/Panda/Helper/StateHelper.hs view
@@ -34,7 +34,7 @@ default_parse_date s = s.parse_post_date .fromMaybe default_date has_extension x = G.extensions.has x-for_extension ext x = if has_extension ext then x else toHtml ""+only_for ext x = if has_extension ext then x else toHtml "" -- controller paginate = length >>> full_paginate (G.per_page)
src/Panda/Model/Comment.hs view
@@ -44,6 +44,8 @@ instance Datable Comment where date x = x.uid.split "/".last.default_parse_date +instance Default Comment where+ def = Comment def def def def def -- CRUD list_for post_id = do@@ -96,7 +98,7 @@ write_config_io (uid ++ ".meta") meta -- extra-from_post_id x = Comment (post_id_to_uid x) "" "" "" ""+from_post_id x = def { uid = post_id_to_uid x } post_id_to_uid x = G.flat_uri / G.comment_id / x.split "/" .last uid_to_post_id x = G.post_id / x.split "/" .last@@ -106,4 +108,4 @@ return $ x { Post.comment_size = size } gravatar_default_size = size 40-gravatar_link x = gravatarWith (x.author_email) Nothing gravatar_default_size Nothing+gravatar_link x = gravatarWith (x.author_email) def gravatar_default_size def
src/Panda/Type/Extension.hs view
@@ -11,6 +11,6 @@ deriving (Show, Read, Eq) -to_extension s = s.camel_case.read :: Extension-to_extensions xs = xs.map to_extension+read_data s = s.camel_case.read+read_data_list xs = xs.map read_data
src/Panda/Type/Pager.hs view
@@ -1,5 +1,7 @@ module Panda.Type.Pager where- ++import Data.Default+ data Pager = Pager { length :: Int, current :: Int,@@ -9,5 +11,9 @@ previous :: Int } deriving (Eq, Show)++instance Default Bool where+ def = False -empty = Pager 0 0 False False 0 0+instance Default Pager where+ def = Pager def def def def def def
src/Panda/Type/Reader.hs view
@@ -8,9 +8,12 @@ import Text.Pandoc import Control.Arrow ((>>>)) import Text.XHtml.Strict-import Data.Generics+import Data.Default -data Reader = Markdown | RST | HTML | Latex deriving (Show, Eq, Typeable, Data)+data Reader = Markdown | RST | HTML | Latex deriving (Show, Eq)++instance Default Reader where+ def = Markdown readers = [ (Markdown, ["markdown", "md"])
− src/Panda/Type/Sidebar.hs
@@ -1,20 +0,0 @@-module Panda.Type.Sidebar where--import Panda.Helper.Env hiding (body)-import Prelude hiding ((.), (/), (^), id, readFile)-import Panda.Type.Reader--data SidebarItem = SidebarItem- { name :: String- , body :: String- , reader :: Reader- }- deriving (Show, Eq)--instance Markable SidebarItem where- markup x = render_to_html (x.reader) (x.body)--read_sidebar_item default_reader s = liftM2 (SidebarItem name) body (return reader) where- body = s.to_utf8.readFile- reader = s.take_extension.guess_reader.fromMaybe default_reader- name = s.takeFileName.dropExtension
src/Panda/Type/State.hs view
@@ -7,6 +7,7 @@ import Control.Arrow ((>>>), (&&&), (***)) import MPS import Prelude hiding ((.), (/), (^), id, readFile, writeFile)+import Data.Default data State = State -- model state@@ -33,19 +34,22 @@ display_op Minus = "-" data HumanTestData = HumanTestData - { left :: Int+ { left :: Int , right :: Int- , op :: Op+ , op :: Op } deriving (Show) +instance Default HumanTestData where+ def = HumanTestData def def def+ data Op = Plus | Minus deriving (Show) -empty = State "" Pager.empty [] "" "" empty_human_test-empty_human_test = HumanTestData 0 0 Plus+instance Default Op where+ def = Plus +instance Default State where+ def = State def def def def def def -(^) = (<.>)-infixl 9 ^ ops = [Plus, Minus] nums = [0, 5, 10, 15, 20]
+ src/Panda/Type/StaticWidget.hs view
@@ -0,0 +1,20 @@+module Panda.Type.StaticWidget where++import Panda.Helper.Env hiding (body)+import Prelude hiding ((.), (/), (^), id, readFile)+import Panda.Type.Reader++data StaticWidget = StaticWidget+ { name :: String+ , body :: String+ , reader :: Reader+ }+ deriving (Show, Eq)++instance Markable StaticWidget where+ markup x = render_to_html (x.reader) (x.body)++read_static_widget default_reader s = liftM2 (StaticWidget name) body (return reader) where+ body = s.to_utf8.readFile+ reader = s.take_extension.guess_reader.fromMaybe default_reader+ name = s.takeFileName.dropExtension
src/Panda/Type/Theme.hs view
@@ -14,31 +14,34 @@ , css :: [String] , js :: [String] } deriving (Show, Read)- ++data ThemeData = + Name+ | Container+ | Header+ | Navigation+ | Main+ | Sidebar+ | Footer+ | Css+ | Js+ deriving (Eq, Show, Read)+ to_theme xs = Theme - { name = at "name"- , container = at "container"- , header = at "header"- , navigation = at "navigation"- , main = at "main"- , sidebar = at "sidebar"- , footer = at "footer"- , css = at "css" .css_list- , js = at "js" .js_list+ { name = at Name+ , container = at Container+ , header = at Header+ , navigation = at Navigation+ , main = at Main+ , sidebar = at Sidebar+ , footer = at Footer+ , css = at Css .css_list+ , js = at Js .js_list } where- at s = xs.lookup s .fromJust- css_list s = s.parse_list.map (\x -> "/theme/" ++ at "name" ++ "/css/" ++ x ++ ".css")- js_list s = s.parse_list.map (\x -> "/theme/" ++ at "name" ++ "/js/" ++ x ++ ".js")- -blank_theme = Theme- { name = ""- , container = ""- , header = ""- , navigation = ""- , main = ""- , sidebar = ""- , footer = ""- , css = [""]- , js = [""]- }+ at s = xs.lookup (s.show_data) .fromJust+ css_list s = s.parse_list.map (\x -> "/theme/" ++ at Name ++ "/css/" ++ x ++ ".css")+ js_list s = s.parse_list.map (\x -> "/theme/" ++ at Name ++ "/js/" ++ x ++ ".js")++instance Default Theme where+ def = Theme def def def def def def def def def
src/Panda/View/Control/Post.hs view
@@ -22,7 +22,7 @@ -- entry view view state xs x = (x.render_data +++ comment_view ).page state- where comment_view = for_extension Comment $ CommentV.list xs +++ CommentV.create state (x.uid.Comment.from_post_id)+ where comment_view = only_for Comment $ CommentV.list xs +++ CommentV.create state (x.uid.Comment.from_post_id) -- list view list state = for_current_page p >>> map render >>> (+++ nav p G.root) >>> page state where
@@ -5,7 +5,7 @@ import qualified Panda.Config.Global as G -footer c = div_class_id c "footer" <<+static_footer c = toHtml [ toHtml $ copyright , toHtml $ "2008 " , toHtml $ G.blog_title@@ -15,3 +15,8 @@ , toHtml $ " using " , toHtml $ hotlink "http://www.haskell.org/" << "Haskell" ]+ +custom_footer _ | G.footer.isJust = G.footer.fromJust.markup+custom_footer x = static_footer x++footer c = div_class_id c "footer" << custom_footer c
src/Panda/View/Widget/RSS.hs view
@@ -14,8 +14,8 @@ -- RSS channel_rss_template = [ RSS.Language "en-us" ] -render_rss x | G.summary_for_rss.is True = x.markup_summary.show-render_rss x | otherwise = x.markup.show+render_rss x | G.summary_for_rss.is True = x.markup_summary.show+ | otherwise = x.markup.show item_rss_template x = [ Title $ x.Post.title@@ -25,8 +25,11 @@ , PubDate $ x.date ] -item_uri x = nullURI { uriScheme = "http://", uriPath = host_link (x.uri) }-rss_uri x = nullURI { uriScheme = "http://", uriPath = host_link x }+instance Default URI where+ def = nullURI++item_uri x = def { uriScheme = "http://", uriPath = host_link (x.uri) }+rss_uri x = def { uriScheme = "http://", uriPath = host_link x } rss categary s xs = RSS title (rss_uri link) title channel_rss_template (xs.take 20 .map item_rss_template) .rssToXML.showXML
src/Panda/View/Widget/SearchBar.hs view
@@ -6,4 +6,4 @@ import Panda.Type.Extension import Panda.Helper.StateHelper -search_bar = for_extension Search $ div_id "search" << form ! [action (G.root / "search"), method "get"] << thediv << textfield "s"+search_bar = only_for Search $ div_id "search" << form ! [action (G.root / "search"), method "get"] << thediv << textfield "s"
src/Panda/View/Widget/Sidebar.hs view
@@ -6,7 +6,7 @@ import qualified Data.Set as Set import qualified Panda.Config.Global as G-import qualified Panda.Type.Sidebar as Sidebar+import qualified Panda.Type.StaticWidget as Sidebar import Panda.View.Widget.Helper -- model
src/Panda/View/Widget/Template.hs view
@@ -27,7 +27,7 @@ , div_id "page" << [ div_class (t.T.main) << body_content x, sidebar (t.T.sidebar) state ] , footer (t.T.footer) ]- , for_extension Analytics $ primHtml analytics_snippet+ , only_for Analytics $ primHtml analytics_snippet ] template t state x = [html_head state, body t state x]