Derive a link's page region from its DOM path
Source:R/screaming_frog_contract.R
sf_region_from_path.RdReads the page region a link sits in out of Screaming Frog's
Link Path (an XPath-like source locator), returning the same compact
vocabulary as sf_normalize_position(). This is the preferred
source of placement, because Link Position loses the enclosing
region whenever a <nav> is nested inside one.
Value
A character vector the same length as x containing
"nav", "header", "footer", "aside", or
"content". Blank strings and NA yield NA, so a caller
can fall back to sf_normalize_position().
Details
The region is the **outermost** layout container on the path —
header, footer, or aside — and "nav" applies
only when the link sits in a <nav> that is not inside one of those.
So a footer nav resolves to "footer", a header nav to
"header", and a standalone nav to "nav". Anything else is
"content", which is an acknowledged residual bucket rather than a
positive claim about the markup.
Why not just read Link Position? On a site whose footer is marked up
as footer > nav > a, Screaming Frog reports every footer link as
Navigation and emits no Footer bucket at all, so footer
is not merely mislabeled but unreachable — a user wanting footer at 0.05
and nav at 0.2 has no way to express it. Other sites do emit Footer,
so the vocabulary silently varies with the site's markup. The DOM path has
the region unambiguously in both cases.
Element names are matched on their own: predicates are stripped first, so a
div[@class='site-footer'] is not read as a footer. Only real
<footer> elements are.
See also
[pagerank()], whose `placement_col` consumes the result.
Other Screaming Frog toolkit:
sf_container_from_path(),
sf_contract(),
sf_graph_eligible(),
sf_normalize_position(),
sf_parse_follow(),
sf_read_input(),
sf_rel_nofollow()
Examples
sf_region_from_path(c(
"//body/footer/nav/ul/li[1]/a", # footer nav -> footer, not nav
"//body/header/nav/ul/li[2]/a", # header nav -> header
"//body/nav/ul/li[1]/a", # standalone nav -> nav
"//body/main/article/p[5]/a[1]", # -> content
"//body/div[@class='site-footer']/a" # a class is not an element
))
#> [1] "footer" "header" "nav" "content" "content"