Provide (relative) reference funcs & shortcodes.

-   `.Ref` and `.RelRef` take a reference (the logical filename for a
    page, including extension and/or a document fragment ID) and return
    a permalink (or relative permalink) to the referenced document.

    -   If the reference is a page name (such as `about.md`), the page
        will be discovered and the permalink will be returned: `/about/`
    -   If the reference is a page name with a fragment (such as
        `about.md#who`), the page will be discovered and used to add the
        `page.UniqueID()` to the resulting fragment and permalink:
        `/about/#who:deadbeef`.
    -   If the reference is a fragment and `.*Ref` has been called from
        a `Node` or `SiteInfo`, it will be returned as is: `#who`.
    -   If the reference is a fragment and `.*Ref` has been called from
        a `Page`, it will be returned with the page’s unique ID:
        `#who:deadbeef`.

-   `.*Ref` can be called from either `Node`, `SiteInfo` (e.g.,
    `Node.Site`), `Page` objects, or `ShortcodeWithPage` objects in
    templates.

-   `.*Ref` cannot be used in content, so two shortcodes have been
    created to provide the functionality to content: `ref` and `relref`.
    These are intended to be used within markup, like `[Who]({{% ref
    about.md#who %}})` or `<a href="{{% ref about.md#who %}}">Who</a>`.

-   There are also `ref` and `relref` template functions (used to create
    the shortcodes) that expect a `Page` or `Node` object and the
    reference string (e.g., `{{ relref . "about.md" }}` or `{{
    "about.md" | ref . }}`). It actually looks for `.*Ref` as defined on
    `Node` or `Page` objects.

-   Shortcode handling had to use a *differently unique* wrapper in
    `createShortcodePlaceholder` because of the way that the `ref` and
    `relref` are intended to be used in content.
This commit is contained in:
Austin Ziegler
2014-11-24 01:15:34 -05:00
committed by spf13
parent 14bce119b6
commit 112c3c5c04
7 changed files with 183 additions and 35 deletions

View File

@@ -19,6 +19,7 @@ import (
"fmt"
"html/template"
"io"
"net/url"
"os"
"strconv"
"strings"
@@ -128,6 +129,65 @@ func (s *SiteInfo) GetParam(key string) interface{} {
return nil
}
func (s *SiteInfo) refLink(ref string, page *Page, relative bool) (string, error) {
var refUrl *url.URL
var err error
refUrl, err = url.Parse(ref)
if err != nil {
return "", err
}
var target *Page = nil
var link string = ""
if refUrl.Path != "" {
var target *Page
for _, page := range []*Page(*s.Pages) {
if page.Source.Path() == refUrl.Path || page.Source.LogicalName() == refUrl.Path {
target = page
break
}
}
if target == nil {
return "", errors.New(fmt.Sprintf("No page found with path or logical name \"%s\".\n", refUrl.Path))
}
if relative {
link, err = target.RelPermalink()
} else {
link, err = target.Permalink()
}
if err != nil {
return "", err
}
}
if refUrl.Fragment != "" {
link = link + "#" + refUrl.Fragment
if refUrl.Path != "" {
link = link + ":" + target.UniqueId()
} else if page != nil {
link = link + ":" + page.UniqueId()
}
}
return link, nil
}
func (s *SiteInfo) Ref(ref string, page *Page) (string, error) {
return s.refLink(ref, page, false)
}
func (s *SiteInfo) RelRef(ref string, page *Page) (string, error) {
return s.refLink(ref, page, true)
}
type runmode struct {
Watching bool
}