estado: vigilar también los archivos de tag (H1 y título duplicado)
Salieron al ordenar la taxonomía del EN, y son los dos visibles:
1. el H1 del archivo de tag sale del campo `name`, y en el EN los siete tags
se llamaban COMO SU SLUG: /tag/military-cases/ le enseñaba
«military-cases» al lector, con el <title> correcto justo encima. El ES
enseñaba «Casos Militares». Siete páginas indexadas con un slug de titular.
2. `uap` e `investigation` tenían el MISMO meta_title — dos archivos
compitiendo en el SERP con el mismo titular.
Los nombres no se inventaron: salían del meta_title que cada tag ya tenía, o
sea de una decisión editorial que estaba en el campo equivocado. Slugs
intactos: `--name` y `--new-slug` son opciones distintas, así que las siete
URLs siguen dando 200 y no hace falta ninguna redirección.
Renombrar era IMPOSIBLE hasta esta mañana: researchowl casaba los tags por
NOMBRE, así que esto habría creado siete duplicados `-2`. Se pudo porque el
commit 3d8cba6 los pasó a resolver por slug→id.
El detector de «nombre == slug» exige un guion a propósito: `uap` llamándose
«uap» no se lee como slug crudo y marcarlo sería un falso positivo. Hay test.
Y un fallo del propio fichero de tests, encontrado al añadir estos: el bloque
`if __name__ == "__main__"` estaba en MEDIO, así que los tests definidos
después no entraban en globals() y no corrían nunca — pasaban en verde sin
ejecutarse. Movido al final.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+22
-1
@@ -123,7 +123,28 @@ def check_tags(site, cfg, posts):
|
||||
if vacios:
|
||||
out.append(f"tags SIN NINGÚN POST (archivo vacío en el sitemap): {vacios}")
|
||||
|
||||
# 3. Posts sin categoría. Incluye los PROGRAMADOS a propósito: los 9 de
|
||||
# 3. El nombre del tag es lo que el TEMA pinta como H1 del archivo. En el EN
|
||||
# los siete se llamaban como su slug, así que /tag/military-cases/ le
|
||||
# enseñaba «military-cases» al lector (el ES enseñaba «Casos Militares»).
|
||||
# Un slug crudo de H1 en una página indexada es un fallo visible.
|
||||
feos = sorted(t["slug"] for t in publicos
|
||||
if (t.get("name") or "") == t["slug"] and "-" in t["slug"])
|
||||
if feos:
|
||||
out.append(f"tags cuyo NOMBRE es el slug (sale de H1 en el archivo): {feos}")
|
||||
|
||||
# 4. Dos archivos de tag con el MISMO <title> compiten entre ellos en el
|
||||
# SERP. Salió al renombrar: `uap` e `investigation` tenían los dos
|
||||
# «UAP Investigation — The Exclusion Zone».
|
||||
por_meta = {}
|
||||
for t in publicos:
|
||||
mt = (t.get("meta_title") or "").strip()
|
||||
if mt:
|
||||
por_meta.setdefault(mt, []).append(t["slug"])
|
||||
for mt, v in sorted(por_meta.items()):
|
||||
if len(v) > 1:
|
||||
out.append(f"mismo <title> en {sorted(v)}: «{mt[:52]}»")
|
||||
|
||||
# 5. Posts sin categoría. Incluye los PROGRAMADOS a propósito: los 9 de
|
||||
# agosto salían sin ninguna y se habrían publicado así.
|
||||
for estado in ("published", "scheduled"):
|
||||
sin = sorted(p["slug"] for p in posts if p.get("status") == estado
|
||||
|
||||
@@ -140,6 +140,59 @@ def test_las_reglas_de_post_que_no_aplican_a_paginas_quedan_fuera():
|
||||
assert not E._fuera_de_paginas(regla), regla
|
||||
|
||||
|
||||
|
||||
# ───────── archivos de tag: lo que el lector ve y lo que ve Google ─────────
|
||||
|
||||
def test_detecta_el_nombre_de_tag_que_es_el_slug():
|
||||
"""El H1 del archivo sale del `name`. En el EN los siete se llamaban como
|
||||
su slug: /tag/military-cases/ enseñaba «military-cases» al lector."""
|
||||
orig = E.sh
|
||||
E.sh = _tags_falsos([
|
||||
{"slug": "military-cases", "name": "military-cases", "visibility": "public"},
|
||||
])
|
||||
try:
|
||||
salida = E.check_tags("en", E.SITES["en"], [
|
||||
{"slug": "p", "status": "published",
|
||||
"tags": [{"slug": "military-cases", "visibility": "public"}]}])
|
||||
finally:
|
||||
E.sh = orig
|
||||
assert any("NOMBRE es el slug" in l for l in salida), salida
|
||||
|
||||
|
||||
def test_un_acronimo_de_una_palabra_no_cuenta_como_slug_crudo():
|
||||
"""`uap` llamándose «uap» no es el mismo problema que «military-cases»:
|
||||
sin guion no se lee como slug. Exigir el guion evita el falso positivo."""
|
||||
orig = E.sh
|
||||
E.sh = _tags_falsos([{"slug": "uap", "name": "uap", "visibility": "public"}])
|
||||
try:
|
||||
salida = E.check_tags("en", E.SITES["en"], [
|
||||
{"slug": "p", "status": "published",
|
||||
"tags": [{"slug": "uap", "visibility": "public"}]}])
|
||||
finally:
|
||||
E.sh = orig
|
||||
assert not any("NOMBRE es el slug" in l for l in salida), salida
|
||||
|
||||
|
||||
def test_detecta_dos_archivos_de_tag_con_el_mismo_title():
|
||||
"""Salió al renombrar: `uap` e `investigation` compartían meta_title, o sea
|
||||
dos páginas indexadas compitiendo con el mismo titular."""
|
||||
orig = E.sh
|
||||
E.sh = _tags_falsos([
|
||||
{"slug": "uap", "name": "UAP", "visibility": "public",
|
||||
"meta_title": "UAP Investigation — The Exclusion Zone"},
|
||||
{"slug": "investigation", "name": "Investigation", "visibility": "public",
|
||||
"meta_title": "UAP Investigation — The Exclusion Zone"},
|
||||
])
|
||||
try:
|
||||
salida = E.check_tags("en", E.SITES["en"], [
|
||||
{"slug": "p", "status": "published", "tags": [
|
||||
{"slug": "uap", "visibility": "public"},
|
||||
{"slug": "investigation", "visibility": "public"}]}])
|
||||
finally:
|
||||
E.sh = orig
|
||||
assert any("mismo <title>" in l for l in salida), salida
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fallos = 0
|
||||
for nombre, fn in sorted(globals().items()):
|
||||
|
||||
Reference in New Issue
Block a user