Dispatches filters listed in an entry's filters.prop to scripts under
$wrt->{filter_dir}.
This is inefficient, in that it starts an entire process (at least) per
filtered entry. On the other hand, it's a pretty clean abstraction, and
it means that filters could be implemented in whatever language.
Adds filters/ creation to wrt init.
You can add a filters.prop in an entry, containing a list of filters to
apply which will be pulled out of the guts of wrt. I'm not sure if this
is a good idea or not, to be honest. It's elegant enough, but it feels
a bit obscure.
I'm also not sure if it should accommodate the user writing custom filters
that can sit in the wrt repo, but it kind of feels like that would be
more in the spirit of things...
- adds an example "flat" site with, for now, a single index in root for
testing purposes
- wrt-render-all handles default entry instead of just using "new"
- EntryStore::all_renderable() correctly filters out paths ending in
"/index" instead of "index", which if nothing else corrects a subtle
bug that would have gotten in the way of naming something "windex"
- WRT::handle() will return the contents of a root-level "index"
Uses JSON::Feed, for the moment, although it might be worth just rolling
my own to avoid the dependency.
Adds:
- feed_print_json_recent()
- feed_print_json()
Also puts a decode() call around feed_print() output and adds open()
pragmas to a couple of utilities.
This could still use some tweaking, probably, but it removes a special
case that's bugged me for years and lets the feed code be used for more
general problems.
Adds a module for wrapping up the sorting in order to use it for more than
just dates. Specifically, adds sorting to the entries-by-property list.
Generalizes sorting to something that kinda works for entries paths which
contain more than dates.
This entails a bunch of stuff, and I'm not sure how good an idea a lot of
it is.
- Adds a new tagging format for properties:
tag.foo.bar.prop
Where `foo` and `bar` are treated as elements of a path. Thus if
`archives/2019/10/5/tag.topics.technical.prop` exists, then
the entry at `/topics/technical` will link back to `/2019/10/5`.
- Adds "virtual" entries - if tags link to entries that don't exist,
they're implicitly created.
- Adds a concept of metadata distinct from (but about) entry text, and
caches this for every entry.
- Adds caching of child entries to EntryStore.
- Migrates `get_sub_entries()` and `subentry_expr` into EntryStore.
There are XXX comments littered all over the place at this point. Stuff
will definitely change before a release.
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".
- move get_date() from App::WRT::Util to App::WRT::Date
- make App::WRT::FileIO and ::Util less redundant
- add App::WRT::Mock::FileIO for faking writes in tests
- make bin/wrt-render-all testable, add t/bin-wrt-render-all.t
Including:
- children() - get immediate children of entry
- parent($entry) - get immediate parent of entry
- days_for($container) - get days in a month or year
- months_for($year) - get months contained in a year
- basename($entry) - get basename of an entry
These are used in App::WRT::year() and App::WRT::month(), replacing
some dir_list() invocations and at least somewhat simplifying the code.
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
Adds a couple of hashes in the App::WRT::EntryStore::new() constructor
which stash arrays of properties for each entry, and arrays of entries
for each property, as File::Find works its way through the $entry_dir.
Uses props_for() in App::WRT::entry_topic_list() instead of dir_list().
This is maybe a tiny performance gain, but also probably more hassle
than it's worth unless other features are going to be built on these
methods (or other code that calls dir_list() simplified).
This also moves a chunk of logic out of EntryStore::all() and into the
constructor, and directly accesses $self->{source_files} in a couple of
methods instead of tossing around copies of the array.
I'm kind of iffy on whether any of this is worth doing.
I never could quite figure out why non-ASCII characters were getting
badly munged in XML::Atom::SimpleFeed output. Using Encode::decode() on
the content of entries turns out to fix this, although it's probably the
tip of an iceberg.
- get_all_source_files() -> EntryStore::all()
- get_date_entries_by_depth() -> EntryStore::dates_by_depth()
- get_recent_entries_by_depth() -> EntryStore::recent_by_depth()
...plus some convenience methods for accessing recent or all years /
months / days, and a next($entry) / previous($entry) for indexing into the
date lists.
An instance of App::WRT::EntryStore is stashed on an App::WRT instance.
- give absolute paths to imgsize() so it chills out on Cwd::getcwd() calls
- rip out App::WRT::MethodSpit's convenience accessors and just access
elements of $self directly
- kill local_path()
- stop using a() in entry_markup()
- cache get_date_entries_by_depth() results
- swap out state vars for stashing things on $self in
get_all_source_files()
This gets rendering the whole p1k3 repo back down in the neighborhood of
2.1 seconds, which is a lot more tolerable than 5 or 6.
It also kinda technically breaks the API, maybe, so I guess this'll be a
v5.0.0 after a while.
Replaces get_all_day_entries() with get_date_entries_by_depth(). Adds
generate_month_lists() to stash %prev_months and %next_months (this can
probably be generalized a bunch).
Generalizes sortable_date_from_entry() to work with different levels of
date. Assumes that no component of the date is more than 4 digits, which
is not very future proof. (Though if this code is still running in the
year 10000, the future will have gone very differently than I expect it
to.)
month_before() now uses the %prev_months and %next_months hashes.
Removes fulltext(), because you can just call get_date_entries_by_depth(3).
Much slower than it probably needs to be.
Shuffles a bit of stuff out of App::WRT::Renderer into App::WRT, including
the method now called get_all_source_files() and a new one called
get_all_day_entries() that returns a sorted listed of days.
Uses state variables to cache the get_all_source_files() data, as well
as month_before() data (this was previously memoized inside a closure).
App::WRT::feed_print() now takes a list of entries instead of a month to
render the feed for.
App::WRT::feed_print_latest() gets a feed with most recent feed_length
entries.
I went and read:
https://pause.perl.org/pause/authenquery?ACTION=pause_namingmodules
Realized I should probably not name this something with an inscrutable
top-level namespace. WRT is still inscrutable, I guess, but at least
it's now under App.
- Renames all modules, fixes tests (such as they are)
- Zaps old t/validate/ stuff
- adds include_process() in WRT::Markup
- moves eval_perl() into WRT::Markup. The way object instances are
composed (and instance methods called) here still feels pretty janky,
and this does nothing to help the situation.
- changes all existing $root_dir instances to $entry_dir; adds a $root_dir
which represents the root of the archive (top-level folder containing
the wrt.json file)
I'd be worried about the $root_dir change if I thought this module had a
single other user in the wild, but I strongly doubt that it does. If I
am wrong and you are that user, I apologize sincerely in advance.
The include feature still has fairly unsettled semantics, but it gets the
whole thing much closer to a usable site generator.