Skip to content

Walk Markdown Directory to Generate Nested Navigation Tree #2

Open
@GeorgeBerdovskiy

Description

@GeorgeBerdovskiy

Background

Right now, we only have one level of pages on our documentation site. In other words, there are no subpages or nested pages. For better organization, we'd like to add them! You can find nested pages on many documentation sites, such as the Next.JS docs (here).

Screen Shot 2024-03-10 at 2 45 23 PM Screen Shot 2024-03-10 at 2 45 58 PM

As you can see in the above screenshots, there is a "Routing" page, but there are also many pages associated with "Routing" that appear below, such as "Defining Routes."

Goal

We want to add nested pages to the PureChart documentation site (here). However, this issue doesn't involve any HTML/CSS, but rather the generation of a nested "navigation tree" that we can use to generate the HTML/CSS later (issue #1 creates the nested buttons and another issue will combine these two together).

Screen Shot 2024-03-10 at 2 48 28 PM

Guidance

Take a look at the app folder of this repository - you should find a markdown folder with several Markdown files. When a user presses one of the navigation buttons, a request is sent to the controller to display the corresponding page. It does this by matching the route name to the Markdown file name, parsing its contents into HTML, and then displaying that HTML. The code that achieves this is in app/controllers/articles_controller.rb -

...
def open_article
    title = Rails.root.to_s + "/app/markdown/" + params[:title] + ".md"
    @content = markdown(File.read(title))
end
...

To support nested navigation, we'll need to adjust the way files are stored. Instead of storing each page as its own .md file, every page should be a folder with at least an index.md inside, and possibly other folders inside for subpages.

app/markdown
├── chart-styling
│   └── index.md
├── contribution
│   └── index.md
├── getting-started
│   └── index.md
└── types-of-charts
    ├── bar-chart
    │   └── index.md
    ├── index.md
    └── pie-chart
        └── index.md

Your updated controller code may look something like this. Ignore the excessive puts calls - those are for some rough debugging to confirm our code is correct.

...
def index
  @parent_path = request.path
  puts "PATH = " + @parent_path
  puts File.basename(Dir.getwd)
  @nav_tree = walk("./app/markdown", "")
  puts @nav_tree
end

def titleize(name)
  lowercase_words = %w{a an the and but or for nor of}
  name.split.each_with_index.map{|x, index| lowercase_words.include?(x) && index > 0 ? x : x.capitalize }.join(" ")
end

def walk(start, parent)
  temp_hash = {}

  Dir.foreach(start) do |x|
    path = File.join(start, x)
    if x == "." or x == ".."
      next
    elsif File.directory?(path)
      # puts path + "/" # remove this line if you want; just prints directories
      name = titleize(x.gsub('-', ' '))
      temp_hash[name] = walk(path, x)
    else
      # Convert path to name
      name = titleize(x[0..-4].gsub('-', ' '))

      temp_hash[name] = parent + '_' + x[0..-4]

      if parent == ""
        temp_hash[name] = name
      end
    end
  end

  temp_hash
end

def open_article
  title = Rails.root.to_s + "/app/markdown/" + params[:title].gsub('_', '/') + "/index.md"
  @content = markdown(File.read(title))
end
...

This results in a "navigation tree" that sort of looks like this...

{
  "Chart Styling" => {
    "Index" => "chart-styling_index"
  },
  "Getting Started" => {
    "Index" => "getting-started_index"
  },
  "Contribution" => {
    "Index" => "contribution_index"
  },
  "Types of Charts" => {
    "Pie Chart" => {
      "Index" => "pie-chart_index"
    },
    "Bar Chart" => {
      "Index" => "bar-chart_index"
    },
    "Index" => "types-of-charts_index"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    BeginnerFor beginners 🐣ClaimedSomeone has claimed this issue ✋FeatureNew feature 💡StandaloneDoesn't depend on other issues 💪

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions