Jak jsem převáděl stovky fotogalerií na nový web

Úkol, který vám dneska chci popsat, mi dal zabrat. Nejhorší je, že to tak složitě nevypadalo, ale nakonec to bylo pracné jak olíznutí lokte. Umíte si olíznout loket? Prý to jde nacvičit.

Tohle taky.

Fakt hodně fotogalerií na starém webu

Chystáme nový web a převádíme vybraná data ze starého na nový. Něco se dělá znovu, ale fotogalerie je potřeba prostě přenést. Jedná se o firemní reference (fotodokumentace prací z terénu).

Na stránce je v Divi builderu vytvořeno opravdu mnoho desítek fotogalerií, bohužel nemají žádnou datovou strukturu, která by šla přímo exportovat, jdou prostě za sebou v pořadí

  • nadpis,
  • popis,
  • fotky
    • odkaz na velký formát obrázku
    • obrázek v náhledovém rozměru
    • popisek fotky

Fotky jsou v různém počtu, dokonce je tam i javascriptové stránkování. Je to starý kód, takže nejsou použity značky <figure> ani jiná struktura pro celou skupinu nebo jednotlivou fotku. Takových stránek je cca šest, každá s tímto obsahem.

Fotky nelze nijak přiřadit ke článku, jsou prostě nahrané v mediální knihovně jedna za druhou, jsou si podobné jako vejce vejci. Ruční přenos by byl

  • extrémně pracný
  • nezkontrolovatelný
  • vysoce chybový

Plánovaný vzhled na novém webu

Cílem bylo vytvořit na novém webu články s nadpisem, v jeho těle se pak mají zobrazit úvodní popis, dále pak fotogalerie (bez stránkování), článek by měl být zařazený do rubriky podle typu prací, kterou fotogalerie reprezentuje. Mnohé nadpisy mají strukturu

2020 Malování na strop, Beroun

2022 Kropení zahrady v Kolíně

Tak jsem navrhl, že

  • úvodní rok převedeme na štítek do taxonomie „rok realizace“ a
  • poslední slovo nebo slovo za předložkou „v“ převedeme na štítek v taxonomii „místo„,

aby pak bylo možné filtrovat reference podle data a místa realizace. Vzniknou tak automaticky stránky s výpisem těchto referencí, které budou mít dostatek originálního obsahu a budou zajímavé jak pro čtenáře, tak pro Google. Hezké, ne?

Plánovaný postup

Napadlo mě tedy uložit stránku jako html, obsah vyčistit a importovat podle nadpisu jako jednotlivé vlastní typy článků, CPT. Ty vytvořím pomocí pluginu ACF a v tomto textu se jimi nezabývám, už jsou připravené.

Adresy obrázků necháme beze změny, protože na současném ostrém webu jsou (to nám pomůže při vytváření) a na nový web je nahrajeme, až bude vše hotové (tím zajistíme funkčnost v produkci). Čili s url článkú se nebude dělat nic, v každý okamžik se načtou správné obrázky. Ovšem náhledové obrázky budou mít jiné velikosti, tak bude lepší je nepoužívat.

Původně jsem myslel, že mi zdroják vyčistí AI, ale buď jí/mu to neumím zadat, nebo to prostě neumí. Nebyl prostor na chybu, kterou bych těžko hledal, takže jsem nakonec na plácání s AI rezignoval a nainstaloval do VS Code doplněk pro práci s XML, který mi zásadně pomohl při editaci.

Druhý zásadní pomocník jsou regulární výrazy. Díky si, že jsem se kdysi naučil aspoň ty základy. I tak ale dalo velkou práci zdroják nepoškodit.

Vytvořil jsem si vzorovou fotogalerii pomocí Gutenbergu a její zdroják jsem použil přímo ve zdrojovém kódu.

WP All Import pracuje s XML nebo CSV, nikoliv HTML. Přejmenoval jsem soubor na xml a program jej načetl. Namapoval jsem jednotlivé prvky do nadpisu, obsahu.. ale výsledné HTML s obrázky se do výsledných článků nikdy nedostalo.

Není to totiž XML, ale HTML, že.

Import jako XML (aneb Tak snadné to nebude)

Soubor jsem tedy musel opravit na skutečné XML. Odstranit všechny HTML značky (včetně pracně přidaných značek pro galerii) a vymyslet si svoje značky (protože stejně nevím, které XML schéma bych měl použít), mi zabralo další čas.

Takže do značky <content> umisťuji samotné HTML s obrázky a na radu ChatGPT ještě vše escapuji pomocí CDATA. V editoru pluginu před importem přidávám značky pro fotogalerii Gutenbergu:

<!-- wp:gallery {"linkTo":"media","sizeSlug":"thumbnail"} -->
<figure class="wp-block-gallery has-nested-images columns-default is-cropped">

<!---- zde jsou jednotlivé obrázky jako <figure> ---->

</figure>
<!-- /wp:gallery -->

V náhledu už vidím i obrázky, zdá se, že to funguje. Spouštím import, vše vypadá dobře. Na frontendu vidím fotogalerie, jsou rozklikávací, jak jsem si zadal. Edituji článek, obsah je pouze v klasickém editoru, to chápu. Převádím na bloky.

Celá galerie mizí, zůstává jeden obrázek.

Zřejmě proto, že před ním není argument ve složených závorkách s jeho id, které neznám. Taky zatím nevím, jak takový argument vkládat při importu, když nevím, kolik obrázků (figures) vlastně importuji. Jak v rámci importu loopovat, zjistit id obrázku a použít funkci attachment_url_to_postid()? Obrázky mám vzdáleně, jejich id nezjistím…

Slepá ulička. Další pokus, tohle by nešlo.

Rozložit datově

Opouštím myšlenku na vizuální import a pokusím se dokument rozparsovat datově na titulek, popis, seznam obrázků. Jednotlivé obrázky pak uložit jako custom fields a jejich fotogalerii generovat, nikoliv importovat. Obejít tedy Gutenberg. Pokud by článek měl obsah, tyto custom fields by se nepoužily – to už bychom ošetřili v šabloně.

Jak ale rozparsovat HTML? Napsat si vlastní obsluhu v PHP, ale to nechceš. Pak jsem si vzpomněl na LibreOffice Calc, ten přece umí načítat XML do spreadsheetu. Jenže předtím musím upravit HTML a znovu z něj udělat XML, protože divy a třídy fakt nejsou XML.

Používám tedy opět regulární výrazy a řádky jako

<div class="et_pb_module et_pb_text et_pb_text_3  et_pb_text_align_left et_pb_bg_layout_light">

převádím na značky jako <item> pomocí regexp:

<div class="et_pb_module et_pb_text et_pb_text_[\w]*  et_pb_text_align_left et_pb_bg_layout_light">

Protip: Vypněte si ve VSCode automatické formátování kódu, nebo skončíte u Chocholouška. Editor samozřejmě nemá problém kód rozlomit, jen aby byl hezký, takže vám spousta dotazů nic nenajde, protože budou rozložené na x řádků. S dalším přeformátováním textu se řádky zase spojí, výraz se objeví a za chvíli nebude XML validní (tedy značky nebudou popárované).

<div class="et_pb_gallery_items et_post_gallery clearfix" data-per_page="4">

měním na <gallery>

Když měníte otevírací značku, ujistěte se předem, že poznáte její uzavírací </div>. Smazat otvírák je snadné, protože má CSS třídy – ale jak poznáte, který </div> ho ve struktuře uzavíral? Pak ho budete muset najít, aspoň podle odpočtu od konce. Také si kontrolujte, kolikrát vyměníte otevírací značky a kolikrát uzavírací – mělo by to samozřejmě sedět.

Pak načítám XML do Calcu a vidím sloupce podle jednotlivých značek, případně argumentů – podle toho, jak pečlivě jsem zdroják čistil. Nepotřebné sloupce mažu a dokument ukládám jako CSV pro další práci. Převod do CSV není nutný, má ale výhody.

  • neomezuje vás požadavek na validitu XML,
  • můžete používat kusy HTML,
  • můžete se rychle zbavit balastu

Ve WP All Import vybíráte, které kolonky se mají párovat, takže si vyberete jen ty potřebné, ostatní se zahazují.

Jenže jsem zapomněl na další věc: nadpis je pouze jednou, kdežto obrázků mám hafo. A zpracování CSV je sekvenční, tzn. každý sloupec má mít hodnotu, aby se při každém cyklu někam uložily. Když hodnoty nemá, bude potřeba přepisovat, přeskakovat… Jak do jednoho článku uložit v šesti nebo osmi krocích postupně obrázky?

To je přece blbost. Musím to dělat z XML ne z CSV. Potřebuji nody, ne řádky.

Generování HTML z XML

Tady si uvědomuju, že mám v datech shluky, skupiny. Potřebuji ze skupiny načíst odkaz na obrázek, zachovat jeho alt popisek a to celé vygenerovat do fotogalerie, kterou bude možné zpracovat následně Gutenbergem.

Vyčištění zdrojáku už mi jde mnohem rychleji, také díky historii ve vyhledávacím políčku. Objevuji tyto články v dokumentaci pluginu a lehce jásám, to je ono!

Hlavní prvek je každý <figure> v galerii (ta je ve skupině pouze jedna, ale figur je neznámý počet). Do výstupu posílám obrázek s adresou z odkazu (všimněte si, že zde není HTML značka a, nýbrž moje značka link):

