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 absolute links to external sites in pages section of mkdocs.yml #989

Closed
nicksnyder opened this issue Jul 4, 2016 · 18 comments
Closed

Allow absolute links to external sites in pages section of mkdocs.yml #989

nicksnyder opened this issue Jul 4, 2016 · 18 comments
Milestone

Comments

@nicksnyder
Copy link

@nicksnyder nicksnyder commented Jul 4, 2016

e.g. mkdocs.yml

site_name: MyCoolSite

pages:
- Home: index.md
- Guide:
  - Know this: know-this.md
  - Other info: "http://www.otherinfo.com"

Currently build_pages in build.py fails

DEBUG   -  Building page http:/www.google.com 
ERROR   -  file not found: /Users/nsnyder/code/linkedin/layoutkit-opensource/docs/http:/www.google.com 
ERROR   -  Error building page http:/www.google.com 

It would be easy to skip the call to _build_pages if the value starts with http but also need to generate the correct absolute link in the nav. Happy to work on this if you agree.

If so, can you point me to the correct place for generating the link?

@waylan
Copy link
Member

@waylan waylan commented Jul 4, 2016

No, this is currently not possible. A few similar requests (#797 and #575) have been punted to the upcoming Plugin API (#206).

However, thinking about this, any such plugin would need to know where in the pages structure the new nav item would need to go. We could just say "add it within the plugin," but with multiple levels of nesting, that really limits what users can do. Either the plugin needs to know the structure of the pages and step through until it guesses the right location, or the plugin would just tack any new nav items on the end at the root level only. In other words, it's either really complex or extremely simple and limited. Perhaps we need to have some native support for a placeholder of some kind. Not really sure what that would look like though. Maybe a title with no data is understood to be a placeholder and just ignored. Then a plugin can use that placeholder as it sees fit (link to generated content, or an external resource, or ...).

Loading

@nicksnyder
Copy link
Author

@nicksnyder nicksnyder commented Jul 5, 2016

Perhaps a plugin could register a handler for values.

Something like this? (warning, I haven't written Python in a while so read this like pseudocode).

for page in site_navigation.walk_pages():
        try:
            log.debug("Building page %s", page.input_path)
            for plugin in page_handler_plugins:
                if plugin.can_handle_page(page):
                    build_result = plugin.handle_page(page)
                    break

            if !build_result:
                build_result = _build_page(page, config, site_navigation, env, dump_json)

            html_content, table_of_contents, _ = build_result
            search_index.add_entry_from_context(
                page, html_content, table_of_contents)
        except Exception:
            log.error("Error building page %s", page.input_path)
            raise

In the meantime, it is easy to me to just create a dummy markdown page that does a redirect using a meta refresh tag.

Loading

@erichgoldman
Copy link

@erichgoldman erichgoldman commented Dec 15, 2016

Would it be possible as a quick fix to just customize the theme where the menu is created with the static link? It would be nice to make this modified easily, but it should be possible to just add another menu item if its going to be just one hardcoded value in a given project.

e.g., hard code in a <li /> under <ul class="nav navbar-nav"> in the theme

Loading

@waylan
Copy link
Member

@waylan waylan commented Jan 20, 2017

@erichgoldman yes that would be an alternate solution for some edge cases (especially with the new theme customization), but that won't address the needs of people who want their links embedded into the structure of the nav.

I suppose, if a user just wants to tack a link on the beginning or end of the nav, that would be easy enough through theme customization. That would also be easy enough to address with a simple Plugin. But if we want to support the ability to have external links anywhere in the nav, then we need to provide something built-in so that the user can define those links within the pages config setting. So I guess the question is, how complex of feature do we want to create? If we keep it simple (add to beginning or end) then we don't need to do anything (except maybe finish the Plugin API), but I can see the elegance of being able to just insert external links right in the pages config.

Loading

@erichgoldman
Copy link

@erichgoldman erichgoldman commented Jan 20, 2017

Agree, the plugin solution is the best longer term solution.

My proposal is as a short term / bridge solution for other users who search, come here, and want a solution today.

Loading

@waylan
Copy link
Member

@waylan waylan commented Jan 20, 2017

Hmm, I just went back and reread this entire thread and I was reminded that we have two separate use cases for adding non-page items to the nav:

  1. Link to an external site. This is easy, just check the config for a URL that starts with http(s):// and insert a external link object in the nav but leave out of page.next/previous.

  2. Link to some local HTML content (whether generated by a third party tool or hand-crafted). Maybe we check that the relative URL ends with .html? Inserting an appropriate object in the nav is easy enough once we identify the type of page, but do we include these pages in the page.next/previous or not? I'm thinking not as there would be no way to add next/previous links to the pages themselves. Or should the pages be treated as templates and run through the template engine?.

    And then what do we do with an entire collection of pages (perhaps generated by a third party tool)? Require every page to be listed in the nav or just point to the dir? If we point to the dir, then next/previous is out I think. If an item in the pages config points to a directory, just create a nav item and that's it.

Loading

@StephenTaylor-Kx
Copy link

@StephenTaylor-Kx StephenTaylor-Kx commented Jan 31, 2017

I have both use cases but support implementing only use case #1.

For use case #2 I have a substantial subsite (also MkDocs as it happens) whose content I have chosen not to integrate into the main site. Implementing for #2 would be cute, but a subsite is a subsite, a little separation does no harm, is arguably better.

Parent site: kx.com
Main site: code.kx.com
Subsite: code.kx.com/q4m3

Big fan of simplicity. Use case #1 looks easy to implement and understand. And would let me link straight from the nav to both parent and subsite. Do only that and assess later whether there’s a case for doing more.

Loading

@waylan
Copy link
Member

@waylan waylan commented Jan 31, 2017

Perhaps it would help to remember that a common request is for people to be able to host their generated documentation (from the source code) for a project as a subsection of their prose documentation (using MkDocs). They expect to be able to run their tool of choice, which generates their documentation in a subdirectory of their docs_dir and then run MkDocs which would copy and integrate that documentation into the MkDocs site. In fact, this was the primary use case I had in mind for option 2 above.

In the end, it probably makes more sense for that type of integration to be left to a plugin. But in that case, how do users tell the plugin where to insert an item into the nav? That is the problem I am trying to solve here. Links to an outside resource are easy, it's the internal links which are less clear. Yes we could require the internal links to be "external" also, but that doesn't feel very clean to me.

Loading

@waylan
Copy link
Member

@waylan waylan commented Jan 31, 2017

One possibility I have thought of but am unsure about is adding support for some kind of "placeholder". Then a plugin could search for a placeholder with a given name and replace it with an actual nav item. Presumably any placheolders left in the nav would be skipped/ignored by the template. What that placeholder looks like and how it is given a unique name is not clear though. Just throwing the idea out there.

Loading

@joseluisq
Copy link

@joseluisq joseluisq commented Oct 20, 2017

Cool!
Any progress on this feature ?

Loading

@yannduran
Copy link

@yannduran yannduran commented Jan 27, 2018

I'm also hoping that @waylan's #1 scenario will be easy to implement (hopefully soon :-))

Loading

@tomaszalusky
Copy link

@tomaszalusky tomaszalusky commented Feb 23, 2018

I had the same problem and found this thread. The simplest workaround I could think up is - in your pages.yml:

  • in pages:... section, compose link title as actual title|href (I found handy to mark external links with 🗗 Unicode character), for example - 'Google &#x1F5D7|http://www.google.com/': 'index.md'
    (just pretend it's local file, it only must be existing md)
  • in extra_javascript:... section, declare file with following code:
var anchors = Array.from(document.getElementsByClassName("navbar-collapse")[0].getElementsByTagName("a"));
anchors.forEach(function(anchor) {
	var sep = anchor.innerText.indexOf("|");
	if (sep != -1) {
		anchor.href = anchor.innerText.substring(sep + 1, anchor.innerText.length);
		anchor.innerText = anchor.innerText.substring(0,sep);
	}
	if (anchor.innerText.indexOf("\uD83D\uDDD7") != -1) { // &#x1F5D7; = "new window" char, see http://www.fileformat.info/info/unicode/char/1f5d7/index.htm
		anchor.target = "_blank";
	}
}); 

Loading

@ghost
Copy link

@ghost ghost commented May 15, 2018

This probably isn't the best solution, but I just use a redirect template.

https://github.com/lramage94/lramage94.github.io/blob/master/_layouts/redirect.html

It works with any static site generator (for that site I'm using jekyll).

Loading

@waylan waylan moved this from To do to In progress in Pages Refactor Jun 3, 2018
@waylan waylan mentioned this issue Jun 8, 2018
@Kikju
Copy link

@Kikju Kikju commented Jun 27, 2018

Hello,
I edited @tomaszalusky's code to work properly for all browsers.

var anchors = document.getElementsByClassName("md-nav__list")[0].getElementsByTagName("a");
for (i = 0; i < anchors.length; i++) {
    var anchor = anchors[i];
    var sep = anchor.title.indexOf("|");
	if (sep != -1) {
		var href = anchor.title.substring(sep + 1, anchor.title.length);
		anchor.href = anchor.title.substring(0, sep);
		anchor.title = title;
		anchor.innerText = title;
	}
	if (anchor.innerText.indexOf("\uD83D\uDDD7") != -1) { // &#x1F5D7; = "new window" char, see http://www.fileformat.info/info/unicode/char/1f5d7/index.htm
		anchor.target = "_blank";
    }
}

Loading

@waylan waylan closed this in 34ef3ca Jun 28, 2018
Pages Refactor automation moved this from In progress to Done Jun 28, 2018
@sstone2423
Copy link

@sstone2423 sstone2423 commented Jul 3, 2018

I edited it to meet my needs. Thanks for the fix!

var anchors = Array.from(document.getElementsByClassName("wy-menu")[0].getElementsByTagName("a"));
anchors.forEach(function(anchor) {
  var sep = anchor.innerText.indexOf("|");
  if (sep != -1) {
    anchor.href = anchor.innerText.substring(sep + 1, anchor.innerText.length);
    anchor.innerText = anchor.innerText.substring(0, sep);
  }
});

Also, this helped me as well if anyone is linking back to a single home page. This will change the top Docs link from site/index to your home page

var homeLink = document.getElementsByClassName("icon-home")[0];
homeLink.href = "https://example.io";
homeLink.innerText = "Home Page";

Loading

@waylan
Copy link
Member

@waylan waylan commented Jul 3, 2018

FYI, this feature will be officially supported without hacks in the next release (1.0). See #1504 for more info.

Loading

@csandanov
Copy link

@csandanov csandanov commented Aug 31, 2018

I'm on 1.0.3 and external links under nav: (pages in older versions) don't work for me.

Loading

@froschdesign
Copy link

@froschdesign froschdesign commented Aug 31, 2018

@csandanov
You should open a separate issue report and add the content from your mkdocs.yml file.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Linked pull requests

Successfully merging a pull request may close this issue.

None yet