Skip to content
This repository has been archived by the owner on May 26, 2019. It is now read-only.

Extract TOC and Pagination Helpers #10

Closed
10 tasks
trek opened this issue Feb 22, 2015 · 10 comments
Closed
10 tasks

Extract TOC and Pagination Helpers #10

trek opened this issue Feb 22, 2015 · 10 comments

Comments

@trek
Copy link
Member

trek commented Feb 22, 2015

Our table of contents and pagination generation is generally useful for anyone writing book-style content. We should extract these helpers so it will be easy to have a Gitbook like site.

A PR that successfully addresses this issue will:

  • create a new repo for making a middleman plugin
  • allow the author to provide a file in data/<name>.yml that is an array of chapter objects that contain section arrays. The data is in the following format:
- title: 'Introduction'
  url: 'index'
- title: 'Chapter 1: Call me Ishmael'
  url: 'chapter-1'
  sections:
    - title: 'A History of horror'
      url: 'index'
    - title: 'The Whale'
      url: 'the-whale'
- title: 'Chapter 2: The Imapler'
  url: 'chapter-2'
  sections:
    - title: 'Sex and Fear'
      url: 'index'

These will correspond to a file structure like this:

.
├── data
│   └── chapters.yml
└── source
    ├── chapter-1
    │   ├── index.md
    │   └── the-whale.md
    ├── chapter-2
    │   └── index.md
    └── index.md
  • provide a helper to generat the table of contents on each page
  • provide a helper to link to the next section. If you're at the end of a chapter, this links to the first section in the next chapter if there is one
  • provide a helper to link to the previous section. If you're at the beginning of a chapter, this links to the last section in the previous chapter if there is one
  • provide a a helper to show the title of the next chapter/section pair
  • provide a a helper to show the title of the previous chapter/section pair
  • unit test all of this (not integation like we've had. but unit tests)

BONUS ROUND:

  • like Gitbook, allow the author to express table of contents as markdown
- title: 'Introduction'
  url: 'index'
- title: 'Chapter 1: Call me Ishmael'
  url: 'chapter-1'
  sections:
    - title: 'A History of horror'
      url: 'index'
    - title: 'The Whale'
      url: 'the-whale'
- title: 'Chapter 2: The Imapler'
  url: 'chapter-2'
  sections:
    - title: 'Sex and Fear'
      url: 'index'

becomes

* [Introduction](index.md)
* [Chapter 1: Call me Ishmael]
    * [A History of horror](chapter-1/index.md)
    * [The Whale](chapter-1/the-whale.md)
* [Chapter 2: The Imapler]
    * [Sex and Fear](chapter-2/index.md)
  • allow arbitary levels of nesting. Each section can have its own section.
@trek
Copy link
Member Author

trek commented Mar 11, 2015

@michaelrkn/@erezny you mentioned wanting to jump in at EmberConf. Either of you want to tackle this?

@johno
Copy link

johno commented Mar 13, 2015

If there's no one currently working on this, I can go ahead and tackle.

@jagthedrummer
Copy link
Contributor

We meet again @johnotander! ;) I was just looking at this one too. It'll probably be tomorrow before I could spend any real time on it, but I'm happy to help you out if you get something started.

@johno
Copy link

johno commented Mar 13, 2015

Hello again @jagthedrummer!

Great, I'll start digging and working on something. I'll let you know if I make any progress today (I only have about an hour or so this evening). I was hoping to get a basic plugin skeleton together with some failing unit tests, and possibly getting some functionality together if things go well.

I'm currently working out of https://github.com/johnotander/middleman-toc as I'm not sure where @trek intends for the plugin to live. I also don't know if I'll even produce anything at this point as I'm new to Middleman. I'm happy to transfer ownership wherever if need be.

Let me know if you'd like to collaborate on the middleman-toc repo, @jagthedrummer and I'll add you as a collaborator.

@trek
Copy link
Member Author

trek commented Mar 13, 2015

I think @tundal45 might have started this?

@michaelrkn
Copy link
Contributor

I'm going to take this up:

  • I've started by opening a PR (Refactor TOC tests #278) to clean up the tests.
  • Next, I'm going to focus on refactoring the code and adding missing tests.
  • Then, I'll pull out the Ember-specific code, and change names as necessary to not be tied to Ember. What's left should be suitable to turn into a general-purpose gem.
  • Finally, I'll pull out toc.rb and toc_spec.rb into a gem.