\[FOREACH({gallery\[1]/figure})]\
\<img src="{/link\[1]/@url}" alt="{/link\[1]/@title}" />\
\[ENDFOREACH]

Protože už to pro vás není taková zábava jako pro mě, když jsem to objevoval :-), tak už jen shrnu svoje další poznatky:

  • je vhodné použít nějakou PHP funkci, třeba pro odstranění white space, kterou si můžete napsat/nechat vygenerovat, použil jsem i pro vytvoření seznamu štítků z názvu (čas, místo),
  • html znaky nejsou vůbec zpracovány, ani <span>,
  • escapování složených závorek,
  • důležitý je unikátní klíč – zabránění duplicitám; pokud to bude nadpis, pak se ještě při přípravě zdroje ujistěte, že nejsou dva stejné nadpisy (budou),
  • pokud generujete HTML jako já, pak je potřeba kód během konfigurace importu zadávat v HTML editoru, jinak ho plugin escapuje a vše vyjde nazmar,
  • kontrolujte si počet položek – v dokumentu zjistíte, kolik jich je, tolik bych jich měl plugin naimportovat

Takhle jsem si vizuálně zkontroloval duplicity (jop, Linux).

grep heading index-ready.xml |  uniq -c | sort

Finální kód

Výsledný kód jsem minifikoval, aby mi do výstupu nešly nežádoucí mezery, protože Gutenberg je na ně háklivý. Zde tedy pro přehlednost s mezerami.

<p>[remove_white_space({description[1]})]</p>
<!-- /wp:paragraph -->

<!-- wp:gallery \{"sizeSlug":"medium"} -->
<figure class="wp-block-gallery has-nested-images columns-default ">

[FOREACH({gallery[1]/figure})]

<!-- wp:image \{"lightbox":\{"enabled":true},"linkDestination":"none", "className":"size-medium"} -->
<figure class="wp-block-image size-medium">

<a href="{link[1]/@href}">
<img src="{link[1]/@href}" alt="{link[1]/@title}" />
</a>

<figcaption class="wp-element-caption">
[remove_white_space({figcaption[1]})]</figcaption>
</figure>
<!-- /wp:image -->

[ENDFOREACH]

</figure>
<!-- /wp:gallery -->

Dosáhl jsem požadovaného výsledku – mám na novém webu nižší stovky kategorizovaných článků, obsahem každého je odpovídající galerie, kterou lze editovat v Gutenbergu. Jediná nevýhoda je, že nejsou použity náhledové obrázky, ale originální velikosti. Po kliknutí se zobrazí plná velikost, což je nyní standardní chování tohoto GB bloku.

K čemu to všechno?

Možná si klepete na čelo, o čem to tady celou dobu píšu a proč to dělám tak složitě…

Well. Takhle se učím. Procvičil jsem si

  • regulární výrazy,
  • práci s XML (to je tedy nejméně přínosná věc, spíše otročina ;-)),
  • nastavení a mnoho různých importních úloh s pluginem WP All in One Import (to je velmi cenná zkušenost),
  • stanovení postupu podle prvotního nápadu, hledání nových postupů, ověřování hypotéz,
  • plánování a dotažení obtížné úlohy do konce,
  • kontrolu emoční křivky, která mě samozřejmě ovlivňuje.

Myslím si, že podobné úlohy může v různých složitostech zkoušet každý, aby svoje osobní know how zlepšoval – zejména, když hledá práci. Já se takovým úlohám nevyhýbám, vidím v nich úžasný prostor pro zlepšení toho, co pak můžu nabízet zákazníkům. (A to jsem na začátku zavrhl scraping dat a pořád mi to s AI jde jen průměrně). Co všechno ještě neumím, jaké cesty vedou k cíli?

Zaujalo vás to? Pomozte někomu a podělte se 🙂

Autor Vlastimil Ott

Pracuji s WordPressem někdy od roku 2006, od roku 2001 s Linuxem. Naučil jsem se programovat, vyvíjet a udržovat weby, což mi umožnilo stát se součástí WP komunity. Vystupoval jsem na několika konferencích, nejčastěji s tématem správy a optimalizace WordPressu. Ještě předtím jsem byl šéfredaktorem magazínu LinuxEXPRES a vydal knihu LibreOffice Writer. Věnuji složitým #WordPress úkolům a #SEO.
WP-admin.cz
WP-admin.cz
@team@wp-admin.cz

Rozvíjíme firemní weby na WordPressu. Vylepšujeme ty, které už fungují, vytváříme nové. Dáváme si záležet na správné metodice, postupech a kvalitě výstupu. Pracujeme s analytikou, daty a open-source nástroji a technologiemi (Nextcloud, Linux, Docker, Matomo apod.).

84 posts
0 followers

Napsat komentář