validador: un par consolidado no es una colisión, es su solución
topic_collision marcaba como colisión los dos artículos del acto de Grusch del 9 de junio, cuando el de mayo lleva canonical_url apuntando al otro desde hace semanas. Google ya sabe cuál manda y Ghost excluye al secundario del sitemap: no hay nada que arreglar, y el propio mensaje ofrecía «interlink deliberately» como salida, que es justo lo que había. Un aviso que no se puede resolver nunca es peor que no avisar, porque enseña a ignorar al validador entero — la misma razón por la que esta mañana retiramos la comprobación de reddit-intel de backup-verify. El par se salta cuando cualquiera de los dos declara canónico al otro. Si el canónico apunta a un tercero, la colisión sigue avisando: comprobado con los cuatro casos (sin canónico dispara, en las dos direcciones se calla, canónico a un tercero dispara). fetch_corpus pide ya canonical_url, que antes no traía.
This commit is contained in:
@@ -270,6 +270,19 @@ def _sig_tokens(title, slug):
|
||||
if len(t) >= 3 and t not in TOPIC_STOPWORDS and not _YEAR_RE.fullmatch(t)}
|
||||
|
||||
|
||||
def _canoniza_a(post):
|
||||
"""Slug al que este post declara canónico, o None si no declara ninguno.
|
||||
|
||||
Ghost guarda una URL completa; aquí solo interesa el último segmento, que es
|
||||
lo único comparable con el slug de otro post del mismo sitio.
|
||||
"""
|
||||
url = _s(post.get("canonical_url"))
|
||||
if not url:
|
||||
return None
|
||||
resto = url.split("?")[0].split("#")[0].rstrip("/")
|
||||
return resto.rsplit("/", 1)[-1] or None
|
||||
|
||||
|
||||
def _hook(title):
|
||||
return _s(title).split(":")[0].strip().lower()
|
||||
|
||||
@@ -290,10 +303,19 @@ def topic_collision(post, corpus):
|
||||
c_hook = _hook(post.get("title"))
|
||||
c_slug_toks = _tokens(_s(post.get("slug")).replace("-", " "))
|
||||
|
||||
c_canon = _canoniza_a(post)
|
||||
|
||||
for other in corpus:
|
||||
if other.get("id") == post.get("id"):
|
||||
continue
|
||||
o_title, o_slug = _s(other.get("title")), _s(other.get("slug"))
|
||||
# Un par consolidado NO es una colisión: es la solución a una colisión.
|
||||
# Cuando uno de los dos declara al otro como canónico, Google ya sabe
|
||||
# cuál manda y Ghost excluye al secundario del sitemap. Marcarlo sería
|
||||
# pedir que se arregle algo que está arreglado — y el aviso, al no poder
|
||||
# resolverse nunca, enseña a ignorar al validador.
|
||||
if c_canon == o_slug or _canoniza_a(other) == _s(post.get("slug")):
|
||||
continue
|
||||
o_years = _case_years(o_title, o_slug)
|
||||
o_sig = _sig_tokens(o_title, o_slug)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user