Simpler data lookups #5

Closed
TWiStErRob opened this Issue Jun 12, 2015 · 17 comments

Projects

None yet

5 participants

@TWiStErRob

Re: http://www.minddust.com/post/tags-and-categories-on-github-pages/

It's possible to get rid of this double for lookup:

{% for post_tag in post.tags %}
    {% for data_tag in site.data.tags %}
        {% if data_tag.slug == post_tag %}
            {% assign tag = data_tag %}
        {% endif %}
    {% endfor %}

Instead you could write a much nicer:

{% for post_tag in post.tags %}
    {% assign tag = site.data.tags[post_tag] %}

Your tags.yml currently looks like this:

- slug: django
  name: Django

- slug: django-template-tags
  name: Django Template Tags

- slug: font-awesome
  name: Font Awesome

- slug: icons
  name: Icons

and the above works if you restructure it like so:

django:
  slug: django
  name: Django
django-template-tags:
  slug: django-template-tags
  name: Django Template Tags
font-awesome:
  slug: font-awesome
  name: Font Awesome
icons:
  slug: icons
  name: Icons

with the added benefit of {{site.data.tags.icons.name}}, should you want to do that. It makes more sense if you're crossreferencing projects. The dot notation even works with font-awesome, probably because Liquid is not a full-fledged language and - doesn't mean minus.

and since you only used slug to look the tag up, you it's not needed any more:

django:
  name: Django
django-template-tags:
  name: Django Template Tags
font-awesome:
  name: Font Awesome
icons:
  name: Icons

Regarding /blog/tag/{{ tag.slug }}/, since tag.slug == post_tag was true you can use post_tag to create the url. This is really question of taste though, if you don't mind duplicating the slug as tag key in yaml you could use the uniform tag.slug version.

When you're listing all tags you can use

{% for data_tag_entry in site.data.tags %}
    {% assign data_tag_slug = data_tag_entry[0] %}
    {% assign data_tag = data_tag_entry[1] %}

so the slug is not lost.

This obviosly works for all data ymls.

@minddust
Owner

just tried this out. works like charm. i will currently stick to my solution but extended the blog post with your solution. thanks for diggin in :) cheers 🍺 stephan

@minddust minddust closed this Jun 13, 2015
@MrLoh
MrLoh commented Jun 15, 2015

Hey @minddust I was also inspired by your blogpost and developed my own solution based on it. I actually completely automated the tag and date archive creation process with a ruby script. It's all compatible with GitHub Pages and you don't even need an extra file to enter tags into, they are accessible via {% for tag in site.tags %} {{ tag[0] }} {% endfor %}. If you are interested you can read about it in my blog and see it working. If you like it, I would be really happy if you'd add a link to my blogpost from your site. Just starting out with my blog.

Best,
Tobias

@minddust
Owner

hey tobias @MrLoh just read through your post. nice. I have a lot of work ahead but I will definitely try this out - maybe at the weekend. will let you now about the update :) stephan

@acao
acao commented Jul 4, 2015

@MrLoh I like this approach but it is not totally Github Pages compatible unfortunately. In my case, users are writing content using prose.io and thus I can only use plugins available in the github-pages gem, though I guess I could schedule a daily build using travis or wercker and rake or gulp. I like your suggestion at the end of using clientside frameworks. Let me know if you find a way around this problem!

Also, @minddust the simplification you mention at the end on your blog doesn't show the first assign statement for the slug that he mentions above.

@TWiStErRob

@acao he added the simplest version: post_tag is the slug and tag.name is the human form. There's not much point in having a different data key and slug for the tags, however possible.

@LovesTha

Thanks for this its really good. I'm just trying to figure out how to have the blog_by_tag.html list the nice friendly name for the tag not the slug. The post layout uses 'tag.name' so the first thing that occured to me was that where the BbT.html uses 'page.tag' to display the slug that 'page.tag.name' should work, but that doesn't.

Other various things I've tried haven't done anything and I have no idea how this stuff is working.

@TWiStErRob

@LovesTha tag.name only works if the tag variable refers to the value in the _data/tags.yml via site.data.tags. post.tags and site.tags only contains the list of tags you put in the front matters and it is advised to put the slug/data key there.

If the page has a single tag like your page.tag.name try suggest, you can try site.data.tags[page.tag].name.

Of course all of the above assumes you used my last version of tags.yml.
(Tip: use backtick instead of apostrophe in GitHub issue comments to designate code)

@LovesTha

Thank you. That makes some sense, but isn't completely obvious.

Yes site.data.tags[page.tag].name works in the header field of blog_by_post.html (I had converted to the style you'd suggested hoping that would make it obvious to me how to do it)

@TWiStErRob

@LovesTha you can read the docs on data files and built-in variables to clear some things up, I turn a lot to the official docs too. The last example at data files looks very similar to this one.

@minddust
Owner

@TWiStErRob thanks for the quick response 👍 :)

@LovesTha

Nup, I still aren't getting what is going on enough to write anything 'simple'. To me this should work:

<p>Categories</p>
<ul>
{% for tag in site.data.tags %}
<li> <a href="/blog/tag/{{tag}}/">{{tag.name}}</a></li>
{% endfor %}
</ul>

But it doesn't. {{tag}} is bbbg{"name"=>"Badass Burgers & Board Games"} and {{tag.name}} is nothing, which really surprises me as tag clearly has a name field. I can't see how this code is materially different to the first example at the data files documentation.

(I'm not sureprised that the straight tag isn't doing what I'd like but tag.name is confounding me)

@TWiStErRob

@LovesTha your tag variable there is actually an array: ["bbbg", {"name": "Badass Burgers & Board Games"}], that bbbg{"name"=... is a very unfortunate toString display.

Based on the above this will solve your problem:

{% for tag in site.data.tags %}
    <li><a href="/blog/tag/{{tag[0]}}/">{{tag[1].name}}</a></li>
{% endfor %}

or a more elaborate and readable version:

{% for tag_entry in site.data.tags %}
    {% assign tag_key = tag_entry[0] %}
    {% assign tag_data = tag_entry[1] %}
    <li><a href="/blog/tag/{{tag_key}}/">{{tag_data.name}}</a></li>
{% endfor %}
@LovesTha

Okay, that is a bit counter intuitive :) But I can cope with that.

@justopie justopie added a commit to justopie/justopie.github.io that referenced this issue Jan 12, 2016
@justopie justopie Simplify the lookups per minddust/minddust.github.io#5 f8995ea
@minddust
Owner
minddust commented Sep 8, 2016

for those of you who are still interested:

found an other way to generate content (like tags and categories, etc):

http://www.minddust.com/post/alternative-tags-and-categories-on-github-pages/

@TWiStErRob

Thanks for the alert!

Bug?: Didn't you mean permalink: /blog/category/:slug/ instead of :name?

@minddust
Owner

slug is not available in the jekyll _config. the only attributes listed under step3:

https://jekyllrb.com/docs/collections/#step-3-optionally-render-your-collections-documents-into-independent-files

they are directly related to the collection entry and therefore should/must be named equal to the slug. maybe i should add a note in the post.

@TWiStErRob

Aah, that name is the filename and not the name in front matter. Maybe change name in front matter to title.... And do you need to repeat (DRY) slug if it has to be the same as file name?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment