[OCaml] Mobile-friendly clone of cgit.
feat display inline README at bottom of directory listings
When a directory contains a README.* file, its content is now rendered at the bottom of the file listing in a dedicated section with a header and the standard line-numbered blob display. The handler finds the README entry (case-insensitive prefix match), fetches its blob content, and passes it to the files view as an optional parameter. Styled with a bordered container and subdued header.
Changed files
lib/handlers.ml
@@ -139,10 +139,20 @@
139
139
let* diff = Resolvers.Diff.of_commit repository commit in
140
140
Views.Repo.commit context commit diff
141
141
142
Added:
let find_readme repository (tree : Resolvers.Tree.t) =
143
Added:
match List.find_opt Resolvers.Entry.is_readme tree.entries with
144
Added:
| None -> Lwt_result.return None
145
Added:
| Some entry ->
146
Added:
Lwt.bind (Resolvers.blob_or_tree repository entry.hash) (function
147
Added:
| Ok (`Blob blob) -> Lwt.return (Ok (Some blob))
148
Added:
| Ok _ -> Lwt.return (Ok None)
149
Added:
| Error e -> Lwt.return (Error e))
150
Added:
142
151
let files_at_head repository context =
143
152
let* tree = Resolvers.Tree.head repository in
144
153
let* preloaded = Resolvers.Tree.preload repository tree in
145
Removed:
Views.Repo.files context [] preloaded
154
Added:
let* readme = find_readme repository tree in
155
Added:
Views.Repo.files context [] ?readme preloaded
146
156
147
157
let file_id repository context id =
148
158
let* trail = Resolvers.Tree.find_path repository id in
@@ -150,7 +160,8 @@
150
160
match object_ with
151
161
| `Tree tree ->
152
162
let* preloaded = Resolvers.Tree.preload repository tree in
153
Removed:
Views.Repo.files context trail preloaded
163
Added:
let* readme = find_readme repository tree in
164
Added:
Views.Repo.files context trail ?readme preloaded
154
165
| `Blob blob -> Views.Repo.file context trail blob
155
166
156
167
let branches repository context =
lib/static/styles.css
@@ -657,6 +657,28 @@
657
657
text-decoration: underline;
658
658
}
659
659
660
Added:
/* Inline README display at bottom of directory listings */
661
Added:
662
Added:
.readme-inline {
663
Added:
margin-top: 1.5em;
664
Added:
border: 1px solid #3a3a3a;
665
Added:
border-radius: 0.25rem;
666
Added:
overflow-x: auto;
667
Added:
}
668
Added:
669
Added:
.readme-inline h3 {
670
Added:
margin: 0;
671
Added:
padding: 0.6em 1em;
672
Added:
background-color: #242424;
673
Added:
font-size: 0.9em;
674
Added:
color: #b0b0b0;
675
Added:
border-bottom: 1px solid #3a3a3a;
676
Added:
}
677
Added:
678
Added:
.readme-inline #blob {
679
Added:
padding: 0.5em 0;
680
Added:
}
681
Added:
660
682
.diff-file {
661
683
margin: 1.5em 0;
662
684
border: 1px solid #3a3a3a;
lib/views/repo.ml
@@ -340,11 +340,44 @@
340
340
in
341
341
HTML.(span [ class_ "path-pill" ] (root_anchor :: segments))
342
342
343
Removed:
let files context trail (entries : Resolvers.Tree.preloaded_entry list) =
343
Added:
let files context trail ?readme (entries : Resolvers.Tree.preloaded_entry list)
344
Added:
=
344
345
let pill = breadcrumb_pill context.repo trail in
345
346
let tb = toolbar [ pill ] in
347
Added:
let readme_section =
348
Added:
match readme with
349
Added:
| None -> HTML.null []
350
Added:
| Some (blob : Resolvers.Blob.t) ->
351
Added:
let formatted =
352
Added:
String.split_on_char '\n' blob.content
353
Added:
|> List.mapi (fun number line ->
354
Added:
let line_number = number + 1 in
355
Added:
HTML.
356
Added:
[
357
Added:
a
358
Added:
[
359
Added:
id "readme-%d" line_number;
360
Added:
class_ "line-anchor";
361
Added:
href "#readme-%d" line_number;
362
Added:
Aria.label "Line %d" line_number;
363
Added:
]
364
Added:
[ txt "%d" line_number ];
365
Added:
span [ class_ "line" ] [ txt "\t%s\n" line ];
366
Added:
])
367
Added:
|> List.concat
368
Added:
in
369
Added:
HTML.(
370
Added:
section
371
Added:
[ class_ "readme-inline" ]
372
Added:
[ h3 [] [ txt "README" ]; div [ id "blob" ] formatted ])
373
Added:
in
346
374
render_page context ~active:Files
347
Removed:
HTML.[ tb; ul [] (List.map (li_of_preloaded context.repo) entries) ]
375
Added:
HTML.
376
Added:
[
377
Added:
tb;
378
Added:
ul [] (List.map (li_of_preloaded context.repo) entries);
379
Added:
readme_section;
380
Added:
]
348
381
349
382
let file ?(active = Layout.Files) context trail (blob : Resolvers.Blob.t) =
350
383
let to_numbered_line number line =