This should be a nice incremental process, so if I ever get hung up it will be easy for somebody else to jump in.

I'll open PRs for each of these checkboxes along the way to make sure I'm on the right path, and wait for them to be merged in before moving to the next item.

@michaelrkn
Copy link
Contributor

I'm moving on to refactoring, and I'd like some input before I start changing things around.

First, I'd like to suggest we change the basic YAML structure from:

guides:
  - title: "Middleman Basics"
    url: "middleman-basics"
    chapters:
      - title: "What even is middleman?"
        url: "index"
      - title: "Nobody really cares about this"
        url: "meh"
  - title: "Extending Middleman"
    url: "extending-middleman"
    chapters:
      - title: "What are extensions?"
        url: "index"

to:

pages:
  - title: "Middleman Basics"
    url: "middleman-basics"
    pages:
      - title: "What even is middleman?"
        url: "index"
      - title: "Nobody really cares about this"
        url: "meh"
  - title: "Extending Middleman"
    url: "extending-middleman"
    pages:
      - title: "What are extensions?"
        url: "index"

Since we're extracting this into a general-purpose plugin, I think we should get away from Ember guides-specific language like "guides" and "chapters". "pages" is nice and generic. Also, using "pages" for both the top-level key and sub-keys will make things more consistent both for developers using the plugin and for the plugin code itself, and make it easy to allow for arbitrary levels of nesting.

Next, I'd like to change the CSS class structure from:

<ol id='toc-list'>
  <li class='level-1'>
    <a href="getting-started/">Getting Started</a>

    <ol class=''>
      <li class='level-3'>
        <a href="getting-started/">Installing Ember</a>
      </li>

      <li class='level-3'>
        <a href="getting-started/glossary/">Glossary</a>
      </li>
    </ol>
  </li>
</ol>

to:

<ol class='toc-level-1'>
  <li class='toc-level-1'>
    <a href="getting-started/">Getting Started</a>

    <ol class='toc-level-2'>
      <li class='toc-level-2'>
        <a href="getting-started/">Installing Ember</a>
      </li>

      <li class='toc-level-2'>
        <a href="getting-started/glossary/">Glossary</a>
      </li>
    </ol>
  </li>
</ol>

This will again help with allowing arbitrary levels of nesting, and also be a bit easier to reason about.

Finally, for not including items in the TOC, I'd like to suggest we switch from something like:

pages:
  - title: "Middleman Basics"
    url: "middleman-basics"
    pages:
      - title: "What even is middleman?"
        url: "index"
      - title: "Nobody really cares about this"
        url: "meh"
        skip_sidebar_item: true
  - title: "Extending Middleman"
    url: "extending-middleman"
    pages:
      - title: "What are extensions?"
        url: "index"
        skip_sidebar: true

to:

pages:
  - title: "Middleman Basics"
    url: "middleman-basics"
    pages:
      - title: "What even is middleman?"
        url: "index"
      - title: "Nobody really cares about this"
        url: "meh"
        skip: true
  - title: "Extending Middleman"
    url: "extending-middleman"
    skip: true
    pages:
      - title: "What are extensions?"
        url: "index"

This will be easier to reason about: the skip key will be on the element that should be skipped, rather than on the child in the case of skip_sidebar; it will also be consistent, making it easier to figure out where to put it; and it will allow for arbitrary nesting.

Let me know if anybody has any thoughts about this!

@michaelrkn
Copy link
Contributor

I am almost done with this, but I'm 1) getting a little bored of working on it and 2) a little out of my depth on solving the next problem. Here's what's left:

  • Refactor and rename next_chapter and previous_chapter to next_page and previous_page, allowing arbitrary levels of nesting.
  • Move next_chapter_link and previous_chapter_link into layout.erb (since they are Ember-specific).
  • Extract toc.rb and toc_spec.rb into a gem.

The first item is a bit tricky, because you need to traverse from each page up to its parent page if it's the last page in its section, and hashes don't provide a way to find a parent when they are nested. I'm thinking there might be a better data structure, but I don't know what it would be.

The other two items should be pretty straightforward. For the third one, it would be great to keep the Git commit history when the gem is extracted.

@antonfefilov
Copy link
Contributor

antonfefilov commented May 4, 2017

Just extracted TOC and pagination related code into plugin in PR #1936.

@locks locks closed this as completed Jun 25, 2017
@locks
Copy link
Contributor

locks commented Jun 25, 2017

@antonfefilov Thanks for the help ;)

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

No branches or pull requests

7 participants