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

[Proposal] Add support for page meta #7

Closed
carbontwelve opened this issue Dec 14, 2015 · 21 comments
Closed

[Proposal] Add support for page meta #7

carbontwelve opened this issue Dec 14, 2015 · 21 comments

Comments

@carbontwelve
Copy link

With issue #3 the necessity for per page meta will become a requirement for example:

  • taxonomy (tags, categories, etc) used for generating taxonomy index pages
  • draft status flag
  • published_date (to enable scheduling, if the published_date is in the future the page does not get generated)
  • etc

Page meta could also be made available within the page as PHP variables, in the same way as the config.php variables are; page meta variables with the same key would overwrite variables set in config.php.

Possible methods of implementation:

In a recent client project I used blade comment syntax for this for example:

{{-- draft: true --}}
{{-- tags: bar, foo, etc --}}

I would be happy to dig that code out and add the functionality myself. Alternatively page meta could be added knockout.js style with a html comment such as:

<!-- jigsaw-meta
draft: true
tags:
    bar
    foo
    etc
-->

These comments could then be parsed out when the page is generated to html, so that no backend meta is leaked.

I intend to use jigsaw for a blog and am very happy to help write an implementation for both this and #3.

@carbontwelve carbontwelve changed the title Add support for page meta [proposal] Add support for page meta Dec 14, 2015
@carbontwelve carbontwelve changed the title [proposal] Add support for page meta [Proposal] Add support for page meta Dec 14, 2015
@carbontwelve
Copy link
Author

This could also be used to enable/disable pretty URLs on a per page basis rather than as a global via the --pretty=false option.

@adamwathan
Copy link
Contributor

Thanks for getting the discussion started! I think this is gonna have to be done super carefully to make sure we keep the project as simple to use as possible, so would be good to bounce around a bunch of ideas of how this could be done and figure out what seems like the best path forward. I want to be really careful not to offer too much flexibility at the expense of making it much more of a pain in the ass to use.

I'm personally pretty partial to a YAML + Markdown sort of format like you see in Jekyll and Sculpin for blog posts, what are your feelings on that?

@carbontwelve
Copy link
Author

No worries, I really love the simplicity of what you have created and certainly don't wish to add any unnecessary clutter to what is already pretty usable.

I have had a look over a range of static site generators and have noticed they all tend towards YAML + Markdown akin to both Jekyll and Sculpin. I think that works really well, certainly with markdown.

For the blade files a YAML approach would require parsing that out of the files header before passing the body to the blade engine.

@sixlive
Copy link

sixlive commented Dec 17, 2015

I've been working on some integration of content types (#3) using markdown for the content, essentially using some syntax for meta.

e.g.

##
# Title: Super Awesome Post
# Date: 10/21/2015
##

# This is some content

Vestibulum id ligula porta felis euismod semper. Sed posuere consectetur est at lobortis.

Those attributes would get turned into an variables that you can access in the blade template.

Something like this:

{{ $title }}
Published: {{ $date}}

{{ $content }}

This would still involve parsing the header out of the content before hand but it could be accomplished with a few lines of regex. Work has been keeping me pretty busy so I haven't had a ton of time. I'm hoping I can get back to it over the weekend / holiday.

@carbontwelve
Copy link
Author

I have been working on this today here. I ended up moving some parts of the functionality around to aid in testing and to make it easier to add future functionality (such as file watching and collections). Currently I have it to the point where it loads meta from file headers in a YAML format and injects it into the pages scope. All but one unit test passed, and that's because I have yet to implement overloading of the pretty option on a per page basis.

@adamwathan
Copy link
Contributor

@carbontwelve Cool! Keep me updated with how it's going, would love to check it out when you have something you want to show!

@carbontwelve
Copy link
Author

I managed to implement page meta in my branch here I ended up adding some additional classes to help with the additional functionality. I'm not entirely happy with how I have laid out the execution order but its working. What do you think?

@jbrooksuk
Copy link

What about Frontmatter?

@carbontwelve
Copy link
Author

@jbrooksuk it seems I wrote similar functionality into my MetaParser class here I didn't know the method of data storage was called front matter haha.

I have had a look at your implementation with the idea in mind to use the library and raised some issues which stop me from using it at present.

@jbrooksuk
Copy link

I have had a look at your implementation with the idea in mind to use the library and raised some issues which stop me from using it at present.

I'm on them now :)

@jbrooksuk
Copy link

Phrontmatter now supports YAML, JSON and TOML for the meta data :)

@mattstauffer
Copy link
Member

My gut says YAML + Markdown is an easy win, and the tough part will be configuring how to add meta support for Blade pages.

So, the next question is, which Blade pages merit meta data? We've mentioned collection index/listing pages. Anything else? To me YAML frontmatter is a perfect pair with Markdown, but the job we're trying to accomplish in associating a Blade template with being an index page may better be solved a different way.

There's also the interesting idea of doing collection-ing by putting all the markdown in a folder. So that ends up with something like this:

├─ source
│  ├─ _assets
│  ├─ blog
│  │  └─ my-blog-post.md
│  ├─ blog.blade.php
│  └─ index.blade.php

That means we are going to associate a blog collection with the blog folder and the blog root blade file.

What do we think about this? Are there other use cases I'm missing here? Are there things we won't be able to handle given this specific example?

@dannyweeks
Copy link

Hey all, I have been playing around with the concept of collections (#3) on a branch of mine.

I have it working close to what @mattstauffer has outlined above with the exception of including a directory for storing the collection's item template.

single-{collection}.blade.php is what the collection items are passed into to render.

├─ source
│  ├─ _assets
│  ├─ blog
│  │  └─ my-blog-post.md
│  ├─ _collections
│  │  └─ single-blog.blade.php
│  ├─ blog.blade.php
│  └─ index.blade.php

For easy generation I have added a make:collection command which generates all the boilerplate for a given collection.

make:collection

When running jigsaw build the CollectionHandler checks to see if the file in question is in a folder which has been registered in the config under collections. Piggy backing off of @adamwathan's markdown handler the file is compiled to blade going via the collections template e.g. _collections.single-blog.blade.php.

As mentioned above, the CollectionHandler extends the MarkdownHandler for this reason I did have to change some of the visibility from private to protected.

Side note: I have called the above handler CollectionHandler but I think a more suitable name is CollectionItemHandler which will become apparent below

Next steps

This is more of a proof of concept than anything because it is missing a lot but happy to take it as far as needed for it to be an actual PR!

What stands out as missing for is a nice way to pass collection items into a collections index page. I have been trying to think of a clean way of doing this but haven't come up with a nice way. Possibly registering collection items into Jigsaw and then when an index is being registered it can just take them from there. I have been playing about with this on a separate branch but have knowing solid yet! As I type another avenue that could be explored is storing item meta data in a temp folder.

I think once we have a collection of items it won't be too hard to have sorting etc.

@danmatthews
Copy link

danmatthews commented May 4, 2016

Is there no love for keeping the implementation close to what Jekyll already implements?

No matter the language of the post - blade or markdown, just use YAML front matter, and require that a date be specified (in any format parsable by strtotime), markdown posts require that a section be specified alongside a extends param as they do now.

I thought it might make it more Laravel-like by implementing collection folders using the @ prefix:

Directories prefixed by '@' are not ignored during compilation, but rather treated as collections of content. Their content will be rendered using the name of the folder (without the '@' prefix) as the first part of the URL structure.

├─ source
│  ├─ _assets
│  ├─ @posts
│  │  └─ my-first-blog-post.md
│  ├─ blog.blade.php
│  └─ index.blade.php

This would then render out as the URL:

http://mysite.com/posts/my-first-blog-post/index.html (pretty)
http://mysite.com/posts/my-first-blog-post.html

Then you could inject a $collections object into blade which manages listing and paginating collections in templates:

@foreach ($collections->paginate('posts', 10) as $post)

<h2>{{ $post->title }}</h2>

<p>{{ $post->content }}</p>

@endforeach

{{ $collections->pagination('posts') }}

I've got a partial implementation of this already.

@rodrigore
Copy link

Hi!

I'm testing jigsaw and I created a helper function call posts that get a collection of the posts with the yaml content of each file and the link of the post.

For example if I have in my post file the next yaml content:

---
extends: _layouts.master
section: body
title:  "Hello Mundo"
date:   "2014-01-24"
---

In the layout file, I can call the method posts() using a foreach like this:

@foreach (posts() as $post)
    <li><span>{{ $post['date'] }}</span> &raquo; <a href="{{ $post['link'] }}">{{ $post['title'] }}</a></li>
@endforeach

The content of the posts function is this:

<?php

use Mni\FrontYAML\Parser;
use TightenCo\Jigsaw\Filesystem;

function posts()
{
    $posts = [];

    foreach ((new Filesystem)->allFiles('source/posts') as $file) {
        $document = (new Parser())->parse($file->getContents());
        $posts[] = array_merge($document->getYAML(), [
            'link' => "posts/" . basename($file->getRelativePathname(), '.md')
        ]);
    }
    return collect($posts);
}

1 -code

2 - result

@mattstauffer
Copy link
Member

Hey folks, we've let this collections concept sit for a bit and I think it's nearing time to visit our various options.

Could anyone who has a functioning solution do me a huge favor and give me a link to your repo, or, if you'd like, make a PR?

We're looking to combine "what people are already familiar with" (e.g. Jekyll) with "what makes sense for how Blade and Jigsaw work" with "What's both simple and powerful".

@forsaken-threads
Copy link

I've created a working solution. There's a readme file on the repo with an explanation of my methodology as well as some source code using it and a link to the site that it generates. I'd love for you to check it out and let me know what you think: Jigsaw Build Decorating The fork with the code changes is here.

@blazeworx
Copy link

Yo @mattstauffer, the fork mentioned above by @forsaken-threads 👍 is the one I was telling you about the other day - the one we've been working on at the office, check it out :)

@jbrooksuk
Copy link

FWIW, Phrontmatter supports YAML, TOML and JSON meta data, if that makes it more customisable 👍

@damiani
Copy link
Contributor

damiani commented Apr 21, 2017

This is now handled with collections in release 1.0.0 (https://github.com/tightenco/jigsaw/releases/tag/v1.0.0), see the docs for more details. Page variables can be added in YAML front matter to collection items, whether they are Markdown or Blade files, as well as in config.php.

@damiani damiani closed this as completed Apr 21, 2017
@carbontwelve
Copy link
Author

@damiani congratulations on the release of 1.0.0, it looks amazing.

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

No branches or pull requests