Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
6 changes: 3 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Metrics/LineLength:
Metrics/BlockLength:
Exclude:
- spec/**/*

Metrics/MethodLength:
Exclude:
- spec/**/
Exclude:
- spec/**/*
37 changes: 37 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# GitHub Metadata, a.k.a. `site.github`

[![Build Status](https://travis-ci.org/jekyll/github-metadata.svg?branch=test-site)](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)
2 changes: 2 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
permalink: pretty
title: GitHub Metadata
37 changes: 37 additions & 0 deletions docs/authentication.md
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.
Copy link
Member

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?

- 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`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should include an example...

machine api.github.com
    login github-username
    password 123abc-your-token


```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
```
63 changes: 3 additions & 60 deletions README.md → docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,4 @@
github-metadata, a.k.a. `site.github`
=====================================

[![Build Status](https://travis-ci.org/jekyll/github-metadata.svg?branch=test-site)](https://travis-ci.org/jekyll/github-metadata)

Access `site.github` metadata anywhere (...you have an internet connection).

## 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.
## Configuration

In order for jekyll-github-metadata to know what metadata to fetch it must
be able to determine the repository NWO (name with owner, e.g. `jekyll/jekyll-github-metadata`) to ask GitHub about.
Expand Down Expand Up @@ -50,38 +29,6 @@ Your `site.github.*` fields should fill in like normal. If you run Jekyll
with the `--verbose` flag, you should be able to see all the API calls
made.

## 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) 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`.

### 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
```

## Overrides

- `PAGES_REPO_NWO` – overrides `site.repository` as the repo name with owner to fetch (e.g. `jekyll/github-metadata`)
Expand All @@ -94,17 +41,13 @@ Some `site.github` values can be overridden by environment variables.
- `PAGES_HELP_URL` – the `site.github.help_url` (default: `https://help.github.com`)
- `PAGES_GITHUB_HOSTNAME` – the `site.github.hostname` (default: `https://github.com`)
- `PAGES_PAGES_HOSTNAME` – the `site.github.pages_hostname` (default: `github.io`)
- `NO_NETRC` – set if you don't want the fallback to `~/.netrc`

## Configuration
## Using with GitHub Enterprise

Working with `jekyll-github-metadata` and GitHub Enterprise? No sweat. You can configure which API endpoints this plugin will hit to fetch data.

- `SSL` – if "true", sets a number of endpoints to use `https://`, default: `"false"`
- `OCTOKIT_API_ENDPOINT` – the full hostname and protocol for the api, default: `https://api.github.com`
- `OCTOKIT_WEB_ENDPOINT` – the full hostname and protocol for the website, default: `https://github.com`
- `PAGES_PAGES_HOSTNAME` – the full hostname from where GitHub Pages sites are served, default: `github.io`.
- `NO_NETRC` – set if you don't want the fallback to `~/.netrc`

## License

MIT License, credit to GitHub, Inc. See [LICENSE](LICENSE) for more details.
30 changes: 30 additions & 0 deletions docs/edit-on-github-link.md
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>
```
4 changes: 4 additions & 0 deletions lib/jekyll-github-metadata.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "octokit"
require "liquid"
require "logger"

if defined?(Jekyll) && Jekyll.respond_to?(:env) && Jekyll.env == "development"
Expand All @@ -19,6 +20,7 @@ module Errors

module GitHubMetadata
autoload :Client, "jekyll-github-metadata/client"
autoload :EditLinkTag, "jekyll-github-metadata/edit-link-tag"
autoload :MetadataDrop, "jekyll-github-metadata/metadata_drop"
autoload :Pages, "jekyll-github-metadata/pages"
autoload :Repository, "jekyll-github-metadata/repository"
Expand Down Expand Up @@ -83,3 +85,5 @@ def reset!
end
end
end

Liquid::Template.register_tag("github_edit_link", Jekyll::GitHubMetadata::EditLinkTag)
102 changes: 102 additions & 0 deletions lib/jekyll-github-metadata/edit-link-tag.rb
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use public_send here instead of send?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we did, we'd have to make site, site_github, source, and page public.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this unless mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the url is https://github.com/foo/bar/edit/master/page.md, we don't want the last element page.md to be given a trailing slash (and can't rely on the extension, because the repo might be, foo.js).

Copy link
Member

Choose a reason for hiding this comment

The 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
Loading