Almost-minimal filesystem based blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.0 KiB

v6.0.0: expand EntryStore, test more, cache harder This commit is something of a hairball, the result of evenings-and-weekends hacking building up a set of changes that got out of hand in parallel. If I had the energy to spare, I would break it apart into semantically-related changes, but I don't - and I suppose all this crap being rolled together is at least reflective of how the code was written. These changes are really half-finished, at best. Eventual goals: - App::WRT shouldn't directly touch the filesystem - App::WRT::EntryStore should model the entry archive completely - App::WRT::Renderer should say what to write to the publication directory - This one's a maybe: Filesystem interaction should pass through App::WRT::FileIO or something like it so that EntryStore and Renderer can be more usefully tested, with mocked writes (maybe) I do think this represents an inflection point in the long, silly life of this program: It includes a handful of new tests, and a number of the code changes were in turn easy to make because the test suite begins to model the code in a useful way. It's less and less necessary to run wrt against the p1k3.com archives to be sure that I haven't trashed something. Breaking changes to note: - Will no longer render HTML for nonexistent entries - Months and years which are flatfiles or contain an index are handled differently, albeit less brokenly - EntryStore includes index files in its overall list of entries (this seems to break less than I thought), which trickles out to bin/wrt-ls Overall changes herein: - App::WRT::Date - Move month_name() in here from App::WRT, add tests. - App::WRT::EntryStore - Hash file types for entries (directory or flatfile) - Use keys of file type hash for complete list of entries. - has_prop($entry, $property) - is_dir($entry), is_file($entry), is_extant($entry) - parent_of($entry) - has_index($entry) - Make EntryStore cache whether a file is a flatfile or a directory, as well as its existence, in a single hash. - Include index flatfiles in @source_files for use by has_index() - Various tests. - App::WRT::FileIO - Still duplicates a bunch of shit from Util, so that needs sorted. - App::WRT::Renderer - Convert to a proper class. - Add experimental FileIO class to use in Renderer (imperfect, tricky, still thinking about this). The idea is to separate out the concerns of reading and writing the filesystem. - App::WRT - Refactor display() and improve tests - Use "@entries" instead of "@options" for clarity - Handle entry names that might evaluate as false - Test running display() without any params - Rename expand_option() -> expand_alias(), refactor - Use EntryStore::has_prop() to detect wrt-noexpand.prop - year(), month(), entry() partially rewritten to use EntryStore - year() should handle months which are a flatfile - Refactor icon_markup() to use is_file() / is_dir() / is_extant(), add tests. - Add subtitle to feeds - bin/wrt-ls is now a "modulino" with tests - bin/display errors on non-existent entries - Build.PL - Remove bogus XML::Feed dependency
5 years ago
cache rendered html; extract titles; all as utf-8 This stashes the HTML version of every entry in memory and uses Mojo::DOM to extract headers from the markup for use as titles. Titles are displayed in $self->{page_navigation}, now available inside templates as ${page_navigation}. In order to keep Mojo::DOM from choking on other input, it uses the open pragma to open everything as UTF-8 by default, which also eliminates a whole class of character encoding bugs and removes some fiddling with Encode::decode() from feed_print(). This is all obviously a more memory-intensive, but caching the markup turns out to have the side effect of making it much faster to render even a large site, probably as much as anything because the HTML in question is only getting generated once per entry instead of (potentially) 2-3 times. This commit isn't very atomic. In the process of roughing it out and testing it, I made a small pile of minor but potentially breaking changes: - Removed entry_map from settings and hardcoded handling of various types of entry as some if-statements instead. - Removed embedded_perl flag in settings - was always turned on in practice, and wasn't very coherent since templating would have broken without it. - bin/wrt-display - now handles the "feed" alias correctly - EntryStore: now supports retrieving values for properties with prop_value() - this isn't currently used, but it seems like a reasonable extension of the property idea. - Added `wrt ls --with-titles`. - Added dependency versions to Build.PL. - Refactored Markup's line_parse() a little. - Refactored some tests to give cleaner / more useful output. - Renamed default template file to "default".
5 years ago
v6.0.0: expand EntryStore, test more, cache harder This commit is something of a hairball, the result of evenings-and-weekends hacking building up a set of changes that got out of hand in parallel. If I had the energy to spare, I would break it apart into semantically-related changes, but I don't - and I suppose all this crap being rolled together is at least reflective of how the code was written. These changes are really half-finished, at best. Eventual goals: - App::WRT shouldn't directly touch the filesystem - App::WRT::EntryStore should model the entry archive completely - App::WRT::Renderer should say what to write to the publication directory - This one's a maybe: Filesystem interaction should pass through App::WRT::FileIO or something like it so that EntryStore and Renderer can be more usefully tested, with mocked writes (maybe) I do think this represents an inflection point in the long, silly life of this program: It includes a handful of new tests, and a number of the code changes were in turn easy to make because the test suite begins to model the code in a useful way. It's less and less necessary to run wrt against the p1k3.com archives to be sure that I haven't trashed something. Breaking changes to note: - Will no longer render HTML for nonexistent entries - Months and years which are flatfiles or contain an index are handled differently, albeit less brokenly - EntryStore includes index files in its overall list of entries (this seems to break less than I thought), which trickles out to bin/wrt-ls Overall changes herein: - App::WRT::Date - Move month_name() in here from App::WRT, add tests. - App::WRT::EntryStore - Hash file types for entries (directory or flatfile) - Use keys of file type hash for complete list of entries. - has_prop($entry, $property) - is_dir($entry), is_file($entry), is_extant($entry) - parent_of($entry) - has_index($entry) - Make EntryStore cache whether a file is a flatfile or a directory, as well as its existence, in a single hash. - Include index flatfiles in @source_files for use by has_index() - Various tests. - App::WRT::FileIO - Still duplicates a bunch of shit from Util, so that needs sorted. - App::WRT::Renderer - Convert to a proper class. - Add experimental FileIO class to use in Renderer (imperfect, tricky, still thinking about this). The idea is to separate out the concerns of reading and writing the filesystem. - App::WRT - Refactor display() and improve tests - Use "@entries" instead of "@options" for clarity - Handle entry names that might evaluate as false - Test running display() without any params - Rename expand_option() -> expand_alias(), refactor - Use EntryStore::has_prop() to detect wrt-noexpand.prop - year(), month(), entry() partially rewritten to use EntryStore - year() should handle months which are a flatfile - Refactor icon_markup() to use is_file() / is_dir() / is_extant(), add tests. - Add subtitle to feeds - bin/wrt-ls is now a "modulino" with tests - bin/display errors on non-existent entries - Build.PL - Remove bogus XML::Feed dependency
5 years ago
  1. #!/usr/bin/env perl
  2. =pod
  3. =head1 NAME
  4. wrt-display - print static HTML from wrt entries
  5. =head1 USAGE
  6. wrt display new # newest entries
  7. wrt display all # table of contents for all dated entries
  8. wrt display 2016/4/1 # a specific date
  9. wrt display 2016/4 # all entries for a specific month
  10. wrt display 2016/4 # summary of entries for a year
  11. wrt display fulltext # complete text of archive
  12. wrt display feed # Atom feed of most recent month's entries
  13. # Take list of entries to display from standard input:
  14. echo 2016/4/1 | wrt display --stdin
  15. # Specify a different config file:
  16. wrt display --config ./wrt.json ...
  17. # Display help:
  18. wrt display --help
  19. =head1 DESCRIPTION
  20. C<wrt-display> displays HTML for the given entry or entries in the current wrt
  21. repository to F<stdout>. Entries may be specified by date or name.
  22. =head2 Special Entries
  23. B<new> will return entries for the most recent month.
  24. B<feed> will return an Atom feed for the most recent month.
  25. B<all> will return a table-of-contents for all date-based entries.
  26. B<fulltext> will return the full content of all date-based entries in the
  27. archive.
  28. Months in the form of B<yyyy/mm> will return all entries for that month.
  29. Years in the form of B<yyyy> will return a summary of entries for the year.
  30. Detailed documentation can be found in the L<App::WRT> man page or at
  31. L<https://code.p1k3.com/gitea/brennen/wrt>.
  32. =head1 LICENSE
  33. wrt is free software; you can redistribute it and/or modify
  34. it under the terms of the GNU General Public License as published by
  35. the Free Software Foundation; either version 2 of the License, or
  36. (at your option) any later version.
  37. =head1 AUTHOR
  38. Brennen Bearnes <code@p1k3.com>
  39. =cut
  40. use 5.10.0;
  41. use strict;
  42. use warnings;
  43. no warnings 'uninitialized';
  44. # use Data::Dumper;
  45. use App::WRT;
  46. use Carp;
  47. use Getopt::Long;
  48. use Pod::Usage;
  49. # Handle options, including help generated from the POD above. See:
  50. # - http://perldoc.perl.org/Getopt/Long.html#User-defined-subroutines-to-handle-options
  51. # - https://metacpan.org/pod/Pod::Usage
  52. # - http://michael.thegrebs.com/2014/06/08/Pod-Usage/
  53. my $from_stdin = 0;
  54. my $config_file = 'wrt.json';
  55. GetOptions(
  56. stdin => \$from_stdin,
  57. 'config=s' => \$config_file,
  58. help => sub { pod2usage(0) },
  59. ) or pod2usage(2);
  60. unless (-e $config_file) {
  61. croak "No wrt config file found. Tried: $config_file";
  62. }
  63. my $w = App::WRT::new_from_file($config_file);
  64. # With --stdin, take names of entries to display from standard input, one line
  65. # per name. Otherwise, take names from arguments.
  66. my @to_display = ();
  67. if ($from_stdin) {
  68. while (my $entry = <>) {
  69. chomp($entry);
  70. push @to_display, $entry;
  71. }
  72. } else {
  73. (@to_display) = @ARGV;
  74. }
  75. # TODO: Better error reporting strategy, print this on stderr:
  76. foreach my $entry (map { $w->expand_alias($_) } @to_display) {
  77. unless ($w->{entries}->is_extant($entry) || $entry eq $w->{feed_alias}) {
  78. say("No such entry: $entry");
  79. exit(1);
  80. }
  81. }
  82. print $w->display(@to_display);
  83. exit(0);