Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statocles app gets generic #586

Open
wants to merge 2 commits into
base: v2
Choose a base branch
from

Conversation

wbazant
Copy link
Contributor

@wbazant wbazant commented Sep 9, 2019

No description provided.

Also: the blog / list apps do not have a base_url, only the whole application

Produce working URLs whether the blog app route ends with `/` or not, through joining on `/` and doing `=~s{//}{/}r`

Discussion in preaction#585
@coveralls
Copy link

Coverage Status

Coverage remained the same at 86.182% when pulling 35e4271 on wbazant:v2_tags_in_default_templates into 24f6c25 on preaction:v2.

Configurable in statocles.conf:
- arguments to a yancy#list call: filter, order_by, limit, etc.
- categories (and whether to make tags)
- route

Show two typical uses - a "blog" and a "list" in the default config

The app produces a list of posts, and corresponds to a "list" template
There's also a "page" template for a single page

XXX t/theme.t starts failing
@wbazant wbazant changed the title An idea for the tags in templates Statocles app gets generic Sep 13, 2019
@wbazant
Copy link
Contributor Author

wbazant commented Sep 13, 2019

@preaction we were talking about this problem where a piece of content doesn't know which app it was linked from.

I think the solution is to decide that an "app" is a list of posts built on a Yancy query, and tied to a route. It becomes quite configurable - choices like draft => 1/0 vs. status => "published"/"draft" are easy-to-change, sane defaults. One can configure a route for posts only by a certain author, with a certain flag, etc.

This PR breaks something with the themes: I can choose default or bootstrap, but t/theme.t fails, and

@@ -155,8 +171,8 @@ sub startup {
     $app->plugin( Export => );
     push @{$app->export->pages}, '/sitemap.xml', '/robots.txt';
     $app->plugin( AutoReload => );
-
-    if ( my $theme = $app->config->{theme} ) {
+    do {
+        my $theme = $app->config->{theme} //= '+Statocles/theme/default';

seems necessary to fix the other tests. I can spend more time on finding out what it is, if you approve of the general direction.

It's potentially questionable because it blocks a certain route for development. Statocles::App can make default categories from tags, and it can probably also handle a few other optional extras. However, it can't also be something completely different, like a Pod renderer.

If a "blog" is just a Statocles::App with a suggested setup, the current Yancy schema for posts - saying that each $item shall have an author, title, and tags, could also be downgraded to merely a sensible suggestion. Then someone who wants different $item metadata could achieve it with their own configuration and template/layout, and after configuring Yancy accordingly they would also have a cool CMS for it.


if ( my $theme = $app->config->{theme} ) {
do {
my $theme = $app->config->{theme} //= '+Statocles/theme/default';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helped with the unit tests, if it's a clue to why the tests are broken

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Might be that the config_override in Test::Mojo doesn't work the way I assumed it did (which, I don't know why I assumed it would merge with the defaults, because the docs explicitly say it does not)...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It merges with the default when making a statocles.conf, which could be added to each each share directory. Providing a hash to Test::Mojo makes a new config.

@preaction
Copy link
Owner

There are two application ideas that don't quite fit the model of a simple list.

  • Search - The app needs to make a single page, generate an index usable by a client-side search engine (in JavaScript), and render those
  • Calendar - Considering modern Flexbox / Grid CSS, this might be expressible as a list, but it will likely be easier to organize the calendar events into buckets in the controller (day/week/month views would have differently-sized buckets to organize events). Calendars are hard :(

Maybe the idea of having applications manage multiple different lists of data is the problem here: If an app only had one filter and only displayed one list of content, then each app would be a "category" of the site. We could change tags to be just one way to get a document into a category (so, tags aren't links anymore, just labels), and there could be another area on the page for Categories: that would be links (to the landing page of each app the document could appear in). I'm writing a v0 -> v2 upgrade script, and that could be used to generate an appropriate configuration for a v0 blog (though, it wouldn't automatically add new apps when a new tag is created...)

I would definitely be okay if Statocles::App was the generic content list app (so, Statocles::App::List is renamed to Statocles::App). A lot can be done with a simple list and a template, and it would provide some uniformity to the apps: Every app should define a filter to control what content it sees, a template to use to render, etc... So every app should subclass the main Statocles::App.

I'll have to think about this, and maybe try out a couple options to see the pros/cons. If the configuration file gets too complicated, it'll be more difficult to manage / understand. But also maybe we don't need to optimize for sites with 40 different overlapping topics of content (https://mojolicious.io/blog/ has >50 tags by my count).

(aside: "topic" is a shorter word than "category", and might better define what it's doing: collecting articles with similar subject matter)

@wbazant
Copy link
Contributor Author

wbazant commented Sep 14, 2019

@preaction Search and calendar are very nice use cases: they can be generically added to anyone's blog. I think we can arrive at a design that handles them by leaning on the "categories/topics" that an app has.

Each app has a filter: that's a bit like SQL's "where" clause. With more generic topics we would aim at something like a "group by" clause.
When an app has topics, it should do the following when it is being registered:

  • get all content for a filter and no pagination from yancy#list
  • churn through it with a "group by" operation that packs content into labelled buckets, and keep the bucket names
  • for each bucket name, create a route bound to a yancy#list and an tighter filter made from the base filter for an app, and an appropriate extra filter
  • aggregate the buckets into [{href => (that route), text => (bucket name), items => (all items in the bucket)], store them like Statocles::App::Blog stores $self->categories, and make it accessible globally, so that the layout code can read from it

Here are some examples. The current categories correspond to something like below, where the bucket is made from a 'value', and '?' is replaced with it in the bound route for a bucket, like in a stored procedure or something:

{
  value => 'tags',
  filter => { tags => {-has => '?' }},
}

A similar one, for retrieving all posts from the same author:

{
  value => 'author',
  filter => { author => '?'},
}

A calendar is

{
  value => 'date',
  filter => { date => '?' },
}

a template would be using {text, href} assuming that the text field is a date, and be tasked with making a cool widget.

The search index corresponds to a "topic" that puts everything in one bucket:

{
  value => '',
  filter => {},
}

To make the search functional, the template would call a helper and go through the items, tokenising on the item$markdown and making a link from an item$path.

A topic frequently corresponds to a widget in the sidebar: "Categories" and a list of tags, "Posted by" with all the authors, "Search" that searches, "Calendar" that lets you click on days and get posts from that day. However, I expect the functionality will show up throughout the layout: clicking on an author name and seeing their posts, or clicking a label #gardening to see all gardening posts.

I don't know how I would translate "stored procedures" (SQL::Abstract queries with a "?" appearing) to actual code, and keeping items together with text and href is very flexible but seems like too much, and so far it only seems needed for the search use case.

@wbazant wbazant mentioned this pull request Oct 15, 2019
@wbazant
Copy link
Contributor Author

wbazant commented Nov 16, 2019

This branch has a "posted on" and "tags" added to individual blog pages which is probably a patch more than a feature - added through "item-caption" etc. I should have probably done it separately, just now I've tried to make a post on my blog from a master branch, these were gone from posts, and I wondered why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants