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

allow menu front matter specific to a 'post'/Org subtree #19

Closed
titaniumbones opened this issue Jun 30, 2017 · 18 comments
Closed

allow menu front matter specific to a 'post'/Org subtree #19

titaniumbones opened this issue Jun 30, 2017 · 18 comments

Comments

@titaniumbones
Copy link
Contributor

The YAML syntax for Hugo menu placement is:

menu:
main:
parent: articles
[etc]

Do we have a way to gneerate this kind of multilevel metadata? If not, we should have one...

@kaushalmodi
Copy link
Owner

kaushalmodi commented Jun 30, 2017

I didn't follow that.

Isn't the menu configuration done in config.toml or config.yaml? The user would still need to update those manually.

Or did you mean that you'd like to specify the destination subdir for each subtree?

Example:

#+TITLE: My blog
* Posts 
These go to <blog root dir>/posts/
** Post 1
This goes to <blog root dir>/posts/post1.md
* Articles 
These go to <blog root dir>/articles/
** Article 1
This goes to <blog root dir>/articles/article1.md

@titaniumbones
Copy link
Contributor Author

I have a particular use-case in mind.

For my courses, I maintian about 3-5 org source files, e.g., "course Details", "Labs", "Assignments". Then, for each assignment, I I maintian a subtree. So Assignments.org might have the structure:

* Short Paper 1
* Book Review
* Final Essay

Each of these should probably be a child menu item of the Assignments parent menu item. Ideally, this information would be stored (a) in the org-mode properties drawer, and then (b) in the front matter of each post. THis keeps all the rlevant information in the org source files. Otherwise config.toml (or .yaml) will easily get out of sync with the actual files.

Unfortunately, the yaml and toml syntax for storing complex data objects like these hash tables/dictionaries is difficult to reproduce:

menu: 
    main:
        parent: assignments
        weight: -100

I'm not quite sure even how this is supposed to be represeented in TOML.

Anyway, it would be really nice to be able to automate some of this. And I think it's not just me who would like to be able to do that.

Does this make more sense?

Hugo menu docs are here: https://gohugo.io/extras/menus

@titaniumbones
Copy link
Contributor Author

so, basically I'm confirming your example.

@kaushalmodi
Copy link
Owner

Unfortunately, the yaml and toml syntax for storing complex data objects like these hash tables/dictionaries is difficult to reproduce:

menu: 
    main:
        parent: assignments
        weight: -100

Correct. But that menu hierarchy will be pretty much static once your site structure stabilizes. And then may be need adding/removing/moving the menu section once in a while. Is that right?

My concern is that the config.toml contains many things which the user might tweak from time to time. We do not want ox-hugo to unknowingly butcher user settings.. basically don't update the same file manually as well as automatically. And if we do it completely automatically, then what you said verbatim here ( #20 (comment) ) :)

This would get one closer to automating the construction of a whole hugo site directly from org.


I'm not quite sure even how this is supposed to be represeented in TOML.

It would look something like this in TOML:

[[menu.main]]
parent = "Assignments"
weight = -100

[[menu.main]]
parent = "Labs"
weight = 1

Anyway, it would be really nice to be able to automate some of this.

Definitely. Then we need to generate the whole config.toml from scratch on each export ( #20 )

@titaniumbones
Copy link
Contributor Author

Definitely. Then we need to generate the whole config.toml from scratch on each export ( #20 )

Not necessarily, since it's possible to add the individual menu items in the frontmatter of each post. In fact ,this is how the hugo docs manage things:
https:/gohugoio/hugoDocs

here's an example:
https:/gohugoio/hugoDocs/blob/master/content/overview/configuration.md

full YAML for the above:

---
aliases:
- /doc/configuration/
lastmod: 2016-09-17
date: 2013-07-01
linktitle: Configuration
menu:
  main:
    parent: getting started
next: /overview/source-directory
toc: true
prev: /overview/usage
title: Configuring Hugo
weight: 40

@titaniumbones
Copy link
Contributor Author

It seems to me that Hugo itself hasn't really decided how it wants to manage menus and metadata in general. Org's data managmeent strategy is a little clearer, I think, and I would want to err on the side of keeping as much informaiton as possible in org itself, since the very fact of the exporter sort of assumes that the user is org-centric. At least I think so!

@kaushalmodi kaushalmodi changed the title allow menu & other complex frontmatter allow menu & other complex frontmatter specific to a 'post'/Org subtree Jun 30, 2017
@kaushalmodi
Copy link
Owner

here's an example:
https:/gohugoio/hugoDocs/blob/master/content/overview/configuration.md

Thanks for that example. I have tweaked the title slightly. So we will need to support these in the Org property drawer and then translate those to TOML/YAML. Right?

@titaniumbones
Copy link
Contributor Author

Yes, thank you, I think that sounds right.

@titaniumbones
Copy link
Contributor Author

I'm trying to generate a nested plist of values related to menus, that can then be passed off to the frontmatter generators (yaml and toml). Unfortunately I'm terrible at elisp, can can never tel lthe difference between a symbol and a vlaue, or a plist and an alist...

THisi s what I have:

(defun org-hugo--collect-menu-metadata (info)
  "collect all the menu-related metadata and return a nested plist of the values
to be used by toml and yaml frontmatter creators."
  (message "info: %s" info)
  (let* ((menu-atts '(:hugo-menu-parent "parent" :hugo-menu-weight "weight"))
         (menu-name (plist-get info :hugo-menu-name))
         (atts-plist (cl-loop for att in (plist-get-keys menu-atts)
                              collect (plist-get menu-atts att) 
                              collect (plist-get info att))))
    (plist-put '() menu-name atts-plist)))

But this generates (main (parent nil weight 50))

I'm pretty sure this is a symbol/value clash but if you could either show me how to fix it or suggest a better method I'd be very grateful.

@titaniumbones
Copy link
Contributor Author

If you have thoughts on this I'd love to hear them. I will try to investigate myself within the next 48 hours but might not get there, quite.

@kaushalmodi
Copy link
Owner

kaushalmodi commented Jul 6, 2017

can can never tel lthe difference between a symbol and a value, or a plist and an alist

Here's a rough explanation:

  • A symbol is prefixed with a quote. So if you eval (C-x C-e at the end of this expression) 'foo, you will get foo.
  • A variable is not prefixed with a quote. So if you eval foo (note: no quote), you will get the value associated with the 'foo symbol if set, else you will get the error

    Debugger entered--Lisp error: (void-variable foo)
    eval(foo nil)

  • A plist is just a list but with even number of elements. It looks like this: (KEY1 VAL1 KEY2 VAL2). See (elisp) Property Lists for more information.
  • An alist is.. simply put.. a list of conses or lists. It looks like this: ((KEY1 . VAL1) (KEY2 . VAL2)), or ((KEY1 VAL1a VAL1b) (KEY2 VAL2a VAL2b)). See (elisp) Association Lists and (elisp) Plists and Alists for more information.

If you have thoughts on this I'd love to hear them. I will try to investigate myself within the next 48 hours but might not get there, quite.

I cannot promise today, but I will get to this.

Thanks!

@titaniumbones
Copy link
Contributor Author

Hi Kaushal, you have been committing up a storm and I'm struggling to keep up! Thank you for all the new features. Any chance that this menu piece can work its way up your to-do list? getting this working would be really fantastic for me...

@kaushalmodi
Copy link
Owner

I'm really busy this weekend. This is next on my list; will have a look on Monday. The feature additions were just to accommodate for basic support of tables and source blocks. With that, I might even publish a new post on my blog generated by ox-hugo. I think this package is almost ready for basic blogging :)

kaushalmodi pushed a commit that referenced this issue Jul 17, 2017
This commit adds preliminary support for menu metadata in posts. It
sort of works with YAML frontmatter but not with TOML.

For #19
@kaushalmodi
Copy link
Owner

kaushalmodi commented Jul 18, 2017

Found a TOML front matter example (for reference):

+++
date = "2014-09-18T21:51:13+02:00"
title = "About Us"
[menu.main]
name = "About"
weight = 4
+++
  • One important thing to remember is that all table definitions in TOML needs to be last, since it just keeps adding variables that appears until the end or until the next table definition.

Example Hugo partial to make use of the above menu:

<nav>
	<ul>
		{{ range .Site.Menus.main }}
		<li><a href="{{ .Url }}">{{ .Name }}</a></li>
		{{end}}
	</ul>
</nav>

Source

@kaushalmodi
Copy link
Owner

@titaniumbones From what I understand, the parent and identifier part of menu in your PR for menu support is optional, right?

@titaniumbones
Copy link
Contributor Author

titaniumbones commented Jul 18, 2017 via email

@kaushalmodi kaushalmodi changed the title allow menu & other complex frontmatter specific to a 'post'/Org subtree allow menu front matter specific to a 'post'/Org subtree Jul 19, 2017
@kaushalmodi
Copy link
Owner

Closing this issue as menu front matter is now fully supported in both TOML and YAML.

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

No branches or pull requests

2 participants