CarterA / Tribo

Extremely fast static site generator written in Objective-C
http://cartera.me/2011/10/16/made-on-a-mac/
Other
42 stars 6 forks source link

Specific times for posts #16

Open CarterA opened 12 years ago

CarterA commented 12 years ago

I'll admit, this one is stupid. It's rather impressive that I've created an entire blogging engine where every post is written/published at 12:00.

I've never actually had a problem with this because I've never actually published multiple posts in a day. Not that it would break. The system would work just fine. The issue shows up in the RSS feed. Whenever a post is published, it shows up as being posted at 12:00PM on its publishing date in RSS readers. If you publish multiple posts in a day, then they're all going to clump together, and it'll look dumb.

I'm really not sure how best to tackle this.

sgoodwin commented 12 years ago

Why not use the last-modified date of the markdown file as the publish date? Does that get changed when we read it to html-ify it?

CarterA commented 12 years ago

That should work perfectly! I don't know why I didn't think of that right away.

Oh, and the modification date shouldn't be getting changed during HTML processing, unless we're doing something very wrong.

Also, we should use the filename date as the date whenever possible. When we need the actual time on the clock, we can check the modification date.

sgoodwin commented 12 years ago

So you can publish posts in the past?

CarterA commented 12 years ago

Well it doesn't make much sense in theory, but in practice, it'll be a huge pain. It'll show up whenever someone tries to import posts from another system. If you used just modification dates on my blog, it would work perfectly for the most recent 3 posts (because I wrote those with Tribo), but everything before that (written in Jekyll, and before that, WordPress), will simply show up as being written the day that everything was imported.

sgoodwin commented 12 years ago

Ohhh true, imports. Good catch.

CarterA commented 12 years ago

The best bet might be a combination:

sgoodwin commented 12 years ago

What if we just have users put the date at the top of the file or default to the filename-date (with default time)?

CarterA commented 12 years ago

No, that's too annoying to update. The time that you create the post is going to be different than the time that you finish and publish it.

My outline above avoids that.

Tanner commented 10 years ago

The implementation laid out by @CarterA is good, but posts could move around if I edit a file after publishing it.

For example, if I have two posts:

A – 02-06-2013-a.md – Modification Date: 2/6/2013 2:30 PM – Creation Date: 2/6/2013 1:30 PM
B – 02-06-2013-a.md – Modification Date: 2/6/2013 2:50 PM – Creation Date: 2/6/2013 1:25 PM

When I publish, the date for post A and B will both be the modification date, i.e. post B is posted after post A.

If I modify post A after 2:50 PM, then post A will appear to have been posted after post B. Not desired. If I modify post A on 02/07/2013, then post A will use the creation time (if it matches) or default to some default time, e.g. midnight.

I understand that the time you create the post can be different than the time you finish and publish it, but I can also edit a post after I publish it which will then cause posts to be re-ordered.

I'm thinking this is a bit too complicated with too many edge cases for something that can be simply stored in the filename.

CarterA commented 10 years ago

I discussed this a while back with @GeorgeWS, and the one solution we came up with was to use HFS+ extended attributes to store the publishing date/time of the post. However, that is a piece of information that might be difficult for other engines to parse, import, or export. For the same general reason, I'm trying to avoid the obvious choice of a per-site database.

Tanner, if you wanted to make an unforgettable and highly-valued contribution to this project and put me in your debt forever, coming up with an idea to fix this issue would be a good place to start.

On Aug 26, 2013, at 1:20 PM, Tanner Smith notifications@github.com wrote:

The implementation laid out by @CarterA is good, but posts could move around if I edit a file after publishing it.

For example, if I have two posts:

A – 02-06-2013-a.md – Modification Date: 2/6/2013 2:30 PM – Creation Date: 2/6/2013 1:30 PM B – 02-06-2013-a.md – Modification Date: 2/6/2013 2:50 PM – Creation Date: 2/6/2013 1:25 PM When I publish, the date for post A and B will both be the modification date, i.e. post B is posted after post A.

If I modify post A after 2:50 PM, then post A will appear to have been posted after post B. Not desired. If I modify post A on 02/07/2013, then post A will use the creation time (if it matches) or default to some default time, e.g. midnight.

I understand that the time you create the post can be different than the time you finish and publish it, but I can also edit a post after I publish it which will then cause posts to be re-ordered.

I'm thinking this is a bit too complicated with too many edge cases for something that can be simply stored in the filename.

— Reply to this email directly or view it on GitHub.

Tanner commented 10 years ago

One way you could do it is by kicking out another features: drafts.

When you create a post, the post would be a draft, i.e. not published, preview only. No date would be assigned to this post. When you preview the site and chose the option to view drafts, the post would be assigned the current time and date on when the site is generated.

When a post gets published, i.e. no longer a draft, the post would be assigned a date and time.

Implementation Method A

This method does not require any changes in directory structure or any new files. It simply uses the post's file names.

When a post is a draft, the file name would be xslug.markdown where the x indicates the post is a draft.

When a post gets published, the file name would be 2013-02-04T1514Z-slug.md. Everything before the slug is the date and time (compliant with ISO 8601 to my knowledge).

Everything then would be fine and it would be easy to be compatible with Jekyll or other static site generator backends.

Alternative: Drafts could also be stored in their own directory at the same level as Posts. In this case, the file name would just be slug.markdown.

Implementation Method B

This method would require using JSON files, property lists, or XML. I'm not sure if you're against using such things, but it would open doors for more metadata, e.g. tags, categories, etc.

Posts would have their own folder in the Posts directory (just to keep things clean and organized). In each post directory, there would be the post content, e.g. slugA.markdown, and the post's metadata file, e.g. metadata.json.

Posts
|–– slugA
|    |–– slugA.markdown
|    +–– metadata.json
|–– slugB
     |–– slugB.markdown
     +–– metadata.json

This method is more useful in the future, but it lacks direct compatibility with existing Jekyll-like sites.

CarterA commented 10 years ago

Thanks for the excellent write-up!

I think Implementation Method B, but done in a backwards-compatible manner, would be our best course of action. In other words, we get a list of the contents of the Posts directory, and for any Markdown file, we follow existing logic. However, any time a piece of post metadata (like time, draft status, tags, etc.) gets added to a TBPost object, the file is moved into a folder as you outlined, and metadata is placed in a JSON file.

We may want to still name the Posts subdirectories starting with a simple date, just for the purposes of sorting the directory in Finder.

That being said, we could also just make a quick script to convert existing sites (of which there are approximately...5) to use the new system, and ignore any backwards-compatibility code. That's probably the best answer, since the app isn't officially released yet.

Tanner commented 10 years ago

That sounds good!

I think the quick script method would be better. Less code and things to maintain.

GeorgeWS commented 10 years ago

I love @Tanner's idea of assigning each post the date & time at which it's published (and using drafts until then). In terms of how to store that metadata once it's created, I prefer Method B over Method A. However, I still ultimately prefer the idea of the HFS+ extended attributes over the separate metadata files.

Here is my thinking: I get the desire to keep this relatively transparent for the sake of other engines, and I see how extended attributes could be tricky to deal with outside of Tribo. However, while they may be a bit more transparent, separate metadata files will still have to be parsed by other engines. In other words, these are both proprietary solutions.

Given that, I think the extended attributes are cleanest. The post filename won't matter, so you can make it anything you want to make the directory sort nicely. Plus, you won't need any additional files (whether they be individual metadata files or a site-wide database) inside of the Tribo bundle. And it's still expandable by adding more attributes, or (if you don't want to clutter the filesystem with too many attributes) by adding more information to one "Tribo metadata" attribute.

Regardless of what you choose, you'll still want to document whatever you do here in the repository so it's easy for developers of other engines to parse the metadata. It also may not be a bad idea to create a built in export feature for any widely adopted standards you want to support.

And yes—as far as backwards compatibility, don't worry about me. ;-)

CarterA commented 10 years ago

I'm less keen on the HFS+ extended attributes. Yes, both ideas require parsing on the part of another engine, but JSON is a very widely-adopted standard. Extended attributes are not.

But that isn't the worst part. The fatal flaw with using extended attributes is that it means that the file can no longer be safely copied onto other file systems, even for transit/backup. There are even well-known backup tools (I believe Backblaze used to have problems with this, it might still) that fail to backup extended attributes.

That all culminates to mean that we can't rely on xattrs to store important information.

GeorgeWS commented 10 years ago

Ohhh, I didn't know about the flakiness of extended attributes across other file systems. In that case Method B gets my vote, even though I'm still not a fan of every single post having its own metadata file. Perhaps the site-wide metadata database (metadatabase?) isn't such a bad idea if it can use a standard like JSON, again given that the individual metadata files would be proprietary anyway.

Tanner commented 10 years ago

I'm not particularly for having a single, large data file (be it JSON or a property list, whatever).

I would like to be able to easily edit the metadata files for posts. Having a single, large file makes that process tedious. It's convenient to have the files right there next to the posts.

There are also other issues with a large, metadata file such as having to rewrite for just a single change, etc…

Multiple metadata files are just easier in my mind.

@GeorgeWS - What is your definition of proprietary? The definition I go by is Wikipedia's. Your use does not make sense to me. What do you mean by "the individual metadata files would be proprietary anyway"?

GeorgeWS commented 10 years ago

@Tanner: I suppose I'm not really using the term correctly; I'm using it simply to mean that the method we use is our own (e.g. must be parsed by other engines, however transparent it is), not to imply that the format would be "closed" in any legal sense.

And as far as Method B—I'm really not against it; I was just hoping to find an equally appealing option involving less separate files and more logical grouping of the metadata with its post (beyond having them together in the same directory, that is). But I do like the directory structure that @Tanner came up with—at least by giving each post its own folder you maintain a nice list where each of your posts is listed once, even if they each contain multiple components.

Tanner commented 10 years ago

Ah, gotchya. I understand.

I'll start on learning the source and implementing drafts/times. If anyone has any new thoughts, post it here. :)

CarterA commented 10 years ago

My one remaining thought is that drafts could just be implemented as a boolean in the metadata file, instead of having anything to do with the filename.

Tanner commented 10 years ago

Yeah. That's what I was planning on implementing. The filename of the metadata file would just be "metadata.extension" with the data inside in whatever format. On Aug 27, 2013 12:34 PM, "Carter Allen" notifications@github.com wrote:

My one remaining thought is that drafts could just be implemented as a boolean in the metadata file, instead of having anything to do with the filename.

— Reply to this email directly or view it on GitHubhttps://github.com/CarterA/Tribo/issues/16#issuecomment-23350341 .