On this page
Answering whether every reference a build emitted -- links, canonicals, sitemap entries, feed links -- resolves to a file the build itself actually wrote.
#internal/resolution
#internal/resolution
Package resolution answers whether every reference a build emitted resolves to a file it wrote.
The build derives every address from the address package, and the test suite walks a built tree asserting that each emitted reference lands on an emitted file. This package is that assertion as a user-facing check: one lint code, LINK001, over the output directory.
Five kinds of reference are covered, which is every kind the build emits:
- document-relative href/src attributes in the pages themselves, - the absolute rel="canonical" link on each page, - the absolute data-share-url addresses the share control offers, - the
The last four are absolute URLs, so they are checked against the site's configured base: an absolute URL that points into this site must name a page this build wrote, and one that points elsewhere is not ours to verify. A share address is a reference like any other -- it is handed to a reader to open -- so a control that offers an address the build did not write fails here rather than 404ing for whoever it was shared with.
#Two rules that are not about existence
A reference that decides where a CLICK goes -- an -- must be document-relative, so neither of these is allowed:
- /blog/hello/, origin-absolute, which resolves only when the site is served from an origin root and names nothing under a mount; - https://
Absolute is right for metadata, which says where a page lives in the world: the canonical, the share addresses, sitemap entries and feed links, all checked above and none of them somewhere a click goes.
#LintCode
const LintCode = "LINK001"LintCode is the lint code every unresolvable reference is reported under.
#Reference
type Reference structReference is one internal reference a page writes: the attribute that carried it and the reference itself, unescaped.
#ReferenceTarget
func ReferenceTarget(pageRel, ref string) (string, bool)ReferenceTarget resolves ref, written on the page at pageRel, to an output path.
The second result is false when the reference addresses nothing on its own: an empty value, or a bare fragment.
#SiteRelativePath
func SiteRelativePath(url, baseURL string) (string, bool)SiteRelativePath is the output-relative path an absolute url names.
The second result is false when the URL is not this site's -- an external link, or a URL with no base to measure it against.
#PageReferences
func PageReferences(pageHTML string) []ReferencePageReferences returns every internal reference pageHTML writes.
Internal means "addressed within this site": a fragment, an empty value and every off-site scheme are dropped, so what is left is either a document-relative reference or an origin-absolute one -- which is a defect this package reports, not a reference to follow.
#NavigationReferences
func NavigationReferences(pageHTML string) []stringNavigationReferences returns every pageHTML writes, unescaped.
These are the references a click follows, which is the set the mount-relative rule governs. Assets (src, a stylesheet link) are not here: they are fetched by the page rather than navigated to, and the assembly re-points some of them at site-level files after the graft.
#RewriteNavigationReferences
func RewriteNavigationReferences(RewriteNavigationReferences returns pageHTML with every value the rewrite function answers for replaced by what it answered.
rewrite is handed each reference as it is written in the attribute, and returns the replacement plus whether it has one; a false second result leaves the attribute exactly as it was, escaping included.
It is here, rather than beside its caller, so that the repair a tree gets and the rule this package enforces read the same elements: an is what a reader clicks, and anything that rewrites those has to recognise them the way the check does or the two drift apart.
#ExternalReferences
func ExternalReferences(pageHTML string) []stringExternalReferences returns every absolute http(s) URL pageHTML references.
This is the other half of PageReferences: what this package cannot verify against the emitted tree, because it names somebody else's server. Whether those still answer is the outbound check's question.
Origin-only resource hints are not references in that sense and are dropped before the scan -- see originOnlyRels.
#CheckOutputResolution
func CheckOutputResolution(CheckOutputResolution checks every emitted reference in outputDir against what the build wrote, returning one LintCode diagnostic per unresolvable reference.
exemptElements names the elements whose content this build does not answer for: a region written from an assembled site's own data addresses that site, which the project carrying the region never writes, and the assembly's pass over the whole tree is the only place those references can be resolved.
outputDir is the build output directory; a directory that holds no HTML is not a built site and yields no diagnostics. baseURL is the site's configured base URL, used to tell this site's absolute URLs (canonicals, sitemap entries, feed links) from everyone else's.
mountPrefix is the path segments the site serves this output under ("alpha/"), empty when the output root is the served root. A mounted build's output is one subtree of a site it cannot see: its pages address the site level by climbing out of the output root, and its posts are grafted OUT of the subtree to the site root, so neither side's references resolve within this directory. Those are left to the assembly's own pass over the whole tree, which is the only place they can be answered. What still applies here applies everywhere: no reference a reader clicks may be origin-absolute or absolute against the site's base.