diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md
index 014d31e6..ca064c77 100644
--- a/DOCUMENTATION.md
+++ b/DOCUMENTATION.md
@@ -67,7 +67,7 @@ new to you, it may be enough to skim through some of the examples in the
otherwise the ginger docs can be very helpful to see what is supported.
Templates are a folder containing a number of ginger template files. There are
-4 "scopes", each making available a unique set of variables storing information
+5 "scopes", each making available a unique set of variables storing information
about the git repositories. Each template file has access to a single one of
these scopes. The structure of the template folder determines the scopes of the
files contained therein.
@@ -82,8 +82,9 @@ To illustrate, this is the expected structure:
repo/
inside_this_folder.html
two_names_are_special.html
- file.html
- commit.html
+ foreach.blob.html
+ foreach.commit.html
+ foreach.tree.html
The top-level folder, here `template`, is that which is specified in the config
file.
@@ -98,9 +99,14 @@ The special folder "repo" has access to the *repo scope*, which exposes
information pertaining to a single git repository. The template files contained
within this folder are parsed and output once per git repository.
-The exceptions to this are the two special template files with the names
-"file.html" and "commit.html". These have access to the *file scope* and
-*commit scope* respectively, and are parsed and output once per file or commit.
+The exceptions to this are the three special template files with the names
+"foreach.blob.html", "foreach.commit.html" and "foreach.tree.html" - named to
+make clear that, unlike everything else in "repo/", these are parsed and
+output once *per* blob, commit or tree found anywhere in the repository, at
+any depth, rather than once per repository. These have access to the *blob
+scope*, *commit scope* and *tree scope* respectively (a submodule reference
+is currently treated as a blob whose content is its target commit hash,
+rather than as its own scope).
The resulting folder structure found in `output` will look like this (if
`repos` only contains gitja):
@@ -112,7 +118,7 @@ The resulting folder structure found in `output` will look like this (if
gitja/
inside_this_folder.html
two_names_are_special.html
- file/
+ blob/
LICENSE.html
Makefile.html
...
@@ -120,6 +126,9 @@ The resulting folder structure found in `output` will look like this (if
0a18f38bb5c398bd192a6268281fc6abefaedd63.html
0a7601059956d9c4d395f5d08e8cf48a515d080f.html
...
+ tree/
+ src.html
+ ...
...
### Static files
@@ -145,16 +154,20 @@ The variables available within each scope are listed here for reference:
| | name | The repository name, taken from its folder name. |
| | description | The repository's description (see below). |
| | commits | A list of the repository's commits. |
-| | tree | A list of the top-level folder's contents. |
-| | tree\_recursive | A list of *all* of the repository's contents. |
+| | tree | A list of the repository root tree's entries. |
+| | entries | A flat list of *every* entry (blob or tree) at any depth in the repository, like `git ls-tree -r -t`. |
+| | blobs | A flat list of *every* blob (file) in the repository. |
+| | trees | A flat list of *every* tree (directory) at any depth in the repository. |
| | tags | A list of the refs corresponding to tags. |
| | branches | A list of the refs corresponding to branches. |
| | readme | The repository's readme file, if it has one. |
| | license | The repository's license file, if it has one. |
-| File | | *In addition to the variables from the Repo scope...* |
-| | file | A single file. |
+| Blob | | *In addition to the variables from the Repo scope...* |
+| | blob | A single blob (file). |
| Commit | | *In addition to the variables from the Repo scope...* |
| | commit | A single commit. |
+| Tree | | *In addition to the variables from the Repo scope...* |
+| | tree | A single tree (directory) - shadows the repo-scope `tree`, since a tree page is itself scoped to one tree. |
As in [Jinja](https://jinja.palletsprojects.com), a list can be accessed with
indexing, and attributes can be accessed using a dot notation. For example, a
@@ -170,17 +183,17 @@ Here is the reference of attributes available on the variables that have them:
| | description | The repository's description (see below). |
| | head | The current git commit. |
| | updated | The time when the current commit was committed. |
-| file | path | The path the file relative to the repository root. |
-| | name | The name of the file. |
-| | href | The name of the HTML file for this file. |
-| | contents | The file's contents. |
+| blob/tree | path | The path relative to the repository root. |
+| | name | The name of the blob or tree. |
+| | href | The name of the HTML file for this blob or tree. |
+| | contents | The blob's contents (n/a for a tree). |
| | mode | Directory, Plain, Executable, Symlink or Submodule. |
| | mode\_octal | Mode in octal form e.g. "00644" for plain files. |
| | mode\_symbolic | Mode in symbolic form e.g. ""-rw-r--r--" for plain files.|
| | is\_directory | A boolean, useful for ginger conditionals. |
| | is\_binary | A boolean, tells you if the contents can be rendered. |
-| | tree | A list of a directory's direct contents. |
-| | tree\_recursive | A list of *all* of a directory's contents. |
+| | tree | This tree's direct contents (n/a for a blob). |
+| | entries | A flat list of *every* entry (blob or tree) at any depth under this tree (n/a for a blob). |
| ref | name | The tag or branch name. |
| | commit | The commit pointed to by the tag or branch. |
| commit | id | The SHA of the given commit. |
diff --git a/src/Env.hs b/src/Env.hs
index e579e43e..9aee69f8 100644
--- a/src/Env.hs
+++ b/src/Env.hs
@@ -68,7 +68,8 @@ data Env = Env
{ envConfig :: Config
, envIndexTemplates :: [Template]
, envCommitTemplate :: Maybe Template
- , envFileTemplate :: Maybe Template
+ , envBlobTemplate :: Maybe Template
+ , envTreeTemplate :: Maybe Template
, envRepoTemplates :: [Template]
, envOutput :: Path Abs Dir
, envRepos :: [Path Abs Dir]
@@ -104,16 +105,17 @@ loadEnv quiet force config = do
-- Load files from template directory
indexT <- collectTemplates files
- commitT <- findTemplate "commit.html" filesRepo
- fileT <- findTemplate "file.html" filesRepo
+ commitT <- findTemplate "foreach.commit.html" filesRepo
+ blobT <- findTemplate "foreach.blob.html" filesRepo
+ treeT <- findTemplate "foreach.tree.html" filesRepo
repoT <-
collectTemplates
- . filter (flip notElem ["commit.html", "file.html"] . toFilePath . filename)
+ . filter (flip notElem ["foreach.commit.html", "foreach.blob.html", "foreach.tree.html"] . toFilePath . filename)
$ filesRepo
-- Exit early if we didn't find any templates
when
- ( all null [indexT, repoT] && all isNothing [commitT, fileT]
+ ( all null [indexT, repoT] && all isNothing [commitT, blobT, treeT]
)
$ die "No templates were found."
@@ -123,7 +125,8 @@ loadEnv quiet force config = do
{ envConfig = config
, envIndexTemplates = indexT
, envCommitTemplate = commitT
- , envFileTemplate = fileT
+ , envBlobTemplate = blobT
+ , envTreeTemplate = treeT
, envRepoTemplates = repoT
, envOutput = output
, envRepos = repos
diff --git a/src/Repositories.hs b/src/Repositories.hs
index 2635bff7..5768a9af 100644
--- a/src/Repositories.hs
+++ b/src/Repositories.hs
@@ -132,9 +132,11 @@ processRepo' env repos repo = do
withRunInIO \runInIO -> do
-- Create the destination folders --
commitDir <- (directory >) <$> parseRelDir "commit"
- fileDir <- (directory >) <$> parseRelDir "file"
+ blobDir <- (directory >) <$> parseRelDir "blob"
+ treeDir <- (directory >) <$> parseRelDir "tree"
ensureDir commitDir
- ensureDir fileDir
+ ensureDir blobDir
+ ensureDir treeDir
-- Check which commits are new since the last run --
newCommits <- getUpdates commitDir commits
@@ -149,12 +151,21 @@ processRepo' env repos repo = do
whenJust (envCommitTemplate env) \commitT -> do
mapM_ (gen force commitT "commit" commitDir commitHref) newCommits
- whenJust (envFileTemplate env) \fileT -> do
+ whenJust (envBlobTemplate env) \blobT -> do
+ let allBlobs = concatMap flattenFiles tree
if force
- then mapM_ (gen True fileT "file" fileDir fileHref) tree
+ then mapM_ (gen True blobT "blob" blobDir blobHref) allBlobs
else
- let updatedFiles = getUpdatedFiles tree newCommits
- in mapM_ (gen True fileT "file" fileDir fileHref) updatedFiles
+ let updatedBlobs = getUpdatedFiles allBlobs newCommits
+ in mapM_ (gen True blobT "blob" blobDir blobHref) updatedBlobs
+
+ whenJust (envTreeTemplate env) \treeT -> do
+ -- A tree's own path never appears in a commit's diff (only
+ -- the blobs within it do), so unlike blobs, staleness can't
+ -- be judged by newCommits/getUpdatedFiles - always
+ -- regenerate every tree page.
+ let allTrees = concatMap flattenTrees tree
+ mapM_ (gen True treeT "tree" treeDir treeHref) allTrees
-- Copy any static files/folders into the output directory --
envRepoCopyStatics env directory
@@ -174,7 +185,7 @@ package ::
Path Rel Dir ->
T.Text ->
[Commit] ->
- [TreeFile] ->
+ [TreeEntry] ->
HashMap.HashMap T.Text (GVal RunRepo)
package env repos name description commits tree =
HashMap.fromList
@@ -183,16 +194,18 @@ package env repos name description commits tree =
, ("name", toGVal . T.pack . init . toFilePath $ name)
, ("description", toGVal description)
, ("commits", toGVal commits)
- , ("tree", toGVal . filter (notElem FP.pathSeparator . T.unpack . treeFilePath) $ tree)
- , ("tree_recursive", toGVal tree)
+ , ("tree", toGVal tree)
+ , ("entries", toGVal . concatMap flattenTree $ tree)
+ , ("blobs", toGVal . concatMap flattenFiles $ tree)
+ , ("trees", toGVal . concatMap flattenTrees $ tree)
, ("readme", toGVal . findFile "readme" $ tree)
, ("license", toGVal . findFile "license" $ tree)
]
where
-- Find a file in the tree starting with the specified prefix. The prefix is looked
-- for on the full path, so will only find files in the top level directory.
- findFile :: T.Text -> [TreeFile] -> Maybe TreeFile
- findFile prefix = find (T.isPrefixOf prefix . T.toLower . treeFilePath)
+ findFile :: T.Text -> [TreeEntry] -> Maybe TreeEntry
+ findFile prefix = find (T.isPrefixOf prefix . T.toLower . treeEntryPath)
{-
Collect commit history up to a head.
@@ -298,17 +311,17 @@ loadDiff gitCommit = do
Collect tree information for the given commit. Recurses on directories to list their
contents.
-}
-getTree :: Git.CommitOid LgRepo -> ReaderT LgRepo IO [TreeFile]
+getTree :: Git.CommitOid LgRepo -> ReaderT LgRepo IO [TreeEntry]
getTree = getTree' "" 0 . Git.commitTree <=< Git.lookupCommit
where
- getTree' :: Git.TreeFilePath -> Int -> Git.TreeOid LgRepo -> ReaderT LgRepo IO [TreeFile]
+ getTree' :: Git.TreeFilePath -> Int -> Git.TreeOid LgRepo -> ReaderT LgRepo IO [TreeEntry]
getTree' parent count toid = do
one <- Git.lookupTree toid
entries <- Git.listTreeEntries one
let entries' = fmap (prependParent parent) entries
contents <- mapM (\x -> getEntryContents x (count + 1)) entries'
modes <- mapM (getEntryModes . snd) entries'
- return $ zipWith3 TreeFile (fmap treePaths entries') contents modes
+ return $ zipWith3 TreeEntry (fmap treePaths entries') contents modes
prependParent ::
Git.TreeFilePath ->
@@ -317,7 +330,7 @@ getTree = getTree' "" 0 . Git.commitTree <=< Git.lookupCommit
prependParent "" pathentry = pathentry
prependParent parent (path, entry) = (mconcat [parent, "/", path], entry)
- getEntryContents :: (Git.TreeFilePath, Git.TreeEntry LgRepo) -> Int -> ReaderT LgRepo IO TreeFileContents
+ getEntryContents :: (Git.TreeFilePath, Git.TreeEntry LgRepo) -> Int -> ReaderT LgRepo IO TreeEntryContents
getEntryContents (_, Git.BlobEntry oid _) _ = getBlobContents oid
getEntryContents (path, Git.TreeEntry oid) count = FolderContents <$> getTree' path count oid
getEntryContents (_, Git.CommitEntry oid) _ = return . FileContents . B.fromString . show . untag $ oid
@@ -372,10 +385,20 @@ getUpdates directory cs = go cs
(return [])
((x :) <$> go xs)
-getUpdatedFiles :: [TreeFile] -> [Commit] -> [TreeFile]
+flattenFiles :: TreeEntry -> [TreeEntry]
+flattenFiles treeentry = case treeEntryContents treeentry of
+ FolderContents files -> concatMap flattenFiles files
+ _ -> [treeentry]
+
+flattenTrees :: TreeEntry -> [TreeEntry]
+flattenTrees treeentry = case treeEntryContents treeentry of
+ FolderContents files -> treeentry : concatMap flattenTrees files
+ _ -> []
+
+getUpdatedFiles :: [TreeEntry] -> [Commit] -> [TreeEntry]
getUpdatedFiles [] _ = []
getUpdatedFiles _ [] = []
-getUpdatedFiles files commits = filter ((`elem` updated) . treeFilePath) files
+getUpdatedFiles files commits = filter ((`elem` updated) . treeEntryPath) files
where
updated :: [T.Text]
updated = fmap (bsToText . diffNewFile) . concatMap commitDiffs $ commits
@@ -425,8 +448,11 @@ genTarget scope runInIO quiet force template category directory href target = do
commitHref :: Commit -> FilePath
commitHref = (++ ".html") . commitHash
-fileHref :: TreeFile -> FilePath
-fileHref = T.unpack . treePathToHref
+blobHref :: TreeEntry -> FilePath
+blobHref = T.unpack . treePathToHref
+
+treeHref :: TreeEntry -> FilePath
+treeHref = T.unpack . treePathToHref
{-
With a dictionary of preloaded values and a function to access additional data, create a
diff --git a/src/Types.hs b/src/Types.hs
index 233a446e..074a1884 100644
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -14,7 +14,7 @@ import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Reader (ReaderT)
import Data.ByteString (ByteString)
import Data.Default (def)
-import Data.Maybe (fromMaybe, listToMaybe)
+import Data.Maybe (listToMaybe)
import Data.Tagged (untag)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8With)
@@ -214,15 +214,16 @@ lineAsLookup line = \case
{-
Next we have some data used to represent a repository's tree and the different kinds of
-objects contained therein.
+objects contained therein. A TreeEntry is any single entry found in a git tree object -
+a blob, a nested tree, or a commit (submodule reference).
-}
-data TreeFile = TreeFile
- { treeFilePath :: T.Text
- , treeFileContents :: TreeFileContents
- , treeFileMode :: TreeEntryMode
+data TreeEntry = TreeEntry
+ { treeEntryPath :: T.Text
+ , treeEntryContents :: TreeEntryContents
+ , treeEntryMode :: TreeEntryMode
}
-data TreeFileContents = BinaryContents | FileContents ByteString | FolderContents [TreeFile]
+data TreeEntryContents = BinaryContents | FileContents ByteString | FolderContents [TreeEntry]
data TreeEntryMode = ModeDirectory | ModePlain | ModeExecutable | ModeSymlink | ModeSubmodule
deriving stock (Show)
@@ -240,7 +241,7 @@ blobkindToMode Git.SymlinkBlob = ModeSymlink
{-
This
-}
-getBlobContents :: Git.BlobOid LgRepo -> ReaderT LgRepo IO TreeFileContents
+getBlobContents :: Git.BlobOid LgRepo -> ReaderT LgRepo IO TreeEntryContents
getBlobContents oid = do
repo <- Git.getRepository
blobPtr <- liftIO mallocForeignPtr
@@ -259,59 +260,63 @@ getBlobContents oid = do
GVal implementations for data definitions above, allowing commits to be rendered in
Ginger templates.
-}
-instance ToGVal m TreeFile where
- toGVal :: TreeFile -> GVal m
- toGVal treefile =
+instance ToGVal m TreeEntry where
+ toGVal :: TreeEntry -> GVal m
+ toGVal treeentry =
def
- { asHtml = html . treeFilePath $ treefile
- , asText = treeFilePath treefile
- , asLookup = Just . treeAsLookup $ treefile
+ { asHtml = html . treeEntryPath $ treeentry
+ , asText = treeEntryPath treeentry
+ , asLookup = Just . treeAsLookup $ treeentry
, asBoolean = True -- Used for conditionally checking readme/license template variables.
}
-instance ToGVal m TreeFileContents where
- toGVal :: TreeFileContents -> GVal m
+instance ToGVal m TreeEntryContents where
+ toGVal :: TreeEntryContents -> GVal m
toGVal BinaryContents = def
toGVal (FileContents bytestring) = toGVal bytestring
- toGVal (FolderContents treeFiles) =
+ toGVal (FolderContents treeEntries) =
def
- { asHtml = html . T.pack . show . fmap treeFilePath $ treeFiles
- , asText = T.pack . show . fmap treeFilePath $ treeFiles
- , asList = Just . fmap toGVal $ treeFiles
+ { asHtml = html . T.pack . show . fmap treeEntryPath $ treeEntries
+ , asText = T.pack . show . fmap treeEntryPath $ treeEntries
+ , asList = Just . fmap toGVal $ treeEntries
}
-treeAsLookup :: TreeFile -> T.Text -> Maybe (GVal m)
-treeAsLookup treefile = \case
- "path" -> Just . toGVal . treeFilePath $ treefile
- "name" -> Just . toGVal . FP.takeFileName . T.unpack . treeFilePath $ treefile
- "href" -> Just . toGVal . treePathToHref $ treefile
- "contents" -> Just . toGVal . treeFileContents $ treefile
- "tree" -> Just . toGVal . treeFileGetTree (treeFilePath treefile) . treeFileContents $ treefile
- "tree_recursive" -> Just . toGVal . treeFileGetTreeRecursive . treeFileContents $ treefile
- "mode" -> Just . toGVal . drop 4 . show . treeFileMode $ treefile
- "mode_octal" -> Just . toGVal . modeToOctal . treeFileMode $ treefile
- "mode_symbolic" -> Just . toGVal . modeToSymbolic . treeFileMode $ treefile
- "is_binary" -> Just . toGVal . treeFileIsBinary $ treefile
- "is_directory" -> Just . toGVal . treeFileIsDirectory $ treefile
+{-
+Recursively descend into a tree, keeping every entry along the way - blobs and trees
+alike - as a single flat list. Equivalent to `git ls-tree -r -t`.
+-}
+flattenTree :: TreeEntry -> [TreeEntry]
+flattenTree treeentry = case treeEntryContents treeentry of
+ FolderContents entries -> treeentry : concatMap flattenTree entries
+ _ -> [treeentry]
+
+treeAsLookup :: TreeEntry -> T.Text -> Maybe (GVal m)
+treeAsLookup treeentry = \case
+ "path" -> Just . toGVal . treeEntryPath $ treeentry
+ "name" -> Just . toGVal . FP.takeFileName . T.unpack . treeEntryPath $ treeentry
+ "href" -> Just . toGVal . treePathToHref $ treeentry
+ "contents" -> Just . toGVal . treeEntryContents $ treeentry
+ "tree" -> Just . toGVal . treeEntryGetTree . treeEntryContents $ treeentry
+ "entries" -> Just . toGVal . concatMap flattenTree . treeEntryGetTree . treeEntryContents $ treeentry
+ "mode" -> Just . toGVal . drop 4 . show . treeEntryMode $ treeentry
+ "mode_octal" -> Just . toGVal . modeToOctal . treeEntryMode $ treeentry
+ "mode_symbolic" -> Just . toGVal . modeToSymbolic . treeEntryMode $ treeentry
+ "is_binary" -> Just . toGVal . treeEntryIsBinary $ treeentry
+ "is_directory" -> Just . toGVal . treeEntryIsDirectory $ treeentry
_ -> Nothing
where
- treeFileGetTree :: T.Text -> TreeFileContents -> [TreeFile]
- treeFileGetTree parent (FolderContents fs) = filter atTop fs
- where
- atTop = notElem FP.pathSeparator . drop 1 . T.unpack . fromMaybe "" . T.stripPrefix parent . treeFilePath
- treeFileGetTree _ _ = []
-
- treeFileGetTreeRecursive :: TreeFileContents -> [TreeFile]
- treeFileGetTreeRecursive (FolderContents fs) = fs
- treeFileGetTreeRecursive _ = []
-
- treeFileIsBinary :: TreeFile -> Bool
- treeFileIsBinary treefile' = case treeFileContents treefile' of
+ -- The entries of this tree object - i.e. this directory's immediate children.
+ treeEntryGetTree :: TreeEntryContents -> [TreeEntry]
+ treeEntryGetTree (FolderContents fs) = fs
+ treeEntryGetTree _ = []
+
+ treeEntryIsBinary :: TreeEntry -> Bool
+ treeEntryIsBinary treeentry' = case treeEntryContents treeentry' of
BinaryContents -> True
_ -> False
- treeFileIsDirectory :: TreeFile -> Bool
- treeFileIsDirectory treefile' = case treeFileContents treefile' of
+ treeEntryIsDirectory :: TreeEntry -> Bool
+ treeEntryIsDirectory treeentry' = case treeEntryContents treeentry' of
FolderContents _ -> True
_ -> False
@@ -330,10 +335,10 @@ treeAsLookup treefile = \case
modeToSymbolic ModeSubmodule = "git-module"
{-
-Get the name of a tree file path's HTML file. Leading periods are dropped.
+Get the name of a tree entry path's HTML file. Leading periods are dropped.
-}
-treePathToHref :: TreeFile -> T.Text
-treePathToHref = T.dropWhile (== '.') . flip T.append ".html" . T.replace "/" "." . treeFilePath
+treePathToHref :: TreeEntry -> T.Text
+treePathToHref = T.dropWhile (== '.') . flip T.append ".html" . T.replace "/" "." . treeEntryPath
{-
Data to store information about references: tags and branches.
diff --git a/templates/base/repo/file.html b/templates/base/repo/file.html
deleted file mode 100644
index 6321c443..00000000
--- a/templates/base/repo/file.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "../template.html.include" %}
-
-{%- block title %}{{ name }} - {{ file }}{% endblock %}
-
-{%- block content %}
-
{{ file.mode_symbolic }} {{ file }}
-
-{% if file.is_directory %}
-
-
-
- | Mode |
- Name |
-
-
-
-
- {% for child in file.tree %}
-
- | {{ child.mode_symbolic }} |
- {{ child.path }} |
-
- {% endfor %}
-
-
-{% else %}
- {% if file.is_binary %}
- (File is binary)
- {% else %}
-{% for line in split(file.contents, '\n') %}
-{{ printf("%5v", loop.index) }} {{ line }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% endblock %}
diff --git a/templates/base/repo/tree.html b/templates/base/repo/files.html
similarity index 63%
rename from templates/base/repo/tree.html
rename to templates/base/repo/files.html
index 7e62bcde..77b30c54 100644
--- a/templates/base/repo/tree.html
+++ b/templates/base/repo/files.html
@@ -15,7 +15,11 @@
{% for file in tree %}
| {{ file.mode_symbolic }} |
- {{ file.path }} |
+ {% if file.is_directory %}
+ {{ file.path }} |
+ {% else %}
+ {{ file.path }} |
+ {% endif %}
{% endfor %}
diff --git a/templates/base/repo/foreach.blob.html b/templates/base/repo/foreach.blob.html
new file mode 100644
index 00000000..05f08723
--- /dev/null
+++ b/templates/base/repo/foreach.blob.html
@@ -0,0 +1,15 @@
+{% extends "../template.html.include" %}
+
+{%- block title %}{{ name }} - {{ blob }}{% endblock %}
+
+{%- block content %}
+{{ blob.mode_symbolic }} {{ blob }}
+
+{% if blob.is_binary %}
+(File is binary)
+{% else %}
+{% for line in split(blob.contents, '\n') %}
+{{ printf("%5v", loop.index) }} {{ line }}
+{% endfor %}
+{% endif %}
+{% endblock %}
diff --git a/templates/base/repo/commit.html b/templates/base/repo/foreach.commit.html
similarity index 100%
rename from templates/base/repo/commit.html
rename to templates/base/repo/foreach.commit.html
diff --git a/templates/base/repo/foreach.tree.html b/templates/base/repo/foreach.tree.html
new file mode 100644
index 00000000..af179c48
--- /dev/null
+++ b/templates/base/repo/foreach.tree.html
@@ -0,0 +1,29 @@
+{% extends "../template.html.include" %}
+
+{%- block title %}{{ name }} - {{ tree }}{% endblock %}
+
+{%- block content %}
+{{ tree.mode_symbolic }} {{ tree }}
+
+
+
+
+ | Mode |
+ Name |
+
+
+
+
+ {% for child in tree.tree %}
+
+ | {{ child.mode_symbolic }} |
+ {% if child.is_directory %}
+ {{ child.path }} |
+ {% else %}
+ {{ child.path }} |
+ {% endif %}
+
+ {% endfor %}
+
+
+{% endblock %}
diff --git a/templates/base/template.html.include b/templates/base/template.html.include
index 8aa1fab6..18407614 100644
--- a/templates/base/template.html.include
+++ b/templates/base/template.html.include
@@ -19,13 +19,13 @@
git clone {{ host }}/{{ name }}
diff --git a/templates/docs/repo/file.html b/templates/docs/repo/file.html
deleted file mode 100644
index 395f251b..00000000
--- a/templates/docs/repo/file.html
+++ /dev/null
@@ -1,47 +0,0 @@
-{% extends "../template.html.include" %}
-
-{%- block title %}{{ file }}{% endblock -%}
-
-{% block body %}
-{{ file.mode_symbolic }} {{ file }}
-
-{% if file.is_directory %}
-
-
-
- | Mode |
- Name |
-
-
-
-
- {% for child in file.tree %}
-
- | {{ child.mode_symbolic }} |
- {{ child.path }} |
-
- {% endfor %}
-
-
-
- {%- if length(file.contents) == 1 -%}
- {%- set child = file.contents[0] -%}
- {% if child.is_binary %}
- (Child is binary)
- {% else %}
-{% for line in split(child.contents, '\n') %}
-{{ printf("%5v", loop.index) }} {{ line }}
-{% endfor %}
- {% endif %}
- {%- endif -%}
-
-{% else %}
- {% if file.is_binary %}
- (File is binary)
- {% else %}
-{% for line in split(file.contents, '\n') %}
-{{ printf("%5v", loop.index) }} {{ line }}
-{% endfor %}
- {% endif %}
-{% endif %}
-{% endblock %}
diff --git a/templates/docs/repo/tree.html b/templates/docs/repo/files.html
similarity index 63%
rename from templates/docs/repo/tree.html
rename to templates/docs/repo/files.html
index 0e468cff..ce2f5e1c 100644
--- a/templates/docs/repo/tree.html
+++ b/templates/docs/repo/files.html
@@ -15,7 +15,11 @@
{% for file in tree %}
| {{ file.mode_symbolic }} |
- {{ file.path }} |
+ {% if file.is_directory %}
+ {{ file.path }} |
+ {% else %}
+ {{ file.path }} |
+ {% endif %}
{% endfor %}
diff --git a/templates/docs/repo/foreach.blob.html b/templates/docs/repo/foreach.blob.html
new file mode 100644
index 00000000..1d551ac9
--- /dev/null
+++ b/templates/docs/repo/foreach.blob.html
@@ -0,0 +1,15 @@
+{% extends "../template.html.include" %}
+
+{%- block title %}{{ blob }}{% endblock -%}
+
+{% block body %}
+{{ blob.mode_symbolic }} {{ blob }}
+
+{% if blob.is_binary %}
+(File is binary)
+{% else %}
+{% for line in split(blob.contents, '\n') %}
+{{ printf("%5v", loop.index) }} {{ line }}
+{% endfor %}
+{% endif %}
+{% endblock %}
diff --git a/templates/docs/repo/commit.html b/templates/docs/repo/foreach.commit.html
similarity index 100%
rename from templates/docs/repo/commit.html
rename to templates/docs/repo/foreach.commit.html
diff --git a/templates/docs/repo/foreach.tree.html b/templates/docs/repo/foreach.tree.html
new file mode 100644
index 00000000..c8e36bdd
--- /dev/null
+++ b/templates/docs/repo/foreach.tree.html
@@ -0,0 +1,29 @@
+{% extends "../template.html.include" %}
+
+{%- block title %}{{ tree }}{% endblock -%}
+
+{% block body %}
+{{ tree.mode_symbolic }} {{ tree }}
+
+
+
+
+ | Mode |
+ Name |
+
+
+
+
+ {% for child in tree.tree %}
+
+ | {{ child.mode_symbolic }} |
+ {% if child.is_directory %}
+ {{ child.path }} |
+ {% else %}
+ {{ child.path }} |
+ {% endif %}
+
+ {% endfor %}
+
+
+{% endblock %}
diff --git a/templates/docs/template.html.include b/templates/docs/template.html.include
index 43e3af49..9ac9dfe0 100644
--- a/templates/docs/template.html.include
+++ b/templates/docs/template.html.include
@@ -23,10 +23,10 @@
Home |
Log |
- Files |
+ Files |
Refs |
- Readme |
- License
+ Readme |
+ License
diff --git a/templates/stagit/repo/file.html b/templates/stagit/repo/file.html
deleted file mode 100644
index 70301d6f..00000000
--- a/templates/stagit/repo/file.html
+++ /dev/null
@@ -1,41 +0,0 @@
-{% extends "../template.html.include" %}
-
-{%- block title -%}
-{{ name }} - {{ file }}
-{%- endblock -%}
-
-{% block body %}
-{% include "repo-table-header.html.include" %}
-
-
-
{{ file.mode_symbolic }} {{ file }}
-
-{% if file.is_directory %}
-
-
-
- | Mode |
- Name |
-
-
-
-
- {% for child in file.contents %}
-
- | {{ child.mode_symbolic }} |
- {{ child.path }} |
-
- {% endfor %}
-
-
-{% else %}
- {% if file.is_binary %}
- (File is binary)
- {% else %}
-
{% for line in split(file.contents, '\n') %}
-{{ printf("%7v", loop.index) }} {{ line }}
-{% endfor %}
- {% endif %}
-{% endif %}
-
-{% endblock %}
diff --git a/templates/stagit/repo/tree.html b/templates/stagit/repo/files.html
similarity index 66%
rename from templates/stagit/repo/tree.html
rename to templates/stagit/repo/files.html
index 7d5d1ab9..176bb51c 100644
--- a/templates/stagit/repo/tree.html
+++ b/templates/stagit/repo/files.html
@@ -1,7 +1,7 @@
{% extends "../template.html.include" %}
{%- block title -%}
-{{ name }} - target
+{{ name }} - files
{%- endblock -%}
{% block body %}
@@ -20,7 +20,11 @@
{% for file in tree %}
| {{ file.mode_symbolic }} |
- {{ file.path }} |
+ {% if file.is_directory %}
+ {{ file.path }} |
+ {% else %}
+ {{ file.path }} |
+ {% endif %}
{% endfor %}
diff --git a/templates/stagit/repo/foreach.blob.html b/templates/stagit/repo/foreach.blob.html
new file mode 100644
index 00000000..7b540790
--- /dev/null
+++ b/templates/stagit/repo/foreach.blob.html
@@ -0,0 +1,21 @@
+{% extends "../template.html.include" %}
+
+{%- block title -%}
+{{ name }} - {{ blob }}
+{%- endblock -%}
+
+{% block body %}
+{% include "repo-table-header.html.include" %}
+
+
+
{{ blob.mode_symbolic }} {{ blob }}
+
+ {% if blob.is_binary %}
+ (File is binary)
+ {% else %}
+
{% for line in split(blob.contents, '\n') %}
+{{ printf("%7v", loop.index) }} {{ line }}
+{% endfor %}
+ {% endif %}
+
+{% endblock %}
diff --git a/templates/stagit/repo/commit.html b/templates/stagit/repo/foreach.commit.html
similarity index 100%
rename from templates/stagit/repo/commit.html
rename to templates/stagit/repo/foreach.commit.html
diff --git a/templates/stagit/repo/foreach.tree.html b/templates/stagit/repo/foreach.tree.html
new file mode 100644
index 00000000..85d94748
--- /dev/null
+++ b/templates/stagit/repo/foreach.tree.html
@@ -0,0 +1,35 @@
+{% extends "../template.html.include" %}
+
+{%- block title -%}
+{{ name }} - {{ tree }}
+{%- endblock -%}
+
+{% block body %}
+{% include "repo-table-header.html.include" %}
+
+
+
{{ tree.mode_symbolic }} {{ tree }}
+
+
+
+
+ | Mode |
+ Name |
+
+
+
+
+ {% for child in tree.tree %}
+
+ | {{ child.mode_symbolic }} |
+ {% if child.is_directory %}
+ {{ child.path }} |
+ {% else %}
+ {{ child.path }} |
+ {% endif %}
+
+ {% endfor %}
+
+
+
+{% endblock %}
diff --git a/templates/stagit/repo/repo-table-header.html.include b/templates/stagit/repo/repo-table-header.html.include
index e713331c..e3069501 100644
--- a/templates/stagit/repo/repo-table-header.html.include
+++ b/templates/stagit/repo/repo-table-header.html.include
@@ -16,9 +16,9 @@
| {{ description }} |
| git clone {{ host }}/{{ name }} |
|
- Files | Refs
- {% if readme %} | Readme{% endif %}
- {% if license %} | License{% endif %}
+ Files | Refs
+ {% if readme %} | Readme{% endif %}
+ {% if license %} | License{% endif %}
|
diff --git a/test/expected/gitja/blob/github.FUNDING.yml.html b/test/expected/gitja/blob/github.FUNDING.yml.html
new file mode 100644
index 00000000..98ecfdae
--- /dev/null
+++ b/test/expected/gitja/blob/github.FUNDING.yml.html
@@ -0,0 +1,22 @@
+.github/FUNDING.yml
+scope: blob
+blob: .github/FUNDING.yml
+blob.path: .github/FUNDING.yml
+blob.href: github.FUNDING.yml.html
+blob.contents: github: ["m-col"]
+custom: ["https://liberapay.com/mcol"]
+blob.mode: Plain
+blob.mode_octal: 00644
+blob.mode_symbolic: -rw-r--r--
+if blob.is_directory then "directory" else "file": "file"
+
+blob scope also should have data from repo scope available:
+host: https://github.com/m-col/gitja
+repos: gitja
+name: gitja
+description: 🐙 Templated web page generator for your git repositories
+commits: (skipped)
+tree: (skipped)
+tags: 1
+readme.path: README.rst
+license.path: LICENSE
diff --git a/test/expected/gitja/blob/test.templates.so_called_binary_file.html b/test/expected/gitja/blob/test.templates.so_called_binary_file.html
new file mode 100644
index 00000000..ed9d43c2
--- /dev/null
+++ b/test/expected/gitja/blob/test.templates.so_called_binary_file.html
@@ -0,0 +1,21 @@
+test/templates/so_called_binary_file
+scope: blob
+blob: test/templates/so_called_binary_file
+blob.path: test/templates/so_called_binary_file
+blob.href: test.templates.so_called_binary_file.html
+blob.contents: (binary)
+blob.mode: Plain
+blob.mode_octal: 00644
+blob.mode_symbolic: -rw-r--r--
+if blob.is_directory then "directory" else "file": "file"
+
+blob scope also should have data from repo scope available:
+host: https://github.com/m-col/gitja
+repos: gitja
+name: gitja
+description: 🐙 Templated web page generator for your git repositories
+commits: (skipped)
+tree: (skipped)
+tags: 1
+readme.path: README.rst
+license.path: LICENSE
diff --git a/test/expected/gitja/blob/test.templates.style.css.html b/test/expected/gitja/blob/test.templates.style.css.html
new file mode 100644
index 00000000..93d8a281
--- /dev/null
+++ b/test/expected/gitja/blob/test.templates.style.css.html
@@ -0,0 +1,21 @@
+test/templates/style.css
+scope: blob
+blob: test/templates/style.css
+blob.path: test/templates/style.css
+blob.href: test.templates.style.css.html
+blob.contents: html
+blob.mode: Plain
+blob.mode_octal: 00644
+blob.mode_symbolic: -rw-r--r--
+if blob.is_directory then "directory" else "file": "file"
+
+blob scope also should have data from repo scope available:
+host: https://github.com/m-col/gitja
+repos: gitja
+name: gitja
+description: 🐙 Templated web page generator for your git repositories
+commits: (skipped)
+tree: (skipped)
+tags: 1
+readme.path: README.rst
+license.path: LICENSE
diff --git a/test/expected/gitja/file/github.FUNDING.yml.html b/test/expected/gitja/file/github.FUNDING.yml.html
deleted file mode 100644
index 95a8659b..00000000
--- a/test/expected/gitja/file/github.FUNDING.yml.html
+++ /dev/null
@@ -1,22 +0,0 @@
-.github/FUNDING.yml
-scope: file
-file: .github/FUNDING.yml
-file.path: .github/FUNDING.yml
-file.href: github.FUNDING.yml.html
-file.contents: github: ["m-col"]
-custom: ["https://liberapay.com/mcol"]
-file.mode: Plain
-file.mode_octal: 00644
-file.mode_symbolic: -rw-r--r--
-if file.is_directory then "directory" else "file": "file"
-
-file scope also should have data from repo scope available:
-host: https://github.com/m-col/gitja
-repos: gitja
-name: gitja
-description: 🐙 Templated web page generator for your git repositories
-commits: (skipped)
-tree: (skipped)
-tags: 1
-readme.path: README.rst
-license.path: LICENSE
diff --git a/test/expected/gitja/file/test.templates.so_called_binary_file.html b/test/expected/gitja/file/test.templates.so_called_binary_file.html
deleted file mode 100644
index 2e815d3c..00000000
--- a/test/expected/gitja/file/test.templates.so_called_binary_file.html
+++ /dev/null
@@ -1,21 +0,0 @@
-test/templates/so_called_binary_file
-scope: file
-file: test/templates/so_called_binary_file
-file.path: test/templates/so_called_binary_file
-file.href: test.templates.so_called_binary_file.html
-file.contents: (binary)
-file.mode: Plain
-file.mode_octal: 00644
-file.mode_symbolic: -rw-r--r--
-if file.is_directory then "directory" else "file": "file"
-
-file scope also should have data from repo scope available:
-host: https://github.com/m-col/gitja
-repos: gitja
-name: gitja
-description: 🐙 Templated web page generator for your git repositories
-commits: (skipped)
-tree: (skipped)
-tags: 1
-readme.path: README.rst
-license.path: LICENSE
diff --git a/test/expected/gitja/file/test.templates.style.css.html b/test/expected/gitja/file/test.templates.style.css.html
deleted file mode 100644
index 315187f4..00000000
--- a/test/expected/gitja/file/test.templates.style.css.html
+++ /dev/null
@@ -1,21 +0,0 @@
-test/templates/style.css
-scope: file
-file: test/templates/style.css
-file.path: test/templates/style.css
-file.href: test.templates.style.css.html
-file.contents: html
-file.mode: Plain
-file.mode_octal: 00644
-file.mode_symbolic: -rw-r--r--
-if file.is_directory then "directory" else "file": "file"
-
-file scope also should have data from repo scope available:
-host: https://github.com/m-col/gitja
-repos: gitja
-name: gitja
-description: 🐙 Templated web page generator for your git repositories
-commits: (skipped)
-tree: (skipped)
-tags: 1
-readme.path: README.rst
-license.path: LICENSE
diff --git a/test/templates/repo/file.html b/test/templates/repo/file.html
deleted file mode 100644
index e5b0ede1..00000000
--- a/test/templates/repo/file.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "../title.html.include" -%}
-{%- block title -%}{{ file }}{%- endblock -%}
-
-{% block body %}
-scope: file
-file: {{ file }}
-file.path: {{ file.path }}
-file.href: {{ file.href }}
-file.contents: {% if file.is_binary %}(binary)
-{% else %}{{ file.contents }}{% endif %}
-file.mode: {{ file.mode }}
-file.mode_octal: {{ file.mode_octal }}
-file.mode_symbolic: {{ file.mode_symbolic }}
-if file.is_directory then "directory" else "file":
- {%- if file.is_directory %} "directory"{% else %} "file"{% endif %}
-
-
-file scope also should have data from repo scope available:
-host: {{ host }}
-repos: {{ repositories }}
-name: {{ name }}
-description: {{ description }}
-commits: (skipped)
-tree: (skipped)
-tags: {{ length(filter(tags, (t) -> t.name == "0.2.0")) }}
-readme.path: {{ readme.path }}
-license.path: {{ license.path }}
-{% endblock %}
diff --git a/test/templates/repo/foreach.blob.html b/test/templates/repo/foreach.blob.html
new file mode 100644
index 00000000..9ca72d5b
--- /dev/null
+++ b/test/templates/repo/foreach.blob.html
@@ -0,0 +1,28 @@
+{% extends "../title.html.include" -%}
+{%- block title -%}{{ blob }}{%- endblock -%}
+
+{% block body %}
+scope: blob
+blob: {{ blob }}
+blob.path: {{ blob.path }}
+blob.href: {{ blob.href }}
+blob.contents: {% if blob.is_binary %}(binary)
+{% else %}{{ blob.contents }}{% endif %}
+blob.mode: {{ blob.mode }}
+blob.mode_octal: {{ blob.mode_octal }}
+blob.mode_symbolic: {{ blob.mode_symbolic }}
+if blob.is_directory then "directory" else "file":
+ {%- if blob.is_directory %} "directory"{% else %} "file"{% endif %}
+
+
+blob scope also should have data from repo scope available:
+host: {{ host }}
+repos: {{ repositories }}
+name: {{ name }}
+description: {{ description }}
+commits: (skipped)
+tree: (skipped)
+tags: {{ length(filter(tags, (t) -> t.name == "0.2.0")) }}
+readme.path: {{ readme.path }}
+license.path: {{ license.path }}
+{% endblock %}
diff --git a/test/templates/repo/commit.html b/test/templates/repo/foreach.commit.html
similarity index 100%
rename from test/templates/repo/commit.html
rename to test/templates/repo/foreach.commit.html
diff --git a/test/test.sh b/test/test.sh
index b34756ca..35fd9c32 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -36,10 +36,10 @@ TESTS=(
"static/a_nice_file" # Static folder at top level
"gitja/index.html" # Repo scope
"gitja/commit/0292014748caae952bbc8dd6225680d83c0a5135.html" # A commit
- "gitja/file/test.templates.style.css.html" # A plain text file
+ "gitja/blob/test.templates.style.css.html" # A plain text file
"so_called_binary_file" # Static file at top level that git considers binary
- "gitja/file/test.templates.so_called_binary_file.html" # The binary file
- "gitja/file/github.FUNDING.yml.html" # HREF drops leading period
+ "gitja/blob/test.templates.so_called_binary_file.html" # The binary file
+ "gitja/blob/github.FUNDING.yml.html" # HREF drops leading period
"gitja/log.html" # Symbolic link inside repo/
"gitja/static/another_file" # Static folder inside repo/
)