-
Couldn't load subscription status.
- Fork 152
GitHub edit link tag #108
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
GitHub edit link tag #108
Changes from all commits
bf1a19a
b706e31
37eddf4
787313c
3e2f1f0
c93ee73
cf4a784
d84aeef
7273bcc
59bb641
c66124c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # GitHub Metadata, a.k.a. `site.github` | ||
|
|
||
| [](https://travis-ci.org/jekyll/github-metadata) | ||
|
|
||
| Jekyll plugin to propagate the `site.github` namespace and set default values for use with GitHub Pages. | ||
|
|
||
| ## What it does | ||
|
|
||
| * Propagates the `site.github` namespace with [repository metadata](https://help.github.com/articles/repository-metadata-on-github-pages/) | ||
| * Sets `site.title` as the repository name, if none is set | ||
| * Sets `site.description` as the repository tagline if none is set | ||
| * Sets `site.url` as the GitHub Pages domain (cname or user domain), if none is set | ||
| * Sets `site.baseurl` as the project name for project pages if none is set | ||
|
|
||
| ## Usage | ||
|
|
||
| Usage of this gem is pretty straight-forward. Add it to your bundle like this: | ||
|
|
||
| ```ruby | ||
| gem 'jekyll-github-metadata' | ||
| ``` | ||
|
|
||
| Now add it to your `_config.yml`: | ||
|
|
||
| ```yaml | ||
| gems: | ||
| - jekyll-github-metadata | ||
| ``` | ||
|
|
||
| Then go ahead and run `bundle install`. Once you've done that jekyll-github-metadata will run when you run Jekyll. | ||
|
|
||
|
|
||
| ## Further reading | ||
|
|
||
| * [Authentication](authentication.md) | ||
| * [Configuration](configuration.md) | ||
| * [Edit on GitHub link](edit-on-github-link.md) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| permalink: pretty | ||
| title: GitHub Metadata |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| ## Authentication | ||
|
|
||
| For some fields, like `cname`, you need to authenticate yourself. Luckily it's pretty easy. First, you need to generate a personal access token (an oauth token will work too but it's good to have a token for each purpose so you can revoke them later without breaking everything): | ||
|
|
||
| To generate a new personal access token on GitHub.com: | ||
|
|
||
| - Open https://github.com/settings/tokens/new | ||
| - Select the scope *public_repository*, and add a description. | ||
| - Confirm and save the settings. Copy the token you see on the page. | ||
|
|
||
| Once you have your token, you have three ways to pass it to this program: | ||
|
|
||
| ### 1. `JEKYLL_GITHUB_TOKEN` | ||
|
|
||
| These tokens are easy to use and delete so if you move around from machine-to-machine, we'd recommend this route. Set `JEKYLL_GITHUB_TOKEN` to your access token (with `public_repo` scope for public repositories or `repo` scope for private repositories) when you run `jekyll`, like this: | ||
|
|
||
| ```bash | ||
| $ JEKYLL_GITHUB_TOKEN=123abc [bundle exec] jekyll serve | ||
| ``` | ||
|
|
||
| ### 2. `~/.netrc` | ||
|
|
||
| If you prefer to use the good ol' `~/.netrc` file, just make sure the `netrc` gem is bundled and run `jekyll` like normal. So if I were to add it, I'd add `gem 'netrc'` to my `Gemfile`, run `bundle install`, then run `bundle exec jekyll build`. The `machine` directive should be `api.github.com`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I should include an example... |
||
|
|
||
| ```netrc | ||
| machine api.github.com | ||
| login github-username | ||
| password 123abc-your-token | ||
| ``` | ||
|
|
||
| ### 3. Octokit | ||
|
|
||
| We use [Octokit](https://github.com/octokit/octokit.rb) to make the appropriate API responses to fetch the metadata. You may set `OCTOKIT_ACCESS_TOKEN` and it will be used to access GitHub's API. | ||
|
|
||
| ```bash | ||
| $ OCTOKIT_ACCESS_TOKEN=123abc [bundle exec] jekyll serve | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| ## Edit on GitHub link | ||
|
|
||
| The plugin also makes a tag available that generates links to edit the current page on GitHub. | ||
|
|
||
| ### To generate a link | ||
|
|
||
| ```liquid | ||
| <p>This site is open source. {% github_edit_link "Improve this page" %}</p> | ||
| ``` | ||
|
|
||
| Produces: | ||
|
|
||
| ```html | ||
| <p>This site is open source. <a href="https://github.com/benbalter/jekyll-edit-link/edit/master/README.md">Improve this page</a></p> | ||
| ``` | ||
|
|
||
| ### To generate a path | ||
|
|
||
| If you'd prefer to build your own link, simply don't pass link text | ||
|
|
||
| ```liquid | ||
| <p>This site is open source. <a href="{% github_edit_link %}">Improve this page</a></p> | ||
| ``` | ||
|
|
||
| Produces: | ||
|
|
||
|
|
||
| ```html | ||
| <p>This site is open source. <a href="https://github.com/benbalter/jekyll-edit-link/edit/master/README.md">Improve this page</a></p> | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| module Jekyll | ||
| module GitHubMetadata | ||
| class EditLinkTag < Liquid::Tag | ||
| attr_reader :context | ||
|
|
||
| # Defines an instance method that delegates to a hash's key | ||
| # | ||
| # hash_method - a symbol representing the instance method to delegate to. The | ||
| # instance method should return a hash or respond to #[] | ||
| # key - the key to call within the hash | ||
| # method - (optional) the instance method the key should be aliased to. | ||
| # If not specified, defaults to the hash key | ||
| # default - (optional) value to return if value is nil (defaults to nil) | ||
| # | ||
| # Returns a symbol representing the instance method | ||
| def self.def_hash_delegator(hash_method, key, method, default = nil) | ||
| define_method(method) do | ||
| hash = send(hash_method) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we did, we'd have to make |
||
| if hash.respond_to? :[] | ||
| hash[key.to_s] || default | ||
| else | ||
| default | ||
| end | ||
| end | ||
| end | ||
|
|
||
| MISSING_DATA_MSG = "Cannot generate edit URLs due to missing site.github data".freeze | ||
| LINK_TEXT_REGEX = %r!(?:\"(.*)\"|'(.*)')! | ||
|
|
||
| extend Forwardable | ||
| private def_hash_delegator :site, :github, :site_github, {} | ||
| private def_hash_delegator :site_github, :repository_url, :repository_url | ||
| private def_hash_delegator :site_github, :source, :source, {} | ||
| private def_hash_delegator :source, :branch, :branch | ||
| private def_hash_delegator :source, :path, :source_path | ||
| private def_delegator :page, :path, :page_path | ||
|
|
||
| def render(context) | ||
| @context = context | ||
| if link_text | ||
| link | ||
| else | ||
| uri.to_s | ||
| end | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def link_text | ||
| @link_text ||= begin | ||
| matches = @markup.match LINK_TEXT_REGEX | ||
| matches[1] || matches[2] if matches | ||
| end | ||
| end | ||
|
|
||
| def link | ||
| "<a href=\"#{uri}\">#{link_text}</a>" | ||
| end | ||
|
|
||
| def uri | ||
| if parts.any?(&:nil?) | ||
| Jekyll.logger.warn "JekyllEditLink: ", MISSING_DATA_MSG | ||
| "" | ||
| else | ||
| Addressable::URI.join(*parts_normalized).normalize | ||
| end | ||
| end | ||
|
|
||
| def parts | ||
| @parts ||= [repository_url, "edit/", branch, source_path, page_path] | ||
| end | ||
|
|
||
| def parts_normalized | ||
| @parts_normalized ||= parts.map.with_index do |part, index| | ||
| part = remove_leading_slash(part.to_s) | ||
| part = ensure_trailing_slash(part) unless index == parts.length - 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the url is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you leave a comment in the code to that effect or give it a tiny helper method which explains that? |
||
| ensure_not_just_a_slash(part) | ||
| end | ||
| end | ||
|
|
||
| def page | ||
| @page ||= context.registers[:page] | ||
| end | ||
|
|
||
| def site | ||
| @site ||= context.registers[:site].site_payload["site"] | ||
| end | ||
|
|
||
| def remove_leading_slash(part) | ||
| part.start_with?("/") ? part[1..-1] : part | ||
| end | ||
|
|
||
| def ensure_trailing_slash(part) | ||
| part.end_with?("/") ? part : "#{part}/" | ||
| end | ||
|
|
||
| def ensure_not_just_a_slash(part) | ||
| part == "/" ? "" : part | ||
| end | ||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works if you're generating for a public repo – but private repos get this information too. Should we add a disclaimer?