Add links to tosite tags

This commit is contained in:
Saku Laesvuori 2026-01-22 18:37:18 +02:00
parent d387b7c2ab
commit aa928900f8
6 changed files with 45 additions and 4 deletions

View File

@ -61,6 +61,7 @@ import Data.List (isPrefixOf)
data App = App data App = App
{ settings :: AppConfig DefaultEnv Extra { settings :: AppConfig DefaultEnv Extra
, getStatic :: Static -- ^ Settings for static file serving. , getStatic :: Static -- ^ Settings for static file serving.
, getDocument :: Static
, httpManager :: Manager , httpManager :: Manager
-- --
, appOpts :: WebOpts , appOpts :: WebOpts

View File

@ -19,8 +19,14 @@ import Network.Wai.Middleware.RequestLogger (logStdoutDev, logStdout)
import Network.HTTP.Client (defaultManagerSettings) import Network.HTTP.Client (defaultManagerSettings)
import Network.HTTP.Conduit (newManager) import Network.HTTP.Conduit (newManager)
import Yesod.Default.Config import Yesod.Default.Config
import Yesod.Static (staticDevel, Static(Static))
import WaiAppStatic.Types (StaticSettings(..), LookupResult(LRNotFound), MaxAge(NoMaxAge))
import Control.Applicative ((<|>))
import Control.Monad (sequence)
import System.FilePath (takeDirectory, (</>))
import System.Directory (doesDirectoryExist)
import Hledger.Data (Journal, nulljournal) import Hledger.Data (Journal(jfiles), nulljournal)
import Hledger.Web.Handler.AddR import Hledger.Web.Handler.AddR
import Hledger.Web.Handler.MiscR import Hledger.Web.Handler.MiscR
@ -29,7 +35,7 @@ import Hledger.Web.Handler.UploadR
import Hledger.Web.Handler.JournalR import Hledger.Web.Handler.JournalR
import Hledger.Web.Handler.RegisterR import Hledger.Web.Handler.RegisterR
import Hledger.Web.Import import Hledger.Web.Import
import Hledger.Web.WebOptions (ServerMode(..), WebOpts(server_mode_), corsPolicy) import Hledger.Web.WebOptions (ServerMode(..), WebOpts(server_mode_, document_directory_), corsPolicy)
-- mkYesodDispatch creates our YesodDispatch instance. -- mkYesodDispatch creates our YesodDispatch instance.
-- It complements the mkYesodData call in App.hs, -- It complements the mkYesodData call in App.hs,
@ -42,7 +48,7 @@ mkYesodDispatch "App" resourcesApp
-- migrations handled by Yesod. -- migrations handled by Yesod.
makeApplication :: WebOpts -> Journal -> AppConfig DefaultEnv Extra -> IO Application makeApplication :: WebOpts -> Journal -> AppConfig DefaultEnv Extra -> IO Application
makeApplication opts' j' conf' = do makeApplication opts' j' conf' = do
app <- makeApp conf' opts' app <- makeAppWith j' conf' opts'
writeIORef (appJournal app) j' writeIORef (appJournal app) j'
(logWare . (corsPolicy opts')) <$> toWaiApp app (logWare . (corsPolicy opts')) <$> toWaiApp app
where where
@ -59,11 +65,29 @@ makeApp = makeAppWith nulljournal
makeAppWith :: Journal -> AppConfig DefaultEnv Extra -> WebOpts -> IO App makeAppWith :: Journal -> AppConfig DefaultEnv Extra -> WebOpts -> IO App
makeAppWith j' aconf wopts = do makeAppWith j' aconf wopts = do
s <- staticSite s <- staticSite
let ddd = fmap ((</> "tositteet") . takeDirectory . fst) . listToMaybe $ jfiles j'
when pred a = (\x -> if x then Just a else Nothing) <$> pred
defaultDocumentDir <- fmap join . sequence $ (when <$> doesDirectoryExist <*> id) <$> ddd
let documentDir = document_directory_ wopts <|> defaultDocumentDir
nullStatic = Static $ StaticSettings
{ ssLookupFile = const $ pure LRNotFound
, ssGetMimeType = const $ pure ""
, ssIndices = []
, ssListing = Nothing
, ssMaxAge = NoMaxAge
, ssMkRedirect = const id
, ssRedirectToIndex = False
, ssUseHash = False
, ssAddTrailingSlash = True
, ss404Handler = Nothing
}
documentStatic <- sequence $ staticDevel <$> documentDir
m <- newManager defaultManagerSettings m <- newManager defaultManagerSettings
jref <- newIORef j' jref <- newIORef j'
return App{ return App{
settings = aconf settings = aconf
, getStatic = s , getStatic = s
, getDocument = fromMaybe nullStatic documentStatic
, httpManager = m , httpManager = m
, appOpts = wopts , appOpts = wopts
, appJournal = jref , appJournal = jref

View File

@ -7,9 +7,11 @@
module Hledger.Web.Handler.JournalR where module Hledger.Web.Handler.JournalR where
import qualified Data.Text as T -- for journal.hamlet import qualified Data.Text as T -- also for journal.hamlet
import qualified Text.URI as URI import qualified Text.URI as URI
import Yesod.Static
import Hledger import Hledger
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
import Hledger.Web.Import import Hledger.Web.Import
@ -38,6 +40,7 @@ getJournalR = do
isVisibleTag = not . isHiddenTagName . fst isVisibleTag = not . isHiddenTagName . fst
isPostingTag account tag = not $ tag `elem` journalInheritedAccountTags j account isPostingTag account tag = not $ tag `elem` journalInheritedAccountTags j account
isAbsoluteURI = maybe False URI.isPathAbsolute . URI.mkURI isAbsoluteURI = maybe False URI.isPathAbsolute . URI.mkURI
documentRoute = DocumentR . flip StaticRoute [] . T.splitOn "/"
defaultLayout $ do defaultLayout $ do
setTitle "päiväkirja - hledger-web" setTitle "päiväkirja - hledger-web"

View File

@ -100,6 +100,11 @@ webflags =
(\s opts -> Right $ setopt "base-url" s opts) (\s opts -> Right $ setopt "base-url" s opts)
"BASEURL" "BASEURL"
"set the base url (default: http://IPADDR:PORT)" "set the base url (default: http://IPADDR:PORT)"
, flagReq
["document-directory"]
(\s opts -> Right $ setopt "document-directory" s opts)
"DIRECTORY"
"set the directory to search for tositteet (default: JOURNAL-DIRECTORY/tositteet)"
-- XXX #2139 -- XXX #2139
-- , flagReq -- , flagReq
-- ["file-url"] -- ["file-url"]
@ -143,6 +148,7 @@ data WebOpts = WebOpts
, port_ :: !Int , port_ :: !Int
, base_url_ :: !String , base_url_ :: !String
, file_url_ :: !(Maybe String) , file_url_ :: !(Maybe String)
, document_directory_ :: !(Maybe FilePath)
, allow_ :: !AccessLevel , allow_ :: !AccessLevel
, cliopts_ :: !CliOpts , cliopts_ :: !CliOpts
, socket_ :: !(Maybe String) , socket_ :: !(Maybe String)
@ -156,6 +162,7 @@ defwebopts = WebOpts
, port_ = def , port_ = def
, base_url_ = "" , base_url_ = ""
, file_url_ = Nothing , file_url_ = Nothing
, document_directory_ = Nothing
, allow_ = AddAccess , allow_ = AddAccess
, cliopts_ = def , cliopts_ = def
, socket_ = Nothing , socket_ = Nothing
@ -191,6 +198,7 @@ rawOptsToWebOpts rawopts =
, port_ = p , port_ = p
, base_url_ = b , base_url_ = b
, file_url_ = stripTrailingSlash <$> maybestringopt "file-url" rawopts , file_url_ = stripTrailingSlash <$> maybestringopt "file-url" rawopts
, document_directory_ = maybestringopt "document-directory" rawopts
, allow_ = access , allow_ = access
, cliopts_ = cliopts , cliopts_ = cliopts
, socket_ = sock , socket_ = sock

View File

@ -1,6 +1,7 @@
/favicon.ico FaviconR GET /favicon.ico FaviconR GET
/robots.txt RobotsR GET /robots.txt RobotsR GET
/static StaticR Static getStatic /static StaticR Static getStatic
/document DocumentR Static getDocument
/openapi.json OpenApiR GET /openapi.json OpenApiR GET

View File

@ -45,6 +45,8 @@ $if elem AddPermission perms
<div .tag-value> <div .tag-value>
$if isAbsoluteURI tagValue $if isAbsoluteURI tagValue
<a href="#{tagValue}">#{tagValue} <a href="#{tagValue}">#{tagValue}
$elseif tagName == "tosite"
<a href="@{documentRoute tagValue}">#{tagValue}
$else $else
#{tagValue} #{tagValue}
@ -68,6 +70,8 @@ $if elem AddPermission perms
<div .tag-value> <div .tag-value>
$if isAbsoluteURI tagValue $if isAbsoluteURI tagValue
<a href="#{tagValue}">#{tagValue} <a href="#{tagValue}">#{tagValue}
$elseif tagName == "tosite"
<a href="@{documentRoute tagValue}">#{tagValue}
$else $else
#{tagValue} #{tagValue}