PureChart / purechart-documentation

Documentation site for PureChart built using Ruby on Rails!
https://docs.purechart.org
MIT License
4 stars 1 forks source link

Walk Markdown Directory to Generate Nested Navigation Tree #2

Open GeorgeBerdovskiy opened 7 months ago

GeorgeBerdovskiy commented 7 months ago

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"
  }
}
GeorgeBerdovskiy commented 7 months ago

Two notes -

  1. Please watch the meeting recording associated with this issue! You may have difficulty understanding some of this if you don't watch it.
  2. Although the code already does most of what it should, please don't just copy and paste it. Use this as an opportunity to be creative! Is there a better way to do this?

For example, the starter code is pretty sloppy. Is there a more idiomatic way to achieve the same result? What about "index" pages - should the title be "Index" or something else?

sohamnair commented 7 months ago

I can do this one, it’s not that complicated and is interesting

sohamnair commented 7 months ago

Could you assign me this task?

GeorgeBerdovskiy commented 7 months ago

Yepp it's all yours @sohamnair, I added the Claimed label just now!