Wikicesty
cswikivoyage
https://cs.wikivoyage.org/wiki/Hlavn%C3%AD_strana
MediaWiki 1.47.0-wmf.3
first-letter
Média
Speciální
Diskuse
Uživatel
Diskuse s uživatelem
Wikicesty
Diskuse k Wikicestám
Soubor
Diskuse k souboru
MediaWiki
Diskuse k MediaWiki
Šablona
Diskuse k šabloně
Nápověda
Diskuse k nápovědě
Kategorie
Diskuse ke kategorii
TimedText
TimedText talk
Modul
Diskuse k modulu
Podujatie
Diskusia k podujatiu
Brno
0
228
22105
21492
2026-05-20T12:19:31Z
LiMr
96
/* Pravidelné akce */ typo
22105
wikitext
text/x-wiki
{{Pagebanner|Brno - panorama I - 2012.jpg|Panoramatický pohled na přibližně jihozápadní čtvrtinu města|unesco_whs=yes}}
'''Brno''' je město v [[Jihomoravský kraj|Jihomoravském kraji]], největší město [[Morava|Moravy]] a druhé největší město [[Česko|České republiky]]. Je kulturním centrem Moravy a sídlem množství institucí.
K nejvýznamnějším dominantám města patří hrad a pevnost ''Špilberk'' na stejnojmenném kopci a ''katedrála svatého Petra a Pavla'' na vršku ''Petrov'', utvářející charakteristické panorama města. Druhým dochovaným hradem na území Brna je ''Veveří'', kdysi vybudovaný nad řekou Svratkou a dnes se tyčící nad Brněnskou přehradou. Významnou památkou meziválečné architektury je funkcionalistická ''vila Tugendhat'', patřící mezi [[Seznam světového dědictví UNESCO|Světové dědictví UNESCO]]. V Brně se nachází celkem 14 národních kulturních památek. Historické městské jádro bylo vyhlášeno městskou památkovou rezervací. Na území města se také nachází dvě městské památkové zóny, jedna vesnická památková zóna a jedna archeologická památková rezervace. K turisticky atraktivním lokalitám patří také Chráněná krajinná oblast [[Moravský kras]], jejíž nejjižnější část zasahuje na území města.
== Dálková doprava ==
=== Letecká doprava ===
{{Bod|wikidata=Q748848}}
Letiště Brno-Tuřany je mezinárodní letiště nacházející se 7,5 km jihovýchodně od centra Brna. V roce 2020 nabízí společnost Ryanair pravidelné letecké spojení na tato letiště:
* [[Londýn]]/Stansted – Spojené království Velké Británie a Severního Irska
* Milán/Bergamo – [[Itálie]]
* [[Berlín]]-Schönefeld – [[Německo]]
Brněnské letiště je obsluhováno městskou hromadnou dopravou, v denní dobu autobusovou linkou E76 a v noční dobu autobusovou linkou N89. Autobus odjíždí od železničního hlavního nádraží v centru města. Interval mezi spojky činí v denní dobu 30 minut a v noční dobu 60 minut. Cena jízdného pro dospělou osobu je {{CZK|25}}, dětské jízdné je {{CZK|12}}.
Pro cestu do Brna z jiných destinací lze použít větší letiště ve [[Vídeň|Vídni]], [[Praha|Praze]] či [[Bratislava|Bratislavě]], případně z menších letišť v okolí [[Ostrava|Ostravu]], [[Pardubice]] či [[Katovice]].
=== Železniční doprava ===
{{Bod|wikidata=Q921772|popis=[https://www.cd.cz/assets/dalsi-sluzby/sluzby-ve-stanici/brno-hlavni-nadrazi.pdf plánek], [http://provoz.szdc.cz/tabule/StationDetail.aspx?lang=cs&id=5433295&t=2 tabule aktuálních odjezdů]}}
Nejdůležitějším uzlem je ''Brno hlavní nádraží'', které leží u jihovýchodního okraje historického centra v sousedství hlavního tramvajového uzlu. Vede z něj sedm tratí a přímá spojení jsou:
* [[w:Železniční trať Brno – Česká Třebová|tratí na Českou Třebovou]] do [[Blansko|Blanska]], [[Česká Třebová|České Třebové]] a pak dále [[w:První železniční koridor|prvním železničním koridorem]] do [[Pardubice|Pardubic]], [[Kolín]]a a [[Praha|Prahy]], [[Ústí nad Labem|Ústí na Labem]] a [[Drážďany|Drážďan]]
* [[w:Železniční trať Brno–Jihlava|tratí na Jihlavu]] do [[Třebíč]]e a [[Jihlava|Jihlavy]]
* [[w:Železniční trať Brno – Moravské Bránice – Hrušovany nad Jevišovkou/Oslavany|tratí na Hrušovany a Oslavany]] do [[Oslavany|Oslavan]], [[Moravský Krumlov|Moravského Krumlova]] a [[Hrušovany nad Jevišovkou|Hrušovan nad Jevišovkou]]
* [[w:Železniční trať Havlíčkův Brod – Kúty|tratí z Havlíčkova Brodu do Kút]] na západ do [[w:Žďár nad Sázavou|Žďáru nad Sázavou]], [[Přibyslav]]i a [[Havlíčkův Brod|Havlíčkova Brodu]] a na východ do [[Břeclav]]i a následně na [[Slovensko]] do [[Trnava|Trnavy]] nebo [[Bratislava|Bratislavy]].
* [[w:Železniční trať Brno–Přerov|tratí do Přerova]] do [[Přerov]]a
* [[w:Vlárská dráha|Vlárskou drahou]] do [[Slavkov u Brna|Slavkova u Brna]], [[Kyjov]]a, [[Bzenec|Bzence]], [[Veselí nad Moravou]] a dále až na Slovensko do [[Trenčianská Teplá|Trenčianské Teplé]].
=== Autobusová doprava ===
{{Bod|wikidata=Q17489136}}
Autobusové nádraží v Brně, známé jako Autobusové nádraží Zvonařka, je jedním z nejdůležitějších dopravních uzlů na Moravě. Nachází se asi 15 minut od hlavního vlakového nádraží a centra města. Zvonařka slouží jako klíčový uzel pro meziměstskou a mezinárodní autobusovou dopravu. Autobusy odsud jezdí nejen do mnoha měst v České republice (např. Praha, Ostrava, [[Olomouc]]), ale i do zahraničí (např. [[Vídeň]], Bratislava, [[Budapešť]]).
=== Autem ===
Vzdálenosti z vybraných měst:
* [[Olomouc]] – 80 km, 0:55 h
* [[Zlín]] – 100 km, 1:10 h
* [[Bratislava]] – 130 km, 1:25 h
* [[Vídeň]] – 140 km, 1:45 h
* [[Pardubice]] – 140 km, 2:15 h
* [[Hradec Králové]] – 150 km, 2:20 h
* [[Ostrava]] – 170 km, 1:45 h
* [[Praha]] – 210 km, 2:10 h
* [[České Budějovice]] – 220 km, 2:30 h
Dálnice D1 v úseku kolem Brna není zpoplatněná, konkrétně úsek Kývalka – Holubice (182-210 km).
== Místní doprava ==
Pro dopravu po Brně se využívají nejčastěji tramvaje (v Brně často nazývány šaliny), trolejbusy a autobusy. Centrálním místem je nástupiště u hlavního vlakového nádraží.
=== Jízdenky ===
==== Pomocí platební karty ====
Nejpohodlněji je možné koupit jízdenku pomocí platební karty přímo v dopravním prostředku prostým přiložením karty a to bez nutnosti předchozí registrace. Tento systém se jmenuje [https://www.pipniajed.cz/ Pípni a jeď!]. Na jednu platební kartu je možné zakoupit jízdenky i pro více cestujících.
==== SMS jízdenky ====
* Pro jízdenku za 20 Kč s platností 20 minut do textové zprávy napište BRNO20.
* Pro jízdenku za 29 Kč s platností 75 minut do zprávy napište BRNO.
* Pro jízdenku za 99 Kč s platností 24 hodin do zprávy napište BRNOD.
Text odešlete na telefonní číslo 90206. SMS jízdenka vám přijde do dvou minut, při nástupu do vozu je nutné mít již jízdenku v mobilu. SMS jízdenky platí v tramvajích, trolejbusech a autobusech, naopak je nelze využít ve vlacích. Pro jejich nákup je nutná aktivace služby Premium SMS u mobilního operátora a česká mobilní SIM karta.
Aktuální ceny a další možnosti nákupu jízdenek pomocí telefonu jsou na webu [https://www.dpmb.cz/jizdenky-v-mobilu#sms DPMB].
== Co vidět ==
{{Mapa|49.195278|16.608333|zoom=12|width=400|height=400}}
=== Památky ===
{{Bod|wikidata=Q118256}} <!--Špilberk-->
{{Bod|wikidata=Q439347}} <!--Stará radnice-->
{{Bod|wikidata=Q457453}} <!--vila Tugendhat-->
{{Bod|wikidata=Q9374731|popis=Architekt Ernst Wiesner navrhl vilu pro brněnského textilního továrníka Alfreda Stiassniho v letech 1927–1929}} <!--Vila Stiassny-->
{{Bod|wikidata=Q5037118|popis=Klášter kapucínů}} <!--Kapucínská hrobka-->
{{Bod|wikidata=Q4971773}} <!--Kostnice u sv. Jakuba-->
{{Bod|wikidata=Q12037699|popis=Dříve označovaný jako Mincmistrovský sklep}} <!--Sklep pod Novou radnicí-->
{{Bod|wikidata=Q6467737|typ=see}} <!--Podzemí pod Zelným trhem-->
{{Bod|wikidata=Q921344|cena={{CZK|50-210}}}} <!--Hrad Veveří-->
{{Bod|wikidata=Q12039319|popis=Z důvodu rekonstrukce uzavřena|aktualizováno=2024-10-14}} <!--Měnínská brána-->
{{Bod|wikidata=Q24352771|popis=Tři bývalé vodojemy vybudované ve druhé polovině 19. století, ulice Tvrdého (vstup brankou vedle domu č. 15)|cena={{CZK|350}}, zlevněné vstupné {{CZK|250}}|typ=see}} <!--Vodojemy na Žlutém kopci-->
{{Bod|wikidata=Q102347068|popis=Roh ulice Husova a Nádražní (vchod z ulice Husova)|otevřeno=neděle po předchozí online rezervaci|cena={{CZK|150}}, děti, studenti, senioři, ZTP {{CZK|90}}|aktualizováno=2024-10-14}} <!--Kryt Denis-->
{{Bod|wikidata=Q4414992|popis=Expozice o dějinách osídlení Moravy, genetika a vývoj člověka, galerie obrazů Zdeňka Buriana|cena={{CZK|120}}, snížená: {{CZK|70}}, rodinná: {{CZK|250}}}} <!--Pavilon Anthropos-->
==== Sakrální stavby ====
{{Bod|wikidata=Q45033}} <!--katedrála svatého Petra a Pavla-->
{{Bod|wikidata=Q1149587}} <!--kostel svatého Jakuba Staršího-->
{{Bod|wikidata=Q11062049}} <!--Bazilika Nanebevzetí Panny Marie-->
{{Bod|wikidata=Q9188202|popis=Pravoslavný chrám}} <!--Pravoslavný chrám sv. Václava-->
<gallery>
File:Hrad Špilberk v Brně.jpg|Hrad Špilberk
File:Brno, katedrála sv. Petra a Pavla.jpg|Katedrála sv. Petra a Pavla
File:Brno, Radnická Stará radnice.jpg|Stará radnice
File:Vila Tugendhat.jpg|Vila Tugendhat
File:Brno - Church of the st. Jacob (Kostel sv. Jakuba) 1.JPG|Kostel sv. Jakuba
File:Mesto Brno - Kostnice pod kostelem sv. Jakuba 1.jpg|Kostnice u sv. Jakuba
File:Brno, Mincmistrovský sklep, chodba.jpg|Mincmistrovský sklep
File:Brno, podzemí pod Zelným trhem (9).JPG|Labyrint pod Zelným trhem
File:Bazilika Nanebevzetí Panny Marie (Brno).JPG|Bazilika Nanebevzetí Panny Marie
File:Hrad Veveří - letecký pohled 05 upraveny.jpg|Hrad Veveří
File:Brno chrám sv. Václava celý 7.jpg|Pravoslavný chrám sv. Václava
File:Brno, Orlí, Měnínská brána (2013; 01).jpg|Měnínská brána
File:Brno - pavilon Anthropos.jpg|Vstup do pavilonu Anthropos
</gallery>
== Kam jít ==
=== Kina ===
{{Bod|wikidata=Q20052680}} <!--Kino Art-->
{{Bod|wikidata=Q20057638}} <!--Kino Lucerna-->
{{Bod|wikidata=Q8848601}} <!--Kino Cinema City Velký Špalíček-->
{{Bod|wikidata=Q130529927}} <!--Cinema City Olympia-->
==== Letní kina ====
{{Bod|49.1931328|16.6057150|název=Letní kino Brno-střed|typ=do|adresa=Dominikánská 2, 602 00 Brno|facebook=kinobude.cz|web=https://kinobude.cz/letnikino.brnostred/|instagram=letnikino.brnostred|youtube=UCFxZIDi4bba1L9oirOAJO2g|platba=hotově|cena={{CZK|140}}}}
{{Bod|49.1940536|16.6006608|název=Letní kino Špilberk|type=do|adresa=Špilberk 1, 662 24 Brno|facebook=LetniKinoSpilberk|telefon=+420 732 565 202|web=http://www.letnikinospilberk.cz/|instagram=letnikinospilberk|otevírací doba=červen-červenec od 21:30, srpen od 21:00|cena=dospělí {{CZK|120}}, studenti {{CZK|100}}, děti do 12 let zdarma}}
=== Divadla ===
{{Bod|wikidata=Q1138893}} <!--Mahenovo divadlo-->
{{Bod|wikidata=Q3511873}} <!--Janáčkovo divadlo-->
{{Bod|wikidata=Q578426|název=Městské divadlo Brno|web=https://mdb.cz/|adresa=Lidická 16, 602 00 Brno|telefon=+420 533 316 320|email=komercni@mdb.cz}} <!--Městské divadlo Brno - je správná položka wikidat?-->
{{Bod|wikidata=Q660777}} <!--Divadlo Reduta-->
{{Bod|wikidata=Q12034015|název=Divadlo Radost|web=https://divadlo-radost.cz/|komentář=divadlo pro děti a mládež, představení loutková i s živými herci}} <!--Divadlo Radost-->
{{Bod|wikidata=Q12016576}} <!--Divadlo na Orlí-->
{{Bod|wikidata=Q11812406|název=Divadlo Bolka Polívky|web=https://divadlobolkapolivky.cz/}} <!--Divadlo Bolka Polívky-->
{{Bod|wikidata=Q11812413|název=Divadlo Husa na provázku|web=https://www.provazek.cz/}} <!--Divadlo Husa na provázku-->
=== Další ===
{{Bod|wikidata=Q12021065|název=Hvězdárna a planetárium Brno}} <!--Hvězdárna a planetárium Brno-->
{{Bod|wikidata=Q10861305|cena=vstupné (březen-říjen/listopad-únor): {{CZK|180}}/{{CZK|130}}, senioři, studenti a děti: {{CZK|120}}/{{CZK|90}}, rodinné: {{CZK|480}}/{{CZK|350}}, pes: {{CZK|100}}}} <!--Zoo Brno-->
{{Bod|wikidata=Q121084826|cena=vstupné: {{CZK|180}}, děti: {{CZK|120}}, rodinné: {{CZK|450}}}} <!--Papilonia Brno-->
=== Noční život ===
{{Bod|název=Two Faces|typ=drink|49.1920708|16.6060189|web=http://www.twofaces.cz|adresa=Biskupská 1, 602 00 Brno|telefon=+420 775 960 930|email=club@twofaces.cz|komentář=taneční a noční klub}}
{{Bod|název=Tabarin Club & Bar|typ=drink|49.1948875|16.6142128|web=http://www.tabarin.cz|adresa=Divadelní 603/3, 602 00 Brno|email=tabarin@tabarin.cz|facebook=TabarinClub|instagram=tabarinclub|komentář=taneční a noční klub}}
{{Bod|wikidata=Q15304231|typ=drink|komentář=hudební klub, moderní kulturní centrum, ve kterém se konají koncerty, taneční večery, divadelní představení a různé festivaly}}
{{Bod|wikidata=Q12027647|typ=drink|komentář=hudební, divadelní a filmový klub}} <!--Kabinet múz-->
{{Bod|název=Metro Music Bar|typ=drink|49.1947364|16.6100858|web=https://www.metromusic.cz|adresa=Poštovská 450/6, 602 00 Brno|telefon=+420 515 533 452|email=production@metromusic.cz|facebook=metromusic|instagram=metromusicbar|komentář=hudební a taneční klub zaměřený na jazz, funk, blues a rock, často s živou hudbou|otevírací doba=ÚT-SO 19:00-05:00, PO a NE zavřeno}}
{{Bod|wikidata=Q130526608|typ=drink|komentář=hudební klub, otevřeno dle programu}} <!--Melodka-->
{{Bod|název=Cabaret des Péchés|typ=drink|49.1943581|16.6062444|web=https://www.cabaretdespeches.com|adresa=Palác Jalta, Dominikánského náměstí 656/2, 602 00 Brno|telefon=+420 774 497 277|email=info@cabaretdespeches.com|facebook=cabaretdespeches|instagram=cabaretdespeches|komentář=kabaretní, burleskní, hudební, kouzelnická představení a komediální show|otevírací doba=ÚT-SO 18:00-02:00, PO a NE zavřeno}}
{{Bod|název=Artbar|typ=drink|49.2079586|16.6037942|web=https://www.artbar.club|adresa=Štefánikova 836/1, 602 00 Brno|telefon=+420 721 850 166|facebook=artbarmusicclub|instagram=artbar.club|komentář=koncerty, výstavy, divadelní představení, filmové projekce, literární večery a diskusní setkání, interiér zdobený výtvarnými díly|popis=Vstup z ul. Kotlářská}}
{{Bod|wikidata=Q130896103|typ=drink|komentář=menší multižánrový hudební a kulturní klub pořádající koncerty, filmové projekce, literární večery, diskuse a tematické párty}} <!--Klub Alterna-->
{{Bod|wikidata=Q96460947|typ=drink|komentář=hudební klub podporující místní a zahraniční umělce, koncerty od folku a jazzu po alternativní a experimentální hudbu, divadelní inscenace a autorské čtení}}<!--Klub Leitnerova-->
=== Pravidelné akce ===
{{Bod|wikidata=Q545584|komentář=mezinárodní soutěž ohňostrojů, které jsou synchronizovány s hudbou|frekvence=každoročně|místo=Brněnská přehrada|web=https://www.ignisbrunensis.cz|měsíc=červen|youtube=UC9meqUFQ8k70KakEa_WGFiQ|cena=volný vstup}}
{{Bod|49.2002211|16.6078411|typ=do|název=Kultura pod hvězdami|komentář=letní celorepubliková kulturní akce, která zahrnuje, letní kina, muzikály, divadelní, pěvecké a taneční vystoupení, koncerty, výstavy, které se odehrávají pod širým nebem na různých místech v Brně|frekvence=každoročně|web=https://www.kulturapodhvezdami.cz/cs/program?mesto=brno|měsíc=červenec-srpen|telefon=+420 730 111 866|facebook=kulturapodhvezdami|instagram=kulturapodhvezdami|youtube=UChQTcfYKb80NnOqStYxGxaQ|cena=volný vstup}}
{{Bod|49.1931583|16.6085561|typ=do|název=Uprostřed|komentář=multižánrový festival uprostřed Brna náměstí|frekvence=každoročně|web=https://festivaluprostred.cz/|měsíc=červen-srpen|místo=nádvoří Staré radnice, Moravské náměstí, Římské náměstí, Denisovy sady|cena=volný vstup|telefon=+420 542 427 150|facebook=|instagram=|email=info@ticbrno.cz}}
{{Bod|49.1943303|16.5996214|typ=do|název=Letní Shakespearovské slavnosti|komentář=divadelní přehlídka her pod širým nebem zaměřená na uvádění děl Williama Shakespeara|frekvence=každoročně|web=https://brno.shakespeare.cz/|měsíc=červenec-srpen|telefon=|facebook=|instagram=|email=info@ticbrno.cz}}
{{Bod|49.1996192|16.6063089|typ=do|název=Brazil fest Brno|komentář=festival brazilské kultury, karneval, koncerty, hudba, tanec, show, gastro zážitky|frekvence=každoročně|web=https://www.brasilfestbrno.cz/|měsíc=srpen|místo=nádvoří Staré radnice, Moravské náměstí, Červený kostel, nám. Svobody, Jakubské náměstí, park Lužánky|cena=volný vstup|telefon=|facebook=|instagram=|email=info@ticbrno.cz}}
{{Bod|49.1902886|16.5938131|typ=do|název=Mendel festival|komentář=open air festival, hudební a populárně-vědecký program|frekvence=každoročně|web=https://brno.shakespeare.cz/|měsíc=červenec|cena=volný vstup|facebook=mendelfestival|instagram=mendelfestival}}
{{Bod|49.1847011|16.5798281|typ=do|název=Pop Messe|komentář=festival soudobé populární a alternativní hudby|frekvence=každoročně|web=https://popmesse.cz/|telefon=+420 511 112 504|email=info@popmesse.cz|měsíc=červenec|cena={{CZK|1750}}|facebook=popmessefestival|instagram=pop_messe|youtube=UCO-gTW1SNeCSlMMmZfRUJ-A|tiktok=pop_messeis}}
{{Bod|49.2557478|16.4588231|typ=do|název=Festival Hrady CZ|komentář=letní hudební a kulturní festival|frekvence=každoročně|web=https://www.hradycz.cz/|měsíc=srpen|místo=Hrad Veveří|cena=od {{CZK|1250}}|telefon=+420 736 128 736|facebook=CESKEHRADY|instagram=hradycz|tiktok=hradycz|youtube=UC1KwEzuBC9KVoOahejoDCPg|email=info@nedomysleno.cz}}
{{Bod|49.1952669N|16.6073183|typ=do|název=Brněnské vánoce|komentář=vánoční trhy, kulturní program, koncerty, dílny pro děti i dospělé|frekvence=každoročně|web=https://brnenskevanoce.cz/|měsíc=prosinec|místo=náměstí Svobody,Dominikánské náměstí, Zelný trh, Moravské náměstí a nádvoří Staré radnice|cena=volný vstup|facebook=brnenskevanoce|instagram=brnenskevanoce|tiktok=|youtube=|email=info@ticbrno.cz}}
== Kde spát ==
V Brně je přes 10 000 lůžek v hotelích, penzionech, hostelech, ubytovnách a apartmánech. Přinášíme výběr ubytovacích zařízení v centru města a jeho blízkém okolí.
=== Hotely ★★★★★ ===
{{Bod|wikidata=Q115430910}}
{{Bod|název=Grandezza Hotel Luxury Palace|49.1924006N|16.6096886E|typ=sleep|adresa=Zelný trh 314/2, 602 00 Brno|web=https://www.grandezzahotel.com/|telefon=+420 542 106 010|mobil=+420 603 888 789|email=info@grandezzahotel.cz|platba=hotově, bankovní kartou|facebook=100063639666620|instagram=grandezzahotel}}
=== Hotely ★★★★ ===
{{Bod|wikidata=Q30445219}} <!--Hotel Continental-->
{{Bod|wikidata=Q15696494|název=Hotel International}}
{{Bod|49.1926489|16.6071361|název=Hotel Royal Ricc|adresa=Starobrněnská 338/10, 602 00 Brno-střed|typ=sleep|web=https://www.royalricc.cz|telefon=+420 542 219 262|mobil=+420 736 487 948|fax=+420 542 219 265|email=rezervace@royalricc.cz|facebook=RoyalRicc|instagram=hotelroyalricc|cena=od {{CZK|3551}}}}
{{Bod|wikidata=Q30793114|typ=sleep|cena=od {{CZK|2892}}}}
=== Hotely ★★★ ===
{{Bod|wikidata=Q37815141|název=Hotel Pegas}} <!--Hotel Pegas-->
{{Bod|název=VV Hotel|49.19082467745717|16.615932047529807|typ=sleep|adresa=Mlýnská 8a, 602 00 Brno|web=https://www.vvhotel.cz/|telefon=+420 732 558 439|email=info@vvhotel.cz}}
{{Bod|wikidata=Q109624807|cena=od {{CZK|890}}}}
{{Bod|wikidata=Q12020398|cena=od {{CZK|1899}}}}
=== Penziony ===
{{Bod|wikidata=Q126684686|cena= od {{CZK|1670}}}}
=== Hostely ===
{{Bod|wikidata=Q111116356|cena= od {{CZK|350}}}}
{{Bod|název=Schrott Bed&Beer|49.1913603|16.6160114|typ=sleep|adresa=Křenová 291/10, 602 00 Brno|telefon=+420 725 750 256|checkin=15:00|checkout=11:00}}
=== Apartmány ===
{{Bod|49.1959119|16.6090611|název=Apartmánový dům Centrum|typ=sleep|adresa=Běhounská 115/4, 602 00 Brno|aktualizováno=2024-10-19|checkin=15:00|checkout=10:00|telefon=+420 533 534 154}}
{{Bod|49.191439|16.616828|název=Flat in Brno|typ=sleep|adresa=Rumiště 6, 602 00 Brno|web=https://flatinbrno.cz/|aktualizováno=2024-10-19|checkin=15:00|checkout=10:00|telefon=+420 724 185 434|email=info@flatinbrno.cz}}
=== Ubytovny ===
{{Bod|49.1959983|16.6175028|název=Ubytovna Pohoda|typ=sleep|adresa=Cejl 10a, 602 00 Brno|web=https://www.ubytovna-pohoda.cz/|aktualizováno=2024-10-28|telefon=+420 777 201 803}}
{{Bod|49.1939431|16.6246131|název=Ubytovna Moravan|typ=sleep|adresa=Podnásepní 375/1, 602 00 Brno|web=https://www.svomi-ubytovani.cz/ubytovani-centrum-krenova-podnasepni/|cena= od {{CZK|232}}|aktualizováno=2024-10-30|telefon=+420 604 507 030|email=accom.brno@email.cz}}
== Kde jíst ==
{{Bod|typ=eat|název=Restaurace Padowetz|49.1913006|16.6109258|platba=hotově, bankovní kartou|aktualizováno=2024-10-30|adresa=Masarykova 413/34, 602 00 Brno|telefon=+420 734 617 456|web=https://restaurant-padowetz.cz/|email=restaurant@padowetz.cz|facebook=PadowetzOriginalRestaurant|instagram=padowetzrestaurant|otevírací doba=PO-ČT 11:00-24:00, PÁ-SO 11:00-01:00, NE 11:00-24:00}}
{{Bod|typ=eat|název=Stopkova Plzeňská pivnice|49.1956619|16.6067200|komentář=česká kuchyně|platba=hotově, bankovní kartou|aktualizováno=2024-10-30|adresa=Česká 163/5, 602 00 Brno|telefon=+420 517 070 080|web=https://stopkova.kolkovna.cz/|email=info@stopkovapivnice.cz|facebook=StopkovaPivnice|instagram=kolkovna_restaurants|otevírací doba=PO-SO 11:00-24:00, NE 11:00-23:00}}
{{Bod|typ=eat|název=Restaurace ZaZa|49.1956336|16.6118611|komentář=Neapolská pizza, víno, pivo|platba=hotově, bankovní kartou|aktualizováno=2024-10-30|adresa=Váchova 46/4, 602 00 Brno|telefon=+420 517 070 080|web=https://www.zazabrno.cz/|email=rezervace@zazabrno.cz |facebook=zazabrno|instagram=zazabrno|otevírací doba=PO-PÁ 16:30-23:00, SO-NE 11:30-22:00}}
== Kde pít ==
=== Bary ===
{{Bod|typ=drink|název=Super Panda Circus|49.1926003|16.6051831|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Šilingrovo nám. 257/3, 602 00 Brno-střed|telefon=+420 734 878 603|web=https://www.superpandacircus.cz/|popis=Vchod z ulice Husova|komentář=Originální koktejlový bar s unikátní atmosférou a kreativními drinky|email=adam@superpandacircus.cz|facebook=superpandabrno|instagram=super_panda_circus|otevírací doba=PO-ÚT 19:00-02:00, ST-SO 19:00-02:00, NE zavřeno}}
{{Bod|typ=drink|název=Bar, který neexistuje|49.1958947|16.6098228|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Dvořákova 24/1, 602 00 Brno|telefon=+420 734 878 602|web=https://www.barkteryneexistuje.cz|komentář=jeden z nejznámějších barů v Brně s širokou nabídkou koktejlů a příjemnou atmosférou|email=rezervace@turbomost.cz|facebook=BarKteryNeexistuje|instagram=bar_ktery_neexistuje|otevírací doba=PO-ÚT 17:00-02:00, ST-ČT 17:00-02:30, PÁ-SO 17:00-03:30, NE 17:00-02:00}}
{{Bod|typ=drink|název=4pokoje|49.1957508|16.6118183|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Vachova 45/6, 602 00 Brno|telefon=+420 770 122 102|web=https://www.miluju4pokoje.cz|komentář=moderní bar s pestrou nabídkou drinků a jídel|email=hana.vesela@lidizbaru.cz|facebook=4pokojebrno|instagram=4pokojebrno|otevírací doba=PO-ÚT 17:00-01:00, ST 17:00-03:00, ČT-SO 17:00-04:00, NE zavřeno}}
=== Pivnice ===
{{Bod|typ=drink|název=Pivní burza|49.1947461|16.6116414|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Jánská 467/16, 602 00 Brno-střed|telefon=+420 776 668 290|web=https://pivniburza.cz|komentář=zajímavý koncept, kde ceny piva kolísají jako na burze. Výborné místo pro pivní nadšence.|email=info@pivniburza.cz|facebook=pivniburza|instagram=pivniburza|otevírací doba=PO-NE 15:00-01:00}}
{{Bod|typ=drink|název=Lokál U Cajpla|49.1959028|16.6094414|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Kozí 115/3, 602 00 Brno|telefon=+420 731 594 671 |web=https://lokal-ucaipla.ambi.cz/cz/|komentář=skvělé pivo a domácí jídlo|email=ucaipla@ambi.cz|facebook=lokalucaipla|instagram=lokalcz|otevírací doba=PO-ČT 11:00-24:00, PÁ-SO 11:00-01:00, NE 11:00-22:00}}
{{Bod|typ=drink|název=U Dřevěného vlka|49.1928375|16.6097833|platba=hotově, bankovní kartou|aktualizováno=2024-11-02|adresa=Zelný trh 318/1, 602 00 Brno|telefon=+420 511 181 010 |web=https://www.drevenyvlk.cz/|komentář=široká nabídka piv z malých a regionálních pivovarů|email=drevenyvlk@gmail.com|facebook=drevenyvlk|otevírací doba=PO-ÚT 11:00-24:00, ST-PÁ 11:00-01:00, SO 12:00-01:00, NE 12:00-24:00}}
== Nákupy a služby ==
=== Nákupy ===
{{Bod|wikidata=Q11878044|popis=Obchodní centrum stojí mezi hlavním vlakovým a autobusovým nádražím. Tato obchodní galerie je v blízkosti historického centra a zahrnuje obchody, restaurace, služby, parkoviště.}} <!--Galerie Vaňkovka-->
{{Bod|wikidata=Q10859380|popis=Velké nákupní centrum s desítkami obchodů, od velké Ikea až po malé butiky. Leží jižně od centra v městské části Brno-jih (zastávka Ikea nebo Avion Shopping).}} <!--Avion Shopping Park Brno-->
{{Bod|wikidata=Q12042579|popis=Olympia se nachází také v Brně-jihu, samostatné čtvrti jižně od centra (autobusová zastávka "Modřice, Olympia"). Je to obrovské nákupní centrum určené pro rodiny, které zde chtějí strávit celý den. Kromě velkého množství obchodů, které se zde nacházejí, se v centru Olympia nachází také multikino, několik kaváren a restaurací (od McDonald's po Sushi bary), amfiteátr a velké dětské hřiště.}} <!--Olympia centrum-->
{{Bod|wikidata=Q11707375}} <!--Campus Square-->
=== Půjčovny ===
{{Bod|typ=go|název=Autopůjčovna Smíšovský|komentář=půjčovna automobilů a dodávek|49.1223433|16.6047194|aktualizováno=2024-10-30|adresa=Brněnská 988, 664 42 Modřice|telefon=+420 608 776 900|web=https://www.smisak.cz/|cena=od {{CZK|1500}}|email=smisovsky@seznam.cz|otevírací doba=NON-STOP}}
{{Bod|typ=go|název=Autopůjčovna - Comfort Car|komentář=půjčovna automobilů a pick-up|49.1819422|16.6296000|aktualizováno=2024-10-30|adresa=Černovické nábřeží 501/7a, 618 00 Brno|telefon=+420 776 463 211|web=https://www.comfort-car.cz/|cena=od {{CZK|390}}|email=info@comfort-car.cz|otevírací doba=8:00-20:00}}
{{Bod|typ=go|název=Na Skútr Brno|komentář=půjčovna skútrů Honda|49.1755694|16.6397431|platba=hotově, QR|aktualizováno=2024-10-30|adresa=Faměrovo nám. 40/9, 618 00 Brno-Černovice|telefon=+420 724 185 434|web=https://www.naskutrbrno.cz|cena=od {{CZK|950}}|email=pujcovna@naskutrbrno.cz|otevírací doba=8:00-16:00}}
== Kam dál ==
* [[Moravský kras]] - největší a nejlépe vyvinutá krasová oblast s nejširším spektrem krasových jevů v České republice, sousedí s Brnem
== Externí odkazy ==
* {{Wikipedie}}
* [https://www.ticbrno.cz/ Turistické informační centrum Brno]
[[Kategorie:Jihomoravský kraj]]
[[Kategorie:Města v Česku]]
o3v0ntcs2omc8k94kf80v4fdbmmkv8p
Modul:Mapshape utilities/i18n
828
1317
22107
17674
2026-05-20T12:33:10Z
LiMr
96
aktualizace na novější verzi
22107
Scribunto
text/plain
-- kopie z německých wikicest (https://de.wikivoyage.org/w/index.php?title=Modul:Mapshape_utilities/i18n&oldid=1735601)
-- copy from dewikivoyage (https://de.wikivoyage.org/w/index.php?title=Modul:Mapshape_utilities/i18n&oldid=1735601)
return {
-- module administration
moduleInterface = {
suite = 'Mapshape utilities',
sub = 'i18n',
serial = '2025-12-21',
item = 65448276
},
excludeOSM = false, -- set true in case of mapserver malfunction
usePropertyCategs = true, -- for Wikidata properties
-- defaults
defaultFill = '#555555',
defaultFillOpacity = 0.5,
defaultMarkerColor = '#5E74F3',
defaultStroke = '#000000',
defaultStrokeWidth = 2,
defaultStrokeOpacity = 0.5,
defaultShapesWidth = 3,
defaultShapesOpacity = 0.8,
defaultHeight = 420,
defaultWidth = 420,
defaultHighlight = '#66bb77', -- mapgroup
defaultZoom = 14,
defaultColors = { '#8fb6d9', '#a5c15d', '#ffb261', '#e4db5e', '#d56d76', '#a8a567', '#80bb89', '#b569b5' },
maxZoomLevel = 19, -- copy from Module:Marker utilities/i18n
borderAdjustment = 2, -- borders inside maps
-- type defaults for map shapes
defaultGroup = 'mask',
-- Properties for set of mapshapes
-- P527: has part
-- P1535: used by
-- P2670: has parts of the class
mapshapesProps = { 'P527', 'P2670', 'P1535', 'P121' },
-- strings
geomask = 'Maskování %s',
mapOf = '%s na mapě',
-- maintenance
mfBadData = 'Nesprávné souřadnice.',
mfErrorCateg = '[[Kategorie:Údržba:Chyby map]]',
mfExactlyOne = 'Bod se skládá pouze z jedné souřadnice.',
mfMinValues = 'Každá skupina souřadnic musí mít alespoň %d hodnot.',
mfNoCommons = 'Nebyl specifikován soubor Commons.',
mfNoParts = 'V datové sadě Wikidata nejsou žádné podřízené prvky.',
mfNoService = 'Žádný nebo nesprávný typ obrysu.',
mfNoWdCoord = 'Na Wikidatech nejsou k dispozici žádné souřadnice.',
mfNoWikidata = 'Nebyl zadán žádný identifikátor Wikidat.',
mfTogether = '<span class="error">Mapa: Wikidata a parametry souřadnic nelze používat současně.</span>[[Kategorie:Údržba:Chyby map]]',
mfTogether2 = '<span class="error">Mapa: Parametry wikidata a wikicommons nelze používat současně.</span>[[Kategorie:Údržba:Chyby map]]',
mfTooManyLevels = 'Příliš mnoho úrovní.',
mfUnknown = '[[Kategorie:Údržba:Chyby map]]',
-- mfWithShapes = '[[Kategorie:Mapframe: Mit Mapshapes]]', --myslím že není třeba kategorizovat
mfFromCommons = '[[Category:Mapframe: Kartendaten aus Wikimedia Commons]]',
msMissing = '<span class="error">Mapa: Musí být zadán parametr wikidata nebo commons.</span>[[Kategorie:Údržba:Chyby map]]',
msTogether = '<span class="error">Mapa: Parametry wikidata a wikicommons nelze používat současně.</span>[[Kategorie:Údržba:Chyby map]]',
msUnknown = '<span class="error">Mapa: Neznámé parametry.</span>[[Kategorie:Údržba:Chyby map]]',
mssMissingFirst = '<span class="error">Mapa: Parameter 1 chybí.</span>[[Kategorie:Údržba:Chyby map]]',
mssNoChilds = '<span class="error">V datové sadě Wikidata nejsou žádné podřízené prvky.</span>[[Kategorie:Údržba:Chyby map]]',
mssUnknown = '<span class="error">Mapa: Neznámé parametry.</span>[[Kategorie:Údržba:Chyby map]]',
properties = '[[Kategorie:Monitoring:Data z wikidat]]',
unknownParam = ' <span class="error">Neznámý parametr: %s</span>',
unknownParams = ' <span class="error">Neznámé parametry: %s</span>'
}
lae4q93211f7msuy44y13pcrg10hu5i
Modul:Wikidata utilities
828
1320
22104
17190
2026-05-20T12:16:53Z
LiMr
96
aktualizace na novější verzi
22104
Scribunto
text/plain
-- Wikidata convenience utilities
-- kopie z německých wikicest (https://de.wikivoyage.org/w/index.php?title=Modul:Wikidata_utilities&oldid=1775622)
-- copy from dewikivoyage (https://de.wikivoyage.org/w/index.php?title=Modul:Wikidata_utilities&oldid=1775622)
-- documentation
local WikidataUtilities = {
suite = 'WikidataUtilities',
serial = '2026-05-17',
item = 65439025
}
-- i18n
local wd = {
version = 'P348',
startTime = "P580",
endTime = "P582",
retrieved = 'P813',
gregorianCalendar = { -- calendar models
Q12138 = 1, -- Gregorian
Q1985727 = 1 -- proleptic Gregorian
},
redirectBadges = {
Q70894304 = 1, -- intentional sitelink
Q70893996 = 1 -- redirect sitelink
}
}
-- module variable and administration
local wu = {
moduleInterface = WikidataUtilities,
currentTime = ''
}
-- table storing property ids used
local catTable = {
P0 = ''
}
local function isSet( arg )
return arg and arg ~= ''
end
function wu.getEntity( id )
local wrongQualifier = false
local entity = nil
if not isSet( id ) then
return '', entity, wrongQualifier
end
if mw.wikibase.isValidEntityId( id ) then
-- expensive function call
-- redirect ids marked false, too
entity = mw.wikibase.getEntity( id )
end
if not entity then
id = ''
wrongQualifier = true
end
return id, entity, wrongQualifier
end
function wu.getEntityId( id )
local wrongQualifier = false
local entity
if not isSet( id ) then
id = ''
elseif mw.wikibase.isValidEntityId( id ) and mw.wikibase.entityExists( id ) then
-- expensive function call
-- redirect ids marked false, too
entity = id
else
id = ''
wrongQualifier = true
end
return id, entity, wrongQualifier
end
function wu.getLabel( entity, lang, noFallback )
if not isSet( entity ) then
return nil
end
local tp = type( entity )
if tp == 'string' and mw.wikibase.isValidEntityId( entity ) then
return isSet( lang ) and mw.wikibase.getLabelByLang( entity, lang )
or ( not noFallback and mw.wikibase.getLabel( entity ) )
elseif tp == 'table' and entity.labels then -- really a wikidata entity?
return isSet( lang ) and entity:getLabel( lang )
or ( not noFallback and entity:getLabel() )
end
return nil
end
function wu.getAliases( entity, lang )
if type( entity ) == 'string' then -- is Q id
entity = mw.wikibase.getEntity( entity )
end
if not lang then
lang = mw.getContentLanguage():getCode()
end
local aliases = {}
if entity and entity.aliases and entity.aliases[ lang ] then
for i, alias in ipairs( entity.aliases[ lang ] ) do
table.insert( aliases, alias.value )
end
end
return aliases
end
function wu.getSitelink( entity, globalSiteId )
if not isSet( entity ) then
return nil
end
if type( entity ) == 'string' then -- entity is id
return mw.wikibase.getSitelink( entity, globalSiteId )
elseif entity and entity.labels then
return entity:getSitelink( globalSiteId )
end
return nil
end
local function getSitelinkTable( entity, globalSiteId )
if not isSet( entity ) or not isSet( globalSiteId ) then
return nil
elseif type( entity ) == 'string' then -- entity is id
entity = mw.wikibase.getEntity( entity )
end
if entity and entity.sitelinks then
return entity.sitelinks[ globalSiteId ]
end
return nil
end
-- getting sitelink title marking as redirect
function wu.getCheckedSitelink( entity, globalSiteId )
local isRedirect = false
local t = getSitelinkTable( entity, globalSiteId )
if not t or not t.title then
return nil, isRedirect
end
for i = 1, #t.badges do
if wd.redirectBadges[ t.badges[ i ] ] then
isRedirect = true
break
end
end
return t.title, isRedirect
end
-- getting sitelink title exclunding redirects
function wu.getFilteredSitelink( entity, globalSiteId )
local title, isRedirect = wu.getCheckedSitelink( entity, globalSiteId )
return ( title and not isRedirect ) and title or nil
end
-- convert from url to Q id
local function getUnitId( unit )
if isSet( unit ) and type( unit ) == 'string' then
return unit == '1' and unit or unit:sub( unit:find( 'Q', 1, true ), -1 )
end
return ''
end
local function getAmount( amount )
if amount:sub( 1, 1 ) == '+' then
amount = amount:sub( 2 )
end
return amount
end
local function getBestStatements( entity, p )
local tp = type( entity )
if tp == 'string' and mw.wikibase.isValidEntityId( entity ) then
return mw.wikibase.getBestStatements( entity, p )
elseif tp == 'table' and entity.labels then
return entity:getBestStatements( p )
end
return {}
end
local function getTime( statement, p )
local q
if statement and statement.qualifiers and statement.qualifiers[ p ] then
q = statement.qualifiers[ p ][ 1 ]
if q.snaktype == 'value' and q.datatype == 'time' then
q = q.datavalue.value.time
if q:sub( 1, 1 ) ~= '-' then -- B. C.
return q:sub( 1, 11 )
end
end
end
return nil
end
local function getStatements( entity, p, count )
local ar = {}
if not ( isSet( entity ) and isSet( p ) ) then
return ar
end
local statements = getBestStatements( entity, p )
count = math.min( count or #statements, #statements )
if count <= 0 then
return ar
end
local i = 0
local statement, outdated, startTime, endTime
repeat
i = i + 1
statement = statements[ i ].mainsnak
if statement.snaktype == 'value' then
if statement.datatype == 'quantity' then
statement.datavalue.value.amount =
getAmount( statement.datavalue.value.amount )
statement.datavalue.value.unit = getUnitId(
statement.datavalue.value.unit )
end
startTime = getTime( statements[ i ], wd.startTime )
endTime = getTime( statements[ i ], wd.endTime )
if wu.currentTime == '' and ( startTime or endTime ) then
wu.currentTime = '+' .. mw.getContentLanguage():formatDate( 'c' ):sub( 1, 10 )
end
if startTime and wu.currentTime < startTime then
outdated = true
else
outdated = endTime and wu.currentTime > endTime
end
if not outdated then
table.insert( ar, statements[ i ] )
end
end
until i >= #statements or #ar >= count
return ar
end
function wu.getValue( entity, p )
local statements = getStatements( entity, p, 1 )
if #statements > 0 then
catTable[ p ] = ''
return statements[ 1 ].mainsnak.datavalue.value
end
return ''
end
function wu.getId( entity, p )
local value = ''
local statements = getStatements( entity, p, 1 )
if #statements > 0 then
value = statements[ 1 ].mainsnak.datavalue.value
value = value.id or ''
if value ~= '' then
catTable[ p ] = ''
end
end
return value
end
function wu.getValues( entity, p, count )
local statements = getStatements( entity, p, count )
if #statements > 0 then
for i = 1, #statements, 1 do
statements[ i ] = statements[ i ].mainsnak.datavalue.value
end
catTable[ p ] = ''
end
return statements
end
function wu.getIds( entity, p, count )
local statements = getStatements( entity, p, count )
if #statements > 0 then
for i = #statements, 1, -1 do
statements[ i ] = statements[ i ].mainsnak.datavalue.value.id
if not statements[ i ] then
table.remove( statements, i )
end
end
if #statements > 0 then
catTable[ p ] = ''
end
end
return statements
end
function wu.getValuesByLang( entity, p, count, lang )
local ar = {}
local statements = getStatements( entity, p )
if #statements > 0 then
local value
for i = 1, #statements, 1 do
value = statements[ i ].mainsnak.datavalue.value
if value.language and lang == value.language then
table.insert( ar, value.text )
end
if count and #ar >= count then
break
end
end
end
if #ar > 0 then
catTable[ p ] = ''
end
return ar
end
-- get values array for monolingual text
function wu.getMonolingualValues( entity, p )
local result = {}
local statements = getStatements( entity, p, nil )
if #statements > 0 and statements[ 1 ].mainsnak.datatype == 'monolingualtext' then
local hyphen, lng, value
catTable[ p ] = ''
for i = 1, #statements, 1 do
value = statements[ i ].mainsnak.datavalue.value
lng = value.language
hyphen = lng:find( '-' )
if hyphen then
lng = lng:sub( 1, hyphen - 1 )
end
if not result[ lng ] then
result[ lng ] = value.text
end
end
end
return result
end
function wu.getValuesByQualifier( entity, p, qualifierP, defaultId )
local result = {}
if not isSet( qualifierP ) then
return result
elseif type( defaultId ) ~= 'string' or defaultId == '' then
defaultId = 'unknown'
end
local statements = getStatements( entity, p, nil )
if #statements > 0 then
catTable[ p ] = ''
local id, statement, value
for i = 1, #statements do
statement = statements[ i ]
-- defaultId is used if a qualifier is missing
id = defaultId
value = statement.mainsnak.datavalue.value
if statement.qualifiers and statement.qualifiers[ qualifierP ] then
for j, qualifier in ipairs( statement.qualifiers[ qualifierP ] ) do
if qualifier.snaktype == 'value' then
id = qualifier.datavalue.value.id
if id then
catTable[ qualifierP ] = ''
break
end
end
end
end
result[ id ] = value
end
end
return result
end
local function analyzeDatavalue( datavalue, labelFct, ... )
local v = datavalue.value
local t = datavalue.type
if type( v ) == 'table' then
-- items which can be reduced to a string
if t == 'wikibase-entityid' then
v = v.id
if type( labelFct ) == 'function' then
v = labelFct( v, ... )
end
elseif t == 'quantity' then
v.amount = getAmount( v.amount )
if tonumber( v.amount ) == 0 then
v.amount = '0'
end
if v.unit == '1' then
v = tonumber( v.amount ) or 1
else
v.unit = getUnitId( v.unit )
end
elseif t == 'time' then
v.calendarmodel = getUnitId( v.calendarmodel )
if wd.gregorianCalendar[ v.calendarmodel ] then -- is gregorian calendar?
v = v.time
end
end
end
return v, t
end
-- for qualifiers, references
-- { item1, item2, ... } : using named qualifiers/references
-- {} : using no qualifiers/references
-- nil : using all qualifiers/references
function wu.getValuesWithQualifiers( entity, p, values, qualifiers, references,
count, labelFct, ... )
local array, qual
local function toQualifierTable( tab, key, qualTab, aLabelFct, ... )
local v
if not tab[ key ] then
tab[ key ] = {}
end
for i = 1, #qualTab do
qual = qualTab[ i ]
if qual.snaktype == 'value' then
v, tab[ key .. '-type' ] =
analyzeDatavalue( qual.datavalue, aLabelFct, ... )
table.insert( tab[ key ], v )
end
end
if #tab[ key ] == 0 then
tab[ key ] = nil
tab[ key .. '-type' ] = nil
else
catTable[ key ] = ''
end
end
local function hasValue( tab, val )
for i = 1, #tab do
if tab[ i ] == val then
return true
end
end
return false
end
local results = {}
local statements = getStatements( entity, p, count )
if #statements == 0 then
return results
end
local v
if type( values ) == 'table' and #values > 0 then
for i = #statements, 1, -1 do
v = statements[ i ].mainsnak.datavalue.value
if type( v ) ~= 'string' then
v = v.id
end
if not isSet( v ) or not hasValue( values, v ) then
table.remove( statements, i )
end
end
if #statements == 0 then
return results
end
end
catTable[ p ] = ''
if type( qualifiers ) == 'string' then
qualifiers = { qualifiers }
end
if type( references ) == 'string' then
references = { references }
end
local reference, statement
for i = 1, #statements do
statement = statements[ i ]
array = { value = analyzeDatavalue( statement.mainsnak.datavalue, labelFct, ... ),
[ 'value-type' ] = statement.mainsnak.datavalue.type }
if statement.qualifiers then
if not qualifiers then -- all qualifier properties
for key, qualTab in pairs( statement.qualifiers ) do
toQualifierTable( array, key, qualTab, labelFct, ... )
end
else -- table of selected qualifier properties
local key
for j = 1, #qualifiers do
key = qualifiers[ j ]
if statement.qualifiers[ key ] then
toQualifierTable( array, key, statement.qualifiers[ key ], labelFct, ... )
end
end
end
end
array.references = {}
if statement.references then
for k = 1, #statement.references do
reference = statement.references[ k ]
if reference and reference.snaks then
table.insert( array.references, {} )
if not references then -- all references
for key2, refTab in pairs( reference.snaks ) do
toQualifierTable( array.references[ #array.references ],
key2, refTab )
end
else -- table of selected references
local key
for j = 1, #references do
key = references[ j ]
if reference.snaks[ key ] then
toQualifierTable( array.references[ #array.references ],
key, reference.snaks[ key ] )
end
end
end
end
end
end
table.insert( results, array )
end
-- clustering statements with identical value
local helper = {}
local sort1 = 0
local mult = false
local result
for i = 1, #results do
result = results[ i ]
if helper[ result.value ] then
helper[ result.value ].sort2 = helper[ result.value ].sort2 + 1
mult = true
else
sort1 = sort1 + 1
helper[ result.value ] = { sort1 = sort1, sort2 = 1 }
end
result.sort1 = helper[ result.value ].sort1
result.sort2 = helper[ result.value ].sort2
end
if sort1 > 1 and mult and #results > 2 then
table.sort( results,
function( a, b )
return a.sort1 < b.sort1 or
( a.sort1 == b.sort1 and a.sort2 < b.sort2 )
end
)
end
return results
end
-- extract date from time
function wu.getDateFromTime( t )
local model = '' -- is Gregorian
if type( t ) == 'table' then
model = t.calendarmodel
t = t.time
end
t = t:sub( 2, 11 )
return t, model
end
-- get lastEdit from reference retrieve date
function wu.getLastedit( lastEdit, statements )
local isBoolean = type( lastEdit ) == 'boolean'
if isBoolean and lastEdit == false then
return lastEdit
end
local le = ''
for i, statement in ipairs( statements ) do
if statement.references then
for j, reference in ipairs( statement.references ) do
if reference[ wd.retrieved ] then
for k, retrieved in ipairs( reference[ wd.retrieved ] ) do
retrieved = wu.getDateFromTime( retrieved )
if retrieved > le then
le = retrieved
end
end
end
end
end
end
if isBoolean then
return ( le ~= '' ) and le or lastEdit
else
return ( le > lastEdit ) and le or lastEdit
end
end
-- maintenance utilities
function wu.getCategories( formatStr )
if not isSet( formatStr ) then
formatStr = '[[Category:%s]]'
end
catTable.P0 = nil
local result = ''
for key, value in pairs( catTable ) do
result = result .. formatStr:format( key )
end
return result
end
return wu
ogl61n34alfole8xstr51rzb3o5e5zr
Diskuse s uživatelem:OndraMix
3
1324
22113
21374
2026-05-20T13:24:12Z
LiMr
96
nová sekce /* Aktualizace mapových modulů */
22113
wikitext
text/x-wiki
== Šablony s mapami ==
Díky za založení těch mapových šablon. Zatím jsem udělal nějaké rychlé překlady z němčiny, ale mám v plánu spolupracovat ještě víc. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 4. 10. 2024, 22:30 (CEST)
:Děkuju za pomoc s překlady a odchycení překlepů. Teď plánuju překládat nové moduly a založit dokumentaci k [[Šablona:Bod|šabloně Bod]]. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 5. 10. 2024, 22:40 (CEST)
== Modul:Exchangerate ==
Už dřív založil [[Modul:Exchangerate]] z enwikivoyage. Až se mně ji podařilo přeložit a propojit úspěšně s šablonami, tak jsem narážel na nějaké problémy a sám jsem uvažoval, že přejdu na německou verzi. Teď jsi vytvořil [[Modul:Exchange rate]] z dewikivoyage. Ten jsem zkusil opět lokalizovat a napasovat na existující šablony. Teď se mně to zdá všechno funkční a čerpám i z výhod té německé verze. Předpokládám, že tu anglickou už můžeme úplně smazat. Oprávnění k tomu mám, ale chtěl bych to od někoho potvrdit.
Ještě bych chtěl zmínit, že obě verze mají jeden zásadní problém. Přestože vypadají, že se kurzy automaticky aktualizují, tak ve skutečnosti byl kurz z února 2023, kdy byl naposled aktualizovaný robotem. Teď jsem to aktualizoval po roce a půl ručně. Mám v plánu to občas aktualizovat. Spíš se divím, že to tak dlouhou dobu nikomu nechybělo. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 5. 10. 2024, 23:59 (CEST)
:Ten modul z enwikivoyage je na smazání. Používá se jen u [[Šablona:Kurz|šablony Kurz]], což mi přijde, že je duplicita [[Šablona:Měna|šablony Měna]]. Když už budeš mazat ten modul, tak bych tě chtěl poprosit abys smazal i článek [[Vorlage:VCard/styles.css]], který jsem založil omylem.
:S těmi kurzy to je skutečně zarážející, že to nikomu tak dlouho nevadilo. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 6. 10. 2024, 00:21 (CEST)
::Tvoji žádost o smazání jsem vyřešil.
::Šablony [[:Šablona:Kurz]] a [[:Šablona:Měna]] jsou si opravdu hodně podobné. Vypadá to, že Měna je taková vyšší úroveň a má sloužit pro zapisování částek v cizích měnách např. někde v textu. Kurz obsahuje spíš různé pomocné informace. Kurz ale momentálně není nikde používaný a to ani v šabloně Měna. Přesto jsem udělal úpravy, aby byl závislý pouze na novém modulu [[Modul:Exchange rate]].
::Omlouvám se, ale nahoře jsem to napsal blbě. Původní modul [[Modul:Exchangerate]] (včetně šablony Měna) jsem nezakládal já, ale [[:Uživatel:Polda18]]. Já jsem jen pak dělal nějaké úpravy, aby to celé lepší fungovalo. Proto bych před definitivním smazáním původního modulu počkal aspoň týden, aby měl případný čas se k tomu vyjádřit i on. Pak bych to smazal. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 12:06 (CEST)
:::(Sorry in English) hello I'm Tmv from Japanese Wikivoyage. I will leave a note about the Exchange rate. It is a known issue that the Commons data has not been updated, as stated on the [[:de:Modul:Exchange_rate/Doku|German documentation page]]. However, at this moment we have no alternative. For this reason, some Wikivoyage communities including German and Japanese ones have chosen not to use the currency conversion feature.
:::Sorry for the delay, but welcome to the Wikivoyage community! --[[Uživatel:Tmv|Tmv]] ([[Diskuse s uživatelem:Tmv|diskuse]]) 6. 10. 2024, 13:19 (CEST)
:::Šablona {{tl|Kurz}} měla být používána v průvodcích týkající se země, ve které se platí danou měnou, na kterou se ten kurz vztahuje. Zakládal jsem různé technické šablony z envoy, kde se musím přiznat, že jsem se v tom sám moc nevyznal, jaký v tom měli guláš. Pokud se šablona smaže, včetně jejího modulu, tak mi to vadit zřejmě nebude. Jazyku Lua moc nerozumím, takže jsem je v podstatě jen překopíroval (s odkazem na originál samozřejmě) a doufal, že někdo technicky znalejší by to mohl přeložit a případně opravit. Těch rozbitých a polofunkčních šablon a modulů je více. [[Uživatel:Polda18|Polda18]] ([[Diskuse s uživatelem:Polda18|diskuse]]) 6. 10. 2024, 13:59 (CEST)
:::Super, Modul:Exchangerate jsem smazal a jedna duplicita je pryč a máme jen [[Modul:Exchange rate]].
:::Co se týká [[:Šablona:Kurz]], tak tu zatím nechám. Zkusíme víc používat [[:Šablona:Měna]] a uvidíme, co nám bude chybět a jestli nám šablona Kurz nepomůže. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 15:03 (CEST)
::::Dobrá. Kdyby bylo potřeba něco upravit nebo dodělat, jsem k dispozici, určitě se můžeme na něčem domluvit. Nemám problém se případně doučit jazyk Lua, abych mohl navrhovat úpravy modulů nebo moduly nové. Pro testovací účely si mohu udělat testovací wiki na localhostu. [[Uživatel:Polda18|Polda18]] ([[Diskuse s uživatelem:Polda18|diskuse]]) 8. 10. 2024, 11:28 (CEST)
== Modul:VCard/i18n - název ==
Vidím, že experimentuješ s názvy parametrů na svém pískovišti a něco tam nefunguje. Asi to bude tím, že jsem změnil český název parametru v Modul:VCard/i18n. Původně tam bylo "jméno" a změnil jsem to na "název". Přijde mně to vhodnější. Je spíš "název místa" než "jméno místa". I v několika dalších překladech jsem původní "name" přeložil radši jako "název". Omlouvám se, pokud jsi díky tomu ztratil čas hledáním chyby. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 23:18 (CEST)
:Název je určitě vhodnější než jméno. Jak toho teď překládám hodně, tak si takovéto věci občas neuvědomím. Děkuju za upozornění. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 7. 10. 2024, 09:59 (CEST)
== Šablona:GPX indicator ==
Ahoj, teď jsem zkoumal, proč pořád nefunguje [[:Šablona:GPX indicator]], která se automaticky vkládá přes [[:Šablona:Pagebanner]], ale to asi bude fungovat až tady s těmi šablonami, které se teď vytváří. Ono je to navázané přes externí tool, tak k tomu moc nejde dohledat. Tak ať víš ještě o související šabloně, která vlastně není nikde vidět, ale projeví se jako ikona GPX vpravo nahoře.
Ještě procházím všechny šablony, které často ani nejsou kategorizované, takže jsou těžko dohledatelné, a dělám v nich trochu pořádek a objevuju spoustu nových ještě nepoužitých.
Přemýšlím, jestli tyto nové, na kterých právě pracuješ, zařadit i do kategorie Geografických nebo ne. Sice teoreticky můžou být použité jen jako prosté seznamy bez souřadnic a map, ale v principu je bude lepší mít jednoduše mezi geografickými, protože to je jejich hlavní účel. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2024, 16:21 (CEST)
:Děkuju za upozornění na šablonu GPX indicator, po letmém zhlédnutí mě napadlo jestli tomu nevadí jazyk čeština. Kdyžtak na [[:de:MediaWiki:Gadget-Poi2gpx.js|německých wikicestách]] mají asi trochu jinak (nedíval jsem se na to nějak detailněji). Šablony bod i mapa bych určitě vložil do geografických šablon. Někdy o víkendu bych se podíval na tu šablonu jestli se to do té doby nepodaří vyřešit a dodělal překlady a dokumentace. Momentálně nemám moc volného času. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 9. 10. 2024, 16:54 (CEST)
:Já jsem ji původně bral jako jednu z podmínek k fungování toho nového Pagebanneru, tak jsem to nezkoumal, když tam nebyla ani dokumentace. Ten jazyk jsem taky zkoušel a při změně jazyka to funguje, ale odněkud si musí vzít ta data. Není tam v podstatě nic než konkrétní URL. Podle mě to si to webserver stáhne ze zadaných wikicest, zpracuje a vrátí hotový soubor. Na tu německou verzi jsem se díval až teď a dělá to asi stejnou věc, ale technologicky úplně jinak. Na první pohled odhaduju, že soubor je vygenerovaný na straně klienta pomocí Javascriptu. Německý přístup se mně líbí víc, protože se to dá nějak přizpůsobit a není to závislé na dalších službách. Až to bude použité na reálných stránkách, tak se to může vyzkoušet. A taky jestli není lepší způsob než paušální vkládání než přes pagebanner.
:Každopádně díky za super práci! Je dobré tu mít dalšího odborníka :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2024, 17:12 (CEST)
== Problémy Geo šablony ==
Ahoj, zkusil jsem řešit problémy, proč jsou stránky občas v této kategorii: [[:Kategorie:Stránky s nesprávnými značkami zeměpisných souřadnic]]. Může za to {{Šablona|Geo}}, ve které se uvnitř nějak špatně předávají souřadnice nebo ve špatných formátech apod. Věnoval jsem tomu už dost času a nemůžu přijít na problém. Spíš jsem hledal konkrétní problém a konkrétní opravu, ale možná jsou tam složitě použité některé šablony a moduly, nebo je potřeba je nahradit jinými. Myslím, že by tento problém mohl souviset i s jinými problémy, které se týkají souřadnic. Jestli budeš mít někdy čas, zkus se na to prosím taky podívat, jestli něco objevíš. Na testování je vhodný článek [[Zlín]], který neobsahuje další geografické šablony. Díky [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 31. 1. 2025, 13:48 (CET)
:Podívám se na to. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 31. 1. 2025, 14:00 (CET)
:To vypadá, že už [[:Modul:Coord]] předané souřadnice formátuje nějak jinak, než se očekává. Ale ty souřadnice se zanoří postupně do tolika modulů, že nevím, co všechno by ovlivnila jakákoliv změna. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 31. 1. 2025, 16:04 (CET)
::Myslím že jsem to nějak opravil, [[Šablona:Coord|šablona Coord]] měla odkazovat na [[Modul:Coord|modul Coord]], ale odkazovala na [[Modul:Coordinates|Coordinates]]. Tohle je jen konkrétní oprava, nerozumím teď tomu jak ty moduly formátují souřadnice. Jinak stále je u [[Šablona:Geo|šablony Geo]] peoblém že na mapě zobrazuje body z enwikivoy a na českou ji nelze přepnout, proto jsem pracoval na [[Šablona:GeoData|šabloně GeoData]], která má aktuálně ale stejnej problém. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 31. 1. 2025, 16:20 (CET)
:::Mohli bychom se vrátit k těm geografickým šablonám. Poslední cíl byl teda to, že by se šablona {{Š|Geo}} nahradila šablonou {{Š|GeoData}}, aby fungovalo otvírání mapy v pravém horním roku? A pořád nevím, jestli je úspěšně přidané [[MediaWiki:Gadget-MapTools.js]], protože se to zatím nijak neprojevuje, ale má to asi pracovat s tou šablonou {{Š|GeoData}}, takže to spolu bude souviset. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 3. 2025, 22:34 (CET)
::::Ahoj,
::::Můj poslední cíl bylo nahradit Geo šablonou GeoData, jelikož nevím jestli je možné, aby dobře fungovala (jak to je externí nástroj). GeoData mají aktuálně 2 problémy: nezobrazují body na mapě a neregistrují články, aby se zobrazily když vyberu ''zobrazit články v okolí'' na mapě. Snažil jsem se najít, kde je chyba ale nemůžu to najít. Momentálně mám víc jiné práce a nemám sílu hledat kde v kódu bude chyba. Určitě to nějak souvisí s tím Gadgetem, možná se snaží volat něco co není pro něj dostupné. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 3. 2025, 19:02 (CET)
:::::Tak nakonec mi to nedalo, našel jsem že podle [[:de:Wikivoyage:Gadget-MapTools.js|nápovědy na německých wikicestách]] gadget vyžaduje seznam článků na Wikicestách (externí) a ten pro České Wikicesty [https://wikivoyage.toolforge.org/w/data/cs-articles.js není] (zatímco německé ho [https://wikivoyage.toolforge.org/w/data/de-articles.js mají]) Je to v [[MediaWiki:Gadget-MapTools.js#L-149|řádku 149 gadgetu]] <code>(scriptUrl = mw.format( 'https://wikivoyage.toolforge.org/w/data/$1-articles.js', pageLang ),</code>), tady může vznikat nějaký problém. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 3. 2025, 19:13 (CET)
:::::Konečně jsem vyřešil problém s šablonou {{Šablona|Geo}}. Problém je v tom, že uvnitř tagu indicator se proměnné nepřekládají. Proto musí tento tag generován jinou šablonou. Pak to už funguje. Takže odkaz už funguje, ale samozřejmě to nevyřešilo všechny problémy. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 3. 2025, 23:23 (CET)
== Kategorizace ==
Ahoj, mám jen malou poznámku ke kategorizaci. Na Wikicestách jsou na rozdíl od Wikipedie mnohem důležitější kategorie, které upřesňují ''kde to je'' než ''co to je''. Takže jsou vhodné kategorie, které geograficky upřesňují polohu, i když ne nutně administrativní dělení na kraje (i když je to často nejpohodlnější), ale raději tradiční regiony, hory apod. Prostě když někdo někomu říká, že jede na dovolenou na Šumavu, na Slovácko, do Vysokých Tater, ... Pak možná nějaké výjimečné typy konkrétních turistických cílů, které někdo vyhledává: hrady, lázně, ... To je můj pohled na kategorie v budoucnu :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 15. 4. 2025, 12:21 (CEST)
:Ahoj,
:souhlasím s kategorizací na základě polohy, ale myslím že kategorizace na základě typu je taky důležitá. Kdyby třeba někdo hledal cíle kam jet, třeba že chce jet do hor/na hrad, tak kategorie na základě typu můžou být užitečné pro vyhledání možných cílů. Za mě by byly nejlepší kategorie typu: [(stát/kraj) (typ)], [turistické regiony]; př. Slovinská města, Julské Alpy, Triglavský národní park pro ten [[Bled]]. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 15. 4. 2025, 14:54 (CEST)
== Šablona Bod v Českých Budějovicích ==
Ahoj, pokud bys měl čas a chuť, tak se můžeš podívat na chování {{Šablona|Bod}} v článku [[České Budějovice]]. Musel jsem tam udělat takový hack, aby se to správně zobrazovalo. Problémy jsou tam dva:
* Po odrážkách jsou následující body odsazené i když by neměly být.
* Bod bez souřadnic se nezalomí na nový řádek.
Nebo co si myslíš o takovém použití? Resp. viděl jsem i použití šablony uprostřed textu odstavce, což překvapivě nějak fungovalo, ale oprava výše uvedených problémů by to chování mohla ovlivnit. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 5. 2025, 20:31 (CEST)
:Ahoj,
:podívám se na to, až budu mít trochu víc času. Toho že se šablona někdy nezalomuje na další řádek jsem si už všimnul, to odrážení je pro mě novinka.
:Podle mě je dobré používat bod i do souvislého textu, hlavně kvůli propojení s Wikipedií/Commons..., dodání souřadnic místa do mapy a určitého vizuálního zvýraznění místa. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 5. 2025, 23:05 (CEST)
:Myslím, že mám dobrý postřeh. Problém se zalomením mají dva body po sobě, u kterých není vyplněn žádný popis (možná ani nic víc za ikonami). Pěkný příklad je [[Znojmo]], konkrétně tato verze: https://cs.wikivoyage.org/w/index.php?title=Znojmo&oldid=19492, která má dokonce dvě dvojice takových případů. Přidání parametru popis do kteréhokoliv bodu vyřeší problém v dané dvojici. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 5. 2025, 10:23 (CEST)
== Bod a Wikicesty ==
Ahoj, v článku [[Šumava]] je často použita šablona {{Š|Bod}} pro jednotlivé vrcholy. Teď začalo vznikat hodně článků o těchto jednotlivých vrcholech. Šablona zobrazuje odkazy na Wikipedii, Commons, Wikidata, ..., ale vlastně vůbec neumožňuje prokliknutí na článek na Wikicestách, který by dokonce v principu měl být ten nejdůležitější. Překvapuje mně to o to víc, že podle mě ani originální německá verze toto nemá vyřešeno. Nebo je tam něco, co jsem přehlédl? [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2025, 10:13 (CEST)
:Ahoj, myslím že v kódu je někde ikonka pro Wikicesty zakomentovaná, jelikož dělala chyby. Podívám se na to a zkusím to nějak opravit/dodělat ji tam. Dostanu se na to nejspíš někdy o víkendu. -- [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 9. 10. 2025, 10:47 (CEST)
::Ok, díky. Když se na to ale dívám z uživatelského pohledu, tak bych očekával, že odkaz na samotném názvu by měl vést na Wikicesty. To uživatel očekává. Nevím, jestli náhodný uživatel pozná a pochopí tu správnou malou ikonku za názvem. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2025, 12:58 (CEST)
:::Podíval jsem se na to a teď by šablona měla zobrazovat odkaz na Wikicesty v názvu a odkaz na externí web je řešen pomocí ikonky. Momentálně je nastaveno, že jediný odkaz na externí web je přes ikonku, ale dá se upravit, aby se v případě, že neexistuje odkaz na Wikicesty, zobrazoval externí odkaz i v názvu (viz [[Modul:Marker utilities]], řádek 1476). [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 12. 10. 2025, 05:26 (CEST)
::::Tak to je super! Tak jsem si to představoval. Já jsem to teda ještě upravil tak, jak jsi sám psal. Takže je to takový hybrid mezi tím, co bylo dřív a co jsi udělal. Prostě pokud existuje na Wikicestách, tak je tam odkaz na Wikicesty, pokud ne, tak externí odkaz, nebo pokud není, tak obyčejný text. Sice je tam teď ten externí odkaz ještě i s ikonkou zeměkoule, ale myslím, že to nevadí a kvůli jednotnosti je to možná i dobře.
::::Jinak ještě nějaké technické věci:
::::* Lua používá bool hodnotu false jen s malým f, takže False byla jakoby nedefinovaná proměnná a nebylo to požadované chování.
::::* Pokud už neplánuješ nějaké další úpravy, tak bych v Modul:VCard ještě ten nový kód zjednodušil (aby byl i podobnější tomu původnímu). Zkoušel jsem to a na první pohled jsem tam neviděl problém.
::::* Ještě asi udělám aktualizace celého modulu podle nejnovější verzi na DE Wikivoyage. Snad to něco nenabourá.
::::Jsem fakt rád, že jsi to dokázal a že se aspoň občas něco zlepšuje i technicky. Díky! [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 10. 2025, 12:47 (CEST)
:::::Určite jen do toho, nějaké úpravy v nejbližší době neplánuji. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 13. 10. 2025, 15:24 (CEST)
:::::Zjednodušení jsem udělal. A i celá aktualizace proběhla docela bez problémů. Novinkou jsou např. odkazy na mapy u šablony {{Š|Bod}}. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 10:34 (CEST)
::::::Výborně, s tou mapou to vypadá moc dobře. Jen jsem si všiml, že po aktualizaci zmizela ikonka Wikidat ([[Šablona:VCard/styles.css]]). Otázka je, jestli je vůbec vhodné ji tam mít – za mě je docela užitečná, protože se dá jedním kliknutím přejít na Wikidata a upravit tam, ale pro běžného čtenáře asi takový význam nemá.
::::::Další změna je, že pokud existuje článek na Wikicestách, už nejde do šablony {{šablona|Bod}} přidat web místa (viz [[Šablona:Bod/test]] → ODKAZ NA WIKICESTY → druhý odkaz na Pražský hrad nebo druhý Třístoličník). [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 10. 2025, 11:04 (CEST)
:::::::Já jsem věděl, že je dobré, když se na to podívá ještě někdo jiný :) Toho jsem si nevšiml a už jsem to vrátil. Byla to ruční úprava, která se aktualizací přepsala. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 17:06 (CEST)
:::::::Tak to jsem už taky opravil. Bylo to záludné, protože právě ta tebou speciálně upravená část kódu byla přesunuta do jiného modulu a už jsem to neuhlídal. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 18:14 (CEST)
== Šablona Geo - Zobrazit články v okolí ==
Podařilo se mně zase trochu vylepšit ty věci kolem šablony {{Š|Geo}}. Volám ji automaticky s parametry z Wikidat pomocí {{Š|Pagebanner}}, takže je automaticky ve všech článcích, kde je tato šablona a kde jsou definované souřadnice, tzn. fakt skoro všechny. Funguje pak i to tlačítko Zobrazit články v okolí, což je super, aby bylo vidět, které články jsou založené poblíž jiného článku. Ještě trvá problém s tím, že ikona vpravo nahoře otevře jinou mapu, kde ty články v okolí nejsou, ale na to se ještě jednou podívám. Je potřeba otevřít mapu, která je vložena pomocí šablony {{Š|Mapa}}. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 10. 2025, 14:13 (CEST)
:Skvělá práce, u toho {{šablona|Geo}} je problém s {{šablona|PoiMap2}}, že ten web nemá českou verzi, která by přebírala data z českých Wikicesty. Napadlo mě to obejít přes [[Modul:Mapframe|modul Mapframe]], ale momentálně na to nemám moc času. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 13. 10. 2025, 15:35 (CEST)
::Přesně to napadlo i mě. Nakonec jsem udělal samostatnou šablonu {{Š|Maplink}}, která je ale v podstatě to samé (i stejný modul). Zdá se to být funkční a asi to tak nechám. Chtěl jsem to ještě nějak vizuálně vylepšit, ale moc mně to nejde. Ještě pořád si nejsu jistý, jestli to dělat tak plně automaticky přes šablonu {{Š|Pagebanner}}. Zatím to funguje dobře, jen možná parametr pro zoom mapy by mohl být zadaný ručně a v tom případě by bylo lepší mít samostatnou šablonu. Ale jestli vůbec má cenu mít na každé stránce vloženou šablonu <nowiki>{{Geo}}</nowiki> (výchozí zoom) a jen výjimečně něco jako <nowiki>{{Geo|zoom=10}}</nowiki>. Ale nevyužité šablony jako např. {{Š|PoiMap2}} už asi můžu odstranit. Budu rád, když si najdeš trochu času a ještě se zkusíš podívat, co dál by šlo vylepšit, protože v tomto se orientuješ velice dobře :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 10:53 (CEST)
:::Výborně, nevyužité šablony jako {{šablona|PoiMap2}} a {{šablona|GeoData}} už jsou zbytečné. Jen bude potřeba upravit ještě {{šablona|Geo}}, aby už PoiMap2 nepoužívala.
::: Se zoomem asi nic moc dělat nepůjde – ruční zadávání by sice asi šlo přímo do {{šablona|Pagebanner}} (který by si to pak převzal do Geo části), ale to mi přijde zbytečně zatěžující. Možná by šlo zkusit vymyslet způsob, jak by se zoom určoval automaticky podle typu místa. Až budu mít víc času, podívám se na to podrobněji, teď mě ale čeká docela dost zápočtových testů, tak nevím úplně kdy přibližně to bude. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 10. 2025, 11:17 (CEST)
::::PoiMap2 jsem odstranil. Ta nepůjde využít asi nikdy. GeoData jsem ještě nechal. Na tu jsem už zapomněl. Vypadá ještě do budoucna užitečně, i když zatím moc využitá není. Ten automatický zoom podle typu z Wikidat mně taky napadl, ale to bude až taková třešnička. Zatím jsem narazil na větší problém. V náhledu všechno funguje, ale při normálním zobrazení se ten indikátor se souřadnicemi v některých článcích vůbec neukáže. A jestli se ukáže, tak vypadá jinak, než v tom náhledu (bez textových souřadnic). Myslel jsem, že ten chybějící indikátor bude chtít čas na vyprázdnění cache, ale pořád to nejde. Takové věci se hledají blbě, když je chování v náhledu jiné :( [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 15. 10. 2025, 13:21 (CEST)
== Chybějící města na mapě ==
Ahoj, ptám se tě jako specialisty na mapovou šablonu. :) Nevíš, proč se v článku [[Jihočeský kraj]] neukazují na mapě města, ale ostatní místa se ukazují? Je to neznámým typem objektu? Když u toho bodu natvrdo nastavím typ, tak se ukáže, ale nevidím důvod, proč by to nemělo ukazovat města. Navíc v článku [[Itálie]] se města normálně ukazují. Možná je problém s tím, že česká města jsou ve Wikidatech založena jako instance "obec v Česku" nebo "město v Česku", ale už ne obyčejné "město". Takže možná je to fakt neznámý objekt a takové objekty to neukazuje. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 25. 11. 2025, 18:12 (CET)
:Aha, tak už jsem to opravil sám. Po dřívější aktualizaci nebylo přeložené jedno slovo v [[Modul:Marker utilities/Groups]]. Někdy stačí napsat dotaz, abych dostal další nápad. :) Ale s těmi městy na mapě mám ještě nějaké větší plány, tak se to bude hodit. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 25. 11. 2025, 18:17 (CET)
== Aktualizace mapových modulů ==
Ahoj, právě jsem provedl asi největší aktualizaci všech těch mapových modulů, šablon a stylů za poslední dobu. Kvůli kontrole s předchozími ručními úpravami to bylo pracnější, než jsem myslel, ale vypadá to, že se všechno podařilo. Mým hlavním důvodem byly chybějící snad všechny ikony, které s tím souvisely, protože WM změnilo velikosti rastrových obrázků generovaných z vektorových. Aktualizoval jsem ale zrovna už všechno, na co jsem narazil. Čekal jsem, že se to zase totálně rozsype, ale zatím to vypadá dobře. V první řadě bych chtěl, aby ses na to aspoň podíval tvýma očima, ať identifikujeme případné problémy. Až pak se případně podíváme na jejich řešení, příp. přeložení nových textů (přeložil jsem zatím jen část).
Díky [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 5. 2026, 15:24 (CEST)
00slnjzwsb8fv2w000ugs6vlisahlca
22114
22113
2026-05-21T09:02:35Z
OndraMix
385
/* Aktualizace mapových modulů */ odpověď
22114
wikitext
text/x-wiki
== Šablony s mapami ==
Díky za založení těch mapových šablon. Zatím jsem udělal nějaké rychlé překlady z němčiny, ale mám v plánu spolupracovat ještě víc. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 4. 10. 2024, 22:30 (CEST)
:Děkuju za pomoc s překlady a odchycení překlepů. Teď plánuju překládat nové moduly a založit dokumentaci k [[Šablona:Bod|šabloně Bod]]. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 5. 10. 2024, 22:40 (CEST)
== Modul:Exchangerate ==
Už dřív založil [[Modul:Exchangerate]] z enwikivoyage. Až se mně ji podařilo přeložit a propojit úspěšně s šablonami, tak jsem narážel na nějaké problémy a sám jsem uvažoval, že přejdu na německou verzi. Teď jsi vytvořil [[Modul:Exchange rate]] z dewikivoyage. Ten jsem zkusil opět lokalizovat a napasovat na existující šablony. Teď se mně to zdá všechno funkční a čerpám i z výhod té německé verze. Předpokládám, že tu anglickou už můžeme úplně smazat. Oprávnění k tomu mám, ale chtěl bych to od někoho potvrdit.
Ještě bych chtěl zmínit, že obě verze mají jeden zásadní problém. Přestože vypadají, že se kurzy automaticky aktualizují, tak ve skutečnosti byl kurz z února 2023, kdy byl naposled aktualizovaný robotem. Teď jsem to aktualizoval po roce a půl ručně. Mám v plánu to občas aktualizovat. Spíš se divím, že to tak dlouhou dobu nikomu nechybělo. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 5. 10. 2024, 23:59 (CEST)
:Ten modul z enwikivoyage je na smazání. Používá se jen u [[Šablona:Kurz|šablony Kurz]], což mi přijde, že je duplicita [[Šablona:Měna|šablony Měna]]. Když už budeš mazat ten modul, tak bych tě chtěl poprosit abys smazal i článek [[Vorlage:VCard/styles.css]], který jsem založil omylem.
:S těmi kurzy to je skutečně zarážející, že to nikomu tak dlouho nevadilo. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 6. 10. 2024, 00:21 (CEST)
::Tvoji žádost o smazání jsem vyřešil.
::Šablony [[:Šablona:Kurz]] a [[:Šablona:Měna]] jsou si opravdu hodně podobné. Vypadá to, že Měna je taková vyšší úroveň a má sloužit pro zapisování částek v cizích měnách např. někde v textu. Kurz obsahuje spíš různé pomocné informace. Kurz ale momentálně není nikde používaný a to ani v šabloně Měna. Přesto jsem udělal úpravy, aby byl závislý pouze na novém modulu [[Modul:Exchange rate]].
::Omlouvám se, ale nahoře jsem to napsal blbě. Původní modul [[Modul:Exchangerate]] (včetně šablony Měna) jsem nezakládal já, ale [[:Uživatel:Polda18]]. Já jsem jen pak dělal nějaké úpravy, aby to celé lepší fungovalo. Proto bych před definitivním smazáním původního modulu počkal aspoň týden, aby měl případný čas se k tomu vyjádřit i on. Pak bych to smazal. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 12:06 (CEST)
:::(Sorry in English) hello I'm Tmv from Japanese Wikivoyage. I will leave a note about the Exchange rate. It is a known issue that the Commons data has not been updated, as stated on the [[:de:Modul:Exchange_rate/Doku|German documentation page]]. However, at this moment we have no alternative. For this reason, some Wikivoyage communities including German and Japanese ones have chosen not to use the currency conversion feature.
:::Sorry for the delay, but welcome to the Wikivoyage community! --[[Uživatel:Tmv|Tmv]] ([[Diskuse s uživatelem:Tmv|diskuse]]) 6. 10. 2024, 13:19 (CEST)
:::Šablona {{tl|Kurz}} měla být používána v průvodcích týkající se země, ve které se platí danou měnou, na kterou se ten kurz vztahuje. Zakládal jsem různé technické šablony z envoy, kde se musím přiznat, že jsem se v tom sám moc nevyznal, jaký v tom měli guláš. Pokud se šablona smaže, včetně jejího modulu, tak mi to vadit zřejmě nebude. Jazyku Lua moc nerozumím, takže jsem je v podstatě jen překopíroval (s odkazem na originál samozřejmě) a doufal, že někdo technicky znalejší by to mohl přeložit a případně opravit. Těch rozbitých a polofunkčních šablon a modulů je více. [[Uživatel:Polda18|Polda18]] ([[Diskuse s uživatelem:Polda18|diskuse]]) 6. 10. 2024, 13:59 (CEST)
:::Super, Modul:Exchangerate jsem smazal a jedna duplicita je pryč a máme jen [[Modul:Exchange rate]].
:::Co se týká [[:Šablona:Kurz]], tak tu zatím nechám. Zkusíme víc používat [[:Šablona:Měna]] a uvidíme, co nám bude chybět a jestli nám šablona Kurz nepomůže. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 15:03 (CEST)
::::Dobrá. Kdyby bylo potřeba něco upravit nebo dodělat, jsem k dispozici, určitě se můžeme na něčem domluvit. Nemám problém se případně doučit jazyk Lua, abych mohl navrhovat úpravy modulů nebo moduly nové. Pro testovací účely si mohu udělat testovací wiki na localhostu. [[Uživatel:Polda18|Polda18]] ([[Diskuse s uživatelem:Polda18|diskuse]]) 8. 10. 2024, 11:28 (CEST)
== Modul:VCard/i18n - název ==
Vidím, že experimentuješ s názvy parametrů na svém pískovišti a něco tam nefunguje. Asi to bude tím, že jsem změnil český název parametru v Modul:VCard/i18n. Původně tam bylo "jméno" a změnil jsem to na "název". Přijde mně to vhodnější. Je spíš "název místa" než "jméno místa". I v několika dalších překladech jsem původní "name" přeložil radši jako "název". Omlouvám se, pokud jsi díky tomu ztratil čas hledáním chyby. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 6. 10. 2024, 23:18 (CEST)
:Název je určitě vhodnější než jméno. Jak toho teď překládám hodně, tak si takovéto věci občas neuvědomím. Děkuju za upozornění. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 7. 10. 2024, 09:59 (CEST)
== Šablona:GPX indicator ==
Ahoj, teď jsem zkoumal, proč pořád nefunguje [[:Šablona:GPX indicator]], která se automaticky vkládá přes [[:Šablona:Pagebanner]], ale to asi bude fungovat až tady s těmi šablonami, které se teď vytváří. Ono je to navázané přes externí tool, tak k tomu moc nejde dohledat. Tak ať víš ještě o související šabloně, která vlastně není nikde vidět, ale projeví se jako ikona GPX vpravo nahoře.
Ještě procházím všechny šablony, které často ani nejsou kategorizované, takže jsou těžko dohledatelné, a dělám v nich trochu pořádek a objevuju spoustu nových ještě nepoužitých.
Přemýšlím, jestli tyto nové, na kterých právě pracuješ, zařadit i do kategorie Geografických nebo ne. Sice teoreticky můžou být použité jen jako prosté seznamy bez souřadnic a map, ale v principu je bude lepší mít jednoduše mezi geografickými, protože to je jejich hlavní účel. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2024, 16:21 (CEST)
:Děkuju za upozornění na šablonu GPX indicator, po letmém zhlédnutí mě napadlo jestli tomu nevadí jazyk čeština. Kdyžtak na [[:de:MediaWiki:Gadget-Poi2gpx.js|německých wikicestách]] mají asi trochu jinak (nedíval jsem se na to nějak detailněji). Šablony bod i mapa bych určitě vložil do geografických šablon. Někdy o víkendu bych se podíval na tu šablonu jestli se to do té doby nepodaří vyřešit a dodělal překlady a dokumentace. Momentálně nemám moc volného času. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 9. 10. 2024, 16:54 (CEST)
:Já jsem ji původně bral jako jednu z podmínek k fungování toho nového Pagebanneru, tak jsem to nezkoumal, když tam nebyla ani dokumentace. Ten jazyk jsem taky zkoušel a při změně jazyka to funguje, ale odněkud si musí vzít ta data. Není tam v podstatě nic než konkrétní URL. Podle mě to si to webserver stáhne ze zadaných wikicest, zpracuje a vrátí hotový soubor. Na tu německou verzi jsem se díval až teď a dělá to asi stejnou věc, ale technologicky úplně jinak. Na první pohled odhaduju, že soubor je vygenerovaný na straně klienta pomocí Javascriptu. Německý přístup se mně líbí víc, protože se to dá nějak přizpůsobit a není to závislé na dalších službách. Až to bude použité na reálných stránkách, tak se to může vyzkoušet. A taky jestli není lepší způsob než paušální vkládání než přes pagebanner.
:Každopádně díky za super práci! Je dobré tu mít dalšího odborníka :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2024, 17:12 (CEST)
== Problémy Geo šablony ==
Ahoj, zkusil jsem řešit problémy, proč jsou stránky občas v této kategorii: [[:Kategorie:Stránky s nesprávnými značkami zeměpisných souřadnic]]. Může za to {{Šablona|Geo}}, ve které se uvnitř nějak špatně předávají souřadnice nebo ve špatných formátech apod. Věnoval jsem tomu už dost času a nemůžu přijít na problém. Spíš jsem hledal konkrétní problém a konkrétní opravu, ale možná jsou tam složitě použité některé šablony a moduly, nebo je potřeba je nahradit jinými. Myslím, že by tento problém mohl souviset i s jinými problémy, které se týkají souřadnic. Jestli budeš mít někdy čas, zkus se na to prosím taky podívat, jestli něco objevíš. Na testování je vhodný článek [[Zlín]], který neobsahuje další geografické šablony. Díky [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 31. 1. 2025, 13:48 (CET)
:Podívám se na to. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 31. 1. 2025, 14:00 (CET)
:To vypadá, že už [[:Modul:Coord]] předané souřadnice formátuje nějak jinak, než se očekává. Ale ty souřadnice se zanoří postupně do tolika modulů, že nevím, co všechno by ovlivnila jakákoliv změna. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 31. 1. 2025, 16:04 (CET)
::Myslím že jsem to nějak opravil, [[Šablona:Coord|šablona Coord]] měla odkazovat na [[Modul:Coord|modul Coord]], ale odkazovala na [[Modul:Coordinates|Coordinates]]. Tohle je jen konkrétní oprava, nerozumím teď tomu jak ty moduly formátují souřadnice. Jinak stále je u [[Šablona:Geo|šablony Geo]] peoblém že na mapě zobrazuje body z enwikivoy a na českou ji nelze přepnout, proto jsem pracoval na [[Šablona:GeoData|šabloně GeoData]], která má aktuálně ale stejnej problém. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 31. 1. 2025, 16:20 (CET)
:::Mohli bychom se vrátit k těm geografickým šablonám. Poslední cíl byl teda to, že by se šablona {{Š|Geo}} nahradila šablonou {{Š|GeoData}}, aby fungovalo otvírání mapy v pravém horním roku? A pořád nevím, jestli je úspěšně přidané [[MediaWiki:Gadget-MapTools.js]], protože se to zatím nijak neprojevuje, ale má to asi pracovat s tou šablonou {{Š|GeoData}}, takže to spolu bude souviset. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 3. 2025, 22:34 (CET)
::::Ahoj,
::::Můj poslední cíl bylo nahradit Geo šablonou GeoData, jelikož nevím jestli je možné, aby dobře fungovala (jak to je externí nástroj). GeoData mají aktuálně 2 problémy: nezobrazují body na mapě a neregistrují články, aby se zobrazily když vyberu ''zobrazit články v okolí'' na mapě. Snažil jsem se najít, kde je chyba ale nemůžu to najít. Momentálně mám víc jiné práce a nemám sílu hledat kde v kódu bude chyba. Určitě to nějak souvisí s tím Gadgetem, možná se snaží volat něco co není pro něj dostupné. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 3. 2025, 19:02 (CET)
:::::Tak nakonec mi to nedalo, našel jsem že podle [[:de:Wikivoyage:Gadget-MapTools.js|nápovědy na německých wikicestách]] gadget vyžaduje seznam článků na Wikicestách (externí) a ten pro České Wikicesty [https://wikivoyage.toolforge.org/w/data/cs-articles.js není] (zatímco německé ho [https://wikivoyage.toolforge.org/w/data/de-articles.js mají]) Je to v [[MediaWiki:Gadget-MapTools.js#L-149|řádku 149 gadgetu]] <code>(scriptUrl = mw.format( 'https://wikivoyage.toolforge.org/w/data/$1-articles.js', pageLang ),</code>), tady může vznikat nějaký problém. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 3. 2025, 19:13 (CET)
:::::Konečně jsem vyřešil problém s šablonou {{Šablona|Geo}}. Problém je v tom, že uvnitř tagu indicator se proměnné nepřekládají. Proto musí tento tag generován jinou šablonou. Pak to už funguje. Takže odkaz už funguje, ale samozřejmě to nevyřešilo všechny problémy. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 3. 2025, 23:23 (CET)
== Kategorizace ==
Ahoj, mám jen malou poznámku ke kategorizaci. Na Wikicestách jsou na rozdíl od Wikipedie mnohem důležitější kategorie, které upřesňují ''kde to je'' než ''co to je''. Takže jsou vhodné kategorie, které geograficky upřesňují polohu, i když ne nutně administrativní dělení na kraje (i když je to často nejpohodlnější), ale raději tradiční regiony, hory apod. Prostě když někdo někomu říká, že jede na dovolenou na Šumavu, na Slovácko, do Vysokých Tater, ... Pak možná nějaké výjimečné typy konkrétních turistických cílů, které někdo vyhledává: hrady, lázně, ... To je můj pohled na kategorie v budoucnu :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 15. 4. 2025, 12:21 (CEST)
:Ahoj,
:souhlasím s kategorizací na základě polohy, ale myslím že kategorizace na základě typu je taky důležitá. Kdyby třeba někdo hledal cíle kam jet, třeba že chce jet do hor/na hrad, tak kategorie na základě typu můžou být užitečné pro vyhledání možných cílů. Za mě by byly nejlepší kategorie typu: [(stát/kraj) (typ)], [turistické regiony]; př. Slovinská města, Julské Alpy, Triglavský národní park pro ten [[Bled]]. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 15. 4. 2025, 14:54 (CEST)
== Šablona Bod v Českých Budějovicích ==
Ahoj, pokud bys měl čas a chuť, tak se můžeš podívat na chování {{Šablona|Bod}} v článku [[České Budějovice]]. Musel jsem tam udělat takový hack, aby se to správně zobrazovalo. Problémy jsou tam dva:
* Po odrážkách jsou následující body odsazené i když by neměly být.
* Bod bez souřadnic se nezalomí na nový řádek.
Nebo co si myslíš o takovém použití? Resp. viděl jsem i použití šablony uprostřed textu odstavce, což překvapivě nějak fungovalo, ale oprava výše uvedených problémů by to chování mohla ovlivnit. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 5. 2025, 20:31 (CEST)
:Ahoj,
:podívám se na to, až budu mít trochu víc času. Toho že se šablona někdy nezalomuje na další řádek jsem si už všimnul, to odrážení je pro mě novinka.
:Podle mě je dobré používat bod i do souvislého textu, hlavně kvůli propojení s Wikipedií/Commons..., dodání souřadnic místa do mapy a určitého vizuálního zvýraznění místa. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 5. 2025, 23:05 (CEST)
:Myslím, že mám dobrý postřeh. Problém se zalomením mají dva body po sobě, u kterých není vyplněn žádný popis (možná ani nic víc za ikonami). Pěkný příklad je [[Znojmo]], konkrétně tato verze: https://cs.wikivoyage.org/w/index.php?title=Znojmo&oldid=19492, která má dokonce dvě dvojice takových případů. Přidání parametru popis do kteréhokoliv bodu vyřeší problém v dané dvojici. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 5. 2025, 10:23 (CEST)
== Bod a Wikicesty ==
Ahoj, v článku [[Šumava]] je často použita šablona {{Š|Bod}} pro jednotlivé vrcholy. Teď začalo vznikat hodně článků o těchto jednotlivých vrcholech. Šablona zobrazuje odkazy na Wikipedii, Commons, Wikidata, ..., ale vlastně vůbec neumožňuje prokliknutí na článek na Wikicestách, který by dokonce v principu měl být ten nejdůležitější. Překvapuje mně to o to víc, že podle mě ani originální německá verze toto nemá vyřešeno. Nebo je tam něco, co jsem přehlédl? [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2025, 10:13 (CEST)
:Ahoj, myslím že v kódu je někde ikonka pro Wikicesty zakomentovaná, jelikož dělala chyby. Podívám se na to a zkusím to nějak opravit/dodělat ji tam. Dostanu se na to nejspíš někdy o víkendu. -- [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 9. 10. 2025, 10:47 (CEST)
::Ok, díky. Když se na to ale dívám z uživatelského pohledu, tak bych očekával, že odkaz na samotném názvu by měl vést na Wikicesty. To uživatel očekává. Nevím, jestli náhodný uživatel pozná a pochopí tu správnou malou ikonku za názvem. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 9. 10. 2025, 12:58 (CEST)
:::Podíval jsem se na to a teď by šablona měla zobrazovat odkaz na Wikicesty v názvu a odkaz na externí web je řešen pomocí ikonky. Momentálně je nastaveno, že jediný odkaz na externí web je přes ikonku, ale dá se upravit, aby se v případě, že neexistuje odkaz na Wikicesty, zobrazoval externí odkaz i v názvu (viz [[Modul:Marker utilities]], řádek 1476). [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 12. 10. 2025, 05:26 (CEST)
::::Tak to je super! Tak jsem si to představoval. Já jsem to teda ještě upravil tak, jak jsi sám psal. Takže je to takový hybrid mezi tím, co bylo dřív a co jsi udělal. Prostě pokud existuje na Wikicestách, tak je tam odkaz na Wikicesty, pokud ne, tak externí odkaz, nebo pokud není, tak obyčejný text. Sice je tam teď ten externí odkaz ještě i s ikonkou zeměkoule, ale myslím, že to nevadí a kvůli jednotnosti je to možná i dobře.
::::Jinak ještě nějaké technické věci:
::::* Lua používá bool hodnotu false jen s malým f, takže False byla jakoby nedefinovaná proměnná a nebylo to požadované chování.
::::* Pokud už neplánuješ nějaké další úpravy, tak bych v Modul:VCard ještě ten nový kód zjednodušil (aby byl i podobnější tomu původnímu). Zkoušel jsem to a na první pohled jsem tam neviděl problém.
::::* Ještě asi udělám aktualizace celého modulu podle nejnovější verzi na DE Wikivoyage. Snad to něco nenabourá.
::::Jsem fakt rád, že jsi to dokázal a že se aspoň občas něco zlepšuje i technicky. Díky! [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 10. 2025, 12:47 (CEST)
:::::Určite jen do toho, nějaké úpravy v nejbližší době neplánuji. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 13. 10. 2025, 15:24 (CEST)
:::::Zjednodušení jsem udělal. A i celá aktualizace proběhla docela bez problémů. Novinkou jsou např. odkazy na mapy u šablony {{Š|Bod}}. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 10:34 (CEST)
::::::Výborně, s tou mapou to vypadá moc dobře. Jen jsem si všiml, že po aktualizaci zmizela ikonka Wikidat ([[Šablona:VCard/styles.css]]). Otázka je, jestli je vůbec vhodné ji tam mít – za mě je docela užitečná, protože se dá jedním kliknutím přejít na Wikidata a upravit tam, ale pro běžného čtenáře asi takový význam nemá.
::::::Další změna je, že pokud existuje článek na Wikicestách, už nejde do šablony {{šablona|Bod}} přidat web místa (viz [[Šablona:Bod/test]] → ODKAZ NA WIKICESTY → druhý odkaz na Pražský hrad nebo druhý Třístoličník). [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 10. 2025, 11:04 (CEST)
:::::::Já jsem věděl, že je dobré, když se na to podívá ještě někdo jiný :) Toho jsem si nevšiml a už jsem to vrátil. Byla to ruční úprava, která se aktualizací přepsala. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 17:06 (CEST)
:::::::Tak to jsem už taky opravil. Bylo to záludné, protože právě ta tebou speciálně upravená část kódu byla přesunuta do jiného modulu a už jsem to neuhlídal. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 18:14 (CEST)
== Šablona Geo - Zobrazit články v okolí ==
Podařilo se mně zase trochu vylepšit ty věci kolem šablony {{Š|Geo}}. Volám ji automaticky s parametry z Wikidat pomocí {{Š|Pagebanner}}, takže je automaticky ve všech článcích, kde je tato šablona a kde jsou definované souřadnice, tzn. fakt skoro všechny. Funguje pak i to tlačítko Zobrazit články v okolí, což je super, aby bylo vidět, které články jsou založené poblíž jiného článku. Ještě trvá problém s tím, že ikona vpravo nahoře otevře jinou mapu, kde ty články v okolí nejsou, ale na to se ještě jednou podívám. Je potřeba otevřít mapu, která je vložena pomocí šablony {{Š|Mapa}}. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 13. 10. 2025, 14:13 (CEST)
:Skvělá práce, u toho {{šablona|Geo}} je problém s {{šablona|PoiMap2}}, že ten web nemá českou verzi, která by přebírala data z českých Wikicesty. Napadlo mě to obejít přes [[Modul:Mapframe|modul Mapframe]], ale momentálně na to nemám moc času. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 13. 10. 2025, 15:35 (CEST)
::Přesně to napadlo i mě. Nakonec jsem udělal samostatnou šablonu {{Š|Maplink}}, která je ale v podstatě to samé (i stejný modul). Zdá se to být funkční a asi to tak nechám. Chtěl jsem to ještě nějak vizuálně vylepšit, ale moc mně to nejde. Ještě pořád si nejsu jistý, jestli to dělat tak plně automaticky přes šablonu {{Š|Pagebanner}}. Zatím to funguje dobře, jen možná parametr pro zoom mapy by mohl být zadaný ručně a v tom případě by bylo lepší mít samostatnou šablonu. Ale jestli vůbec má cenu mít na každé stránce vloženou šablonu <nowiki>{{Geo}}</nowiki> (výchozí zoom) a jen výjimečně něco jako <nowiki>{{Geo|zoom=10}}</nowiki>. Ale nevyužité šablony jako např. {{Š|PoiMap2}} už asi můžu odstranit. Budu rád, když si najdeš trochu času a ještě se zkusíš podívat, co dál by šlo vylepšit, protože v tomto se orientuješ velice dobře :) [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 14. 10. 2025, 10:53 (CEST)
:::Výborně, nevyužité šablony jako {{šablona|PoiMap2}} a {{šablona|GeoData}} už jsou zbytečné. Jen bude potřeba upravit ještě {{šablona|Geo}}, aby už PoiMap2 nepoužívala.
::: Se zoomem asi nic moc dělat nepůjde – ruční zadávání by sice asi šlo přímo do {{šablona|Pagebanner}} (který by si to pak převzal do Geo části), ale to mi přijde zbytečně zatěžující. Možná by šlo zkusit vymyslet způsob, jak by se zoom určoval automaticky podle typu místa. Až budu mít víc času, podívám se na to podrobněji, teď mě ale čeká docela dost zápočtových testů, tak nevím úplně kdy přibližně to bude. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 14. 10. 2025, 11:17 (CEST)
::::PoiMap2 jsem odstranil. Ta nepůjde využít asi nikdy. GeoData jsem ještě nechal. Na tu jsem už zapomněl. Vypadá ještě do budoucna užitečně, i když zatím moc využitá není. Ten automatický zoom podle typu z Wikidat mně taky napadl, ale to bude až taková třešnička. Zatím jsem narazil na větší problém. V náhledu všechno funguje, ale při normálním zobrazení se ten indikátor se souřadnicemi v některých článcích vůbec neukáže. A jestli se ukáže, tak vypadá jinak, než v tom náhledu (bez textových souřadnic). Myslel jsem, že ten chybějící indikátor bude chtít čas na vyprázdnění cache, ale pořád to nejde. Takové věci se hledají blbě, když je chování v náhledu jiné :( [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 15. 10. 2025, 13:21 (CEST)
== Chybějící města na mapě ==
Ahoj, ptám se tě jako specialisty na mapovou šablonu. :) Nevíš, proč se v článku [[Jihočeský kraj]] neukazují na mapě města, ale ostatní místa se ukazují? Je to neznámým typem objektu? Když u toho bodu natvrdo nastavím typ, tak se ukáže, ale nevidím důvod, proč by to nemělo ukazovat města. Navíc v článku [[Itálie]] se města normálně ukazují. Možná je problém s tím, že česká města jsou ve Wikidatech založena jako instance "obec v Česku" nebo "město v Česku", ale už ne obyčejné "město". Takže možná je to fakt neznámý objekt a takové objekty to neukazuje. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 25. 11. 2025, 18:12 (CET)
:Aha, tak už jsem to opravil sám. Po dřívější aktualizaci nebylo přeložené jedno slovo v [[Modul:Marker utilities/Groups]]. Někdy stačí napsat dotaz, abych dostal další nápad. :) Ale s těmi městy na mapě mám ještě nějaké větší plány, tak se to bude hodit. [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 25. 11. 2025, 18:17 (CET)
== Aktualizace mapových modulů ==
Ahoj, právě jsem provedl asi největší aktualizaci všech těch mapových modulů, šablon a stylů za poslední dobu. Kvůli kontrole s předchozími ručními úpravami to bylo pracnější, než jsem myslel, ale vypadá to, že se všechno podařilo. Mým hlavním důvodem byly chybějící snad všechny ikony, které s tím souvisely, protože WM změnilo velikosti rastrových obrázků generovaných z vektorových. Aktualizoval jsem ale zrovna už všechno, na co jsem narazil. Čekal jsem, že se to zase totálně rozsype, ale zatím to vypadá dobře. V první řadě bych chtěl, aby ses na to aspoň podíval tvýma očima, ať identifikujeme případné problémy. Až pak se případně podíváme na jejich řešení, příp. přeložení nových textů (přeložil jsem zatím jen část).
Díky [[Uživatel:LiMr|LiMr]] ([[Diskuse s uživatelem:LiMr|diskuse]]) 20. 5. 2026, 15:24 (CEST)
:Ahoj,
:podívám se na to, dej mi pár dní, popř. dopopřekládám co bude třeba. Zběžným pohledem to vypadá dobře. [[Uživatel:OndraMix|OndraMix]] ([[Diskuse s uživatelem:OndraMix|diskuse]]) 21. 5. 2026, 11:02 (CEST)
g7qgud4j3wzxillk14re2rfhu53mdqe
Modul:Hours/i18n
828
1333
22102
17714
2026-05-20T12:07:25Z
LiMr
96
aktualizace na novější verzi
22102
Scribunto
text/plain
-- kopie z německých wikicest (https://de.wikivoyage.org/w/index.php?title=Modul:Hours/i18n&oldid=1766826)
-- copy from dewikivoyage (https://de.wikivoyage.org/w/index.php?title=Modul:Hours/i18n&oldid=1766826)
-- This module contains wiki-language specific strings to translate.
return {
-- administration
moduleInterface = {
suite = "Hours",
sub = "Hours/i18n",
serial = "2026-04-07",
item = 99744685
},
-- invoke call parameters
params = {
fallback = "",
format = "",
id = "",
show = ""
},
-- invoke-call show options
show = {
demo = "",
msg = "",
nomsg = ""
},
-- Wikidata property identifiers
wd = {
retrieved = "P813",
validInPeriod = "P1264",
opened = "P3025",
closed = "P3026",
dayOpenFrom = "P3027",
dayOpenTo = "P3028",
natureOfStatement = "P5102",
stateOfUse = "P5817",
hourOpenFrom = "P8626",
hourOpenTo = "P8627",
appliesToJurisdiction = "P1001",
appliesToPart = "P518",
appliesToPeople = "P6001",
occupation = "P106",
of = "P642",
use = "P366",
all = { "P3026", "P3027", "P3028", "P8626", "P8627",
"P1264", "P5102", "P5817",
"P366", "P518", "P642", "P1001", "P6001", "P106" },
comments = { "P1264", "P5102", "P5817",
"P366", "P518", "P642", "P1001", "P6001", "P106" },
commentsForClosed = { "P5102", "P5817",
"P366", "P518", "P642", "P1001", "P6001", "P106" }
},
-- abbreviations for month names
months = {
leden = "led",
["únor"] = "úno",
["březen"] = "bře",
duben = "dub",
["květen"] = "kvě",
["červen"] = "čvn",
["červenec"] = "čvc",
srpen = "srp",
["září"] = "zář",
["říjen"] = "říj",
listopad = "lis",
prosinec = "pro"
},
weekdays = {
Po = 1,
["Út"] = 2,
St = 3,
["Čt"] = 4,
["Pá"] = 5,
So = 6,
Ne = 7
},
-- several strings
texts = {
closed = "uzavřeno: %s",
format = "otevřeno: %s",
-- punctuation
parentheses = "(%s)",
space = " ", -- for instance between days and times
comma = ", ", -- several dates
semicolon = "; ", -- several statesments
from = "od %s",
fromTo = "%s–%s",
to = "do %s",
-- formatting of a single time
timePattern = "^(%d%d?)[.:](%d%d?)%s*Uhr$", -- for German wiki
formatTime = "%s:%s", -- or "%s:%s Uhr" etc.
formatDate = "j. M Y",
formatAM = "%s:%s AM",
formatPM = "%s:%s PM",
-- formatting of a time range
hourReplAll = true, -- (formally) replace all occurrences
hourPattern = "", -- empty if no replacement is requested
hourRepl = "",
-- hourReplAll = false, -- replace only first occurrence
-- hourPattern = "(%d)%s+[aApP][mM]", -- empty if no replacement is requested
-- hourRepl = "%1",
},
options = {
addCategories = false,
clusterClosed = true, -- cluster all closing dates at the end
hour12 = false, -- 12 or 24 hours mode
leadingZero = false, -- add or remove zero for hours
removeZeros = false -- remove zeros :00 for full hours
},
-- Category names
categories = {
fallbackLabel = "[[Kategorie:Údržba:Otevírací doba v angličtině]] <span class=\"voy-listing-check-recommended\" style=\"display:none;\">Otevírací doba v angličtině</span>",
hoursFromWikidata = "[[Kategorie:Monitoring:Data z Wikidat]]",
invalidId = "[[Kategorie:Údržba:Chyba v ID Wikidat]] <span class=\"error\">Chyba v ID Wikidat</span>",
isClosed = "[[Kategorie:Údržba:Zařízení je uzavřeno]] <span class=\"voy-listing-check-recommended\" style=\"display:none;\">Zařízení je uzavřeno</span>",
hoursLabelFromWikidata = "[[Kategorie:Monitoring:Data z Wikidat]] <span class=\"voy-listing-check-recommended\" style=\"display:none;\">Štítek otevírací doby z Wikidat</span>",
properties = "[[Kategorie:Monitoring:Data z Wikidat]]",
unknownError = "[[Kategorie:Údržba:Chyba v otevírací době]] <span class=\"voy-listing-check-recommended\" style=\"display:none;\">Chyba v otevírací době</span>",
unknownParams = "[[Kategorie:Údržba:Neznámý parametr]] <span class=\"error\">Neznámý parametr: %s</span>",
unknownShowOptions = "[[Kategorie:Údržba:Neznámá volba parametru show]] <span class=\"error\"Neznámá volba parametru show: %s</span>",
withoutTime = "[[Kategorie:Údržba:Otevírací doba bez hodin]] <span class=\"voy-listing-check-recommended\" style=\"display:none;\">Otevírací doba bez hodin</span>",
},
-- time to id conversion
times = {
daily = "Q26214163",
Dec31 = "Q2912",
is24_7 = "Q1571749",
Jan1 = "Q2150"
},
-- several abbreviations
abbr = {
{ f = "[Pp]onděl[í|ky]", a = "Po" },
{ f = "[Úú]ter[ý|ky]", a = "Út" },
{ f = "[Ss]třed[a|y]", a = "St" },
{ f = "[Čč]tvrt[ek|ky]", a = "Čt" },
{ f = "[Pp]át[ek|ky]", a = "Pá" },
{ f = "[Ss]obot[a|y]", a = "So" },
{ f = "[Ss]obot[a|y] večer", a = "So" },
{ f = "[Nn]eděle", a = "Ne" },
{ f = "[Pp]rvní[ho]?", a = "1." },
{ f = "[Dd]ruh[ý|á|é|ého]", a = "2." },
{ f = "[Tt]řetí[ho]?", a = "3." },
{ f = "[Čč]tvrt[ý|á|é|ého]", a = "4." },
{ f = "[Pp]át[ý|á|é|ého]", a = "5." }
},
-- selections of date labels to prevent fetching from Wikidata
dateIds = {
-- Table contains common values only and is used for reduction of
-- computing time. Others will be taken from Wikidata labels.
-- days
Q105 = "Po",
Q127 = "Út",
Q128 = "St",
Q129 = "Čt",
Q130 = "Pá",
Q131 = "So",
Q132 = "Ne",
Q211391 = "víkend",
-- use Q99528581 instead of Q211391 because it is culturally dependent
Q26214163 = "denně", -- do not remove this item because it is used in Lua script
Q100274304 = "Po–Pá",
Q116445783 = "Po–Út, Čt",
Q118773943 = "Po–Út, Čt–Pá",
Q104786164 = "Po-St",
Q104057082 = "Po–Čt",
Q97120402 = "Po–Pá",
Q21282379 = "Po–So",
Q101072294 = "Út–St",
Q100320771 = "Út–Čt",
Q100157387 = "Út–Pá",
Q100148056 = "Út–So",
Q99731947 = "Út–Ne",
Q100427721 = "St–Čt",
Q99714084 = "St–Pá",
Q100148065 = "St–Pá",
Q118773278 = "St, Pá",
Q31689308 = "St–So",
Q116328326 = "St, So",
Q65681627 = "St–Ne",
Q100332183 = "St–Ne",
Q99731117 = "St–Po",
Q106714964 = "Čt–Út",
Q106538987 = "Čt–Pá",
Q106541052 = "Čt–So",
Q100274433 = "Čt–Ne",
Q100427930 = "Pá–So",
Q100451849 = "Pá–Ne",
Q111977440 = "Pá–St",
Q102268431 = "So–St",
Q101766385 = "So–Čt",
Q99528581 = "So–Ne",
Q106538981 = "Ne–Po",
Q111127796 = "Ne–St",
Q100587968 = "Ne–Čt",
Q112703547 = "Ne–Pá",
Q1571749 = "24/7", -- do not remove this item because it is used in Lua script
Q819073 = "pracovní den",
Q1445650 = "svátek",
Q1197685 = "svátek",
Q2174956 = "den pracovního klidu",
Q12779928 = "pracovní den",
Q116213 = "dovolená",
-- Zero-width spaces are used to keep the week-day terms and to
-- prevent abbreviation
Q14915111 = "52 dní před Velikonocemi",
Q15834118 = "Weiberfastnacht",
Q2245828 = "Nelkensamstag",
Q1241858 = "Estomihi",
Q2085192 = "Estomihi",
Q153134 = "Rosenmontag",
Q4845365 = "masopustníúterý",
Q123542 = "Popelečnístředa",
Q153308 = "3.nedělepostní",
Q2033651 = "5.nedělepostní",
Q42236 = "Květnáneděle",
Q106333 = "Zelenýčtvrtek",
Q40317 = "Velkýpátek",
Q186206 = "Bílásobota",
Q21196 = "Velikonoce",
Q1512337 = "Velikonočníneděle",
Q209663 = "Velikonočnípondělí",
Q14795170 = "Velikonočnípondělí",
Q14916781 = "Velikonočníúterý",
Q51638 = "SvátekNanebevstoupeníPáně",
Q39864 = "Letnice",
Q2512993 = "Svatodušnípondělí",
Q14795386 = "51dnípoVelikonocích",
Q152395 = "SlavnostTělaaKrvePáně",
Q2304773 = "harvestfestival",
Q2913791 = "Díkůvzdání",
Q59833 = "Dušičky",
Q19809 = "Vánoce",
Q10901070 = "Svátek práce",
Q10274 = "Vidžajadašamí",
Q464458 = "Íd al-fitr",
Q10259 = "Hólí",
Q131772 = "Chinesisches Neujahrsfest",
Q718778 = "Qingming-Fest",
Q1145566 = "Chinesischer Nationalfeiertag",
Q1622041 = "hlavní sezóna",
Q99932986 = "mimosezóna",
Q1777301 = "standardní čas",
Q36669 = "letní čas",
Q107376657 = "leden až březen",
Q107376740 = "březen až říjen",
Q121914265 = "březen až listopad",
Q100157218 = "duben až říjen",
Q107376636 = "duben až prosinec",
Q107359921 = "květen až říjen",
Q107376754 = "listopad až leden",
Q100157227 = "listopad až březen",
Q1312 = "jaro",
Q1313 = "léto",
Q1314 = "podzim",
Q1311 = "zima",
Q100320775 = "první víkend v měsíci",
Q23034736 = "první pondělí v měsíci",
Q51119351 = "druhé pondělí v měsíci",
Q51119371 = "třetí pondělí v měsíci",
Q51119385 = "čtvrté pondělí v měsíci",
Q51119411 = "páté pondělí v měsíci",
Q51120546 = "poslední pondělí v měsíci",
Q51119341 = "první čtvrtek v měsíci",
Q51119361 = "druhý čtvrtek v měsíci",
Q51119378 = "třetí čtvrtek v měsíci",
Q51119395 = "čtvrtý čtvrtek v měsíci",
Q51119421 = "pátý čtvrtek v měsíci",
Q51120559 = "poslední čtvrtek v měsíci",
Q51119344 = "první pátek v měsíci",
Q51119363 = "druhý pátek v měsíci",
Q51119381 = "třetí pátek v měsíci",
Q51119398 = "čtvrtý pátek v měsíci",
Q51119425 = "pátý pátek v měsíci",
Q51120563 = "poslední pátek v měsíci",
Q51119345 = "první sobota v měsíci",
Q51119367 = "druhá sobota v měsíci",
Q51119382 = "třetí sobota v měsíci",
Q51119402 = "čtvrtá sobota v měsíci",
Q51119427 = "pátá sobota v měsíci",
Q51120565 = "poslední sobota v měsíci",
Q51119350 = "první neděle v měsíci",
Q51119369 = "druhá neděle v měsíci",
Q51119383 = "třetí neděle v měsíci",
Q51119404 = "čtvrtá neděle v měsíci",
Q51119429 = "pátá neděle v měsíci",
Q51120567 = "poslední neděle v měsíci",
Q108 = "leden",
Q2150 = "1. leden", -- do not remove this item because it is used in Lua script
Q196627 = "1. leden",
Q2151 = "2. leden",
Q2156 = "3. leden",
Q2221 = "6. leden",
Q1139536 = "26. leden", -- India Republic Day
Q2289 = "31. leden",
Q109 = "únor",
Q2312 = "1. únor",
Q2332 = "14. únor",
Q2334 = "15. únor",
Q2362 = "28. únor",
Q2364 = "29. únor",
Q110 = "březen",
Q2393 = "1. březen",
Q2404 = "14. březen",
Q2403 = "15. březen",
Q2457 = "27. březen",
Q2458 = "28. březen",
Q2461 = "31. březen",
Q118 = "duben",
Q2510 = "1. duben",
Q2505 = "7. duben",
Q2504 = "9. duben",
Q2500 = "14. duben",
Q2497 = "15. duben",
Q2536 = "30. duben",
Q119 = "květen",
Q2544 = "1. květen",
Q47499 = "1. květen",
Q2574 = "16. květen",
Q2591 = "31. květen",
Q120 = "červen",
Q2625 = "1. červen",
Q2657 = "30. červen",
Q121 = "červenec",
Q2700 = "1. červenec",
Q2715 = "31. červenec",
Q122 = "srpen",
Q2788 = "1. srpen",
Q2774 = "15. srpen",
Q162691 = "15. srpen", -- Assumption of Mary
Q56106 = "15. srpen", -- Independence Day, India
Q2830 = "31. srpen",
Q123 = "září",
Q2859 = "1. září",
Q2846 = "15. září",
Q2881 = "30. září",
Q124 = "říjen",
Q2913 = "1. říjen",
Q2932 = "2. říjen",
Q2931 = "3. říjen",
Q157582 = "3. říjen", -- German Unity Day
Q2919 = "15. říjen",
Q2963 = "16. říjen",
Q2949 = "31. říjen",
Q153093 = "31. říjen", -- Reformation Day
Q125 = "listopad",
Q2997 = "1. listopad",
Q2982 = "15. listopad",
Q3029 = "16. listopad",
Q3015 = "30. listopad",
Q126 = "prosinec",
Q2297 = "1. prosinec",
Q2451 = "19. prosinec",
Q2705 = "24. prosinec",
Q106010 = "24. prosinec",
Q2745 = "25. prosinec",
Q2703710 = "25. prosinec", -- Christmas Day
Q2761 = "26. prosinec",
Q15113728 = "26. prosinec",
Q2800 = "27. prosinec",
Q2832 = "28. prosinec",
Q2862 = "29. prosinec",
Q2901 = "30. prosinec",
Q2912 = "31. prosinec", -- do not remove this item because it is used in Lua script
Q11269 = "31. prosinec",
-- points of time
Q573 = "den",
Q575 = "noc",
Q7722 = "ráno",
Q986787 = "dopoledne",
Q283102 = "odpoledne",
Q7725 = "večer",
Q193294 = "východ slunce",
Q166564 = "západ slunce",
Q36402 = "0:00",
Q55812411 = "0:00",
Q55449532 = "0:30",
Q41618001 = "1:00",
Q55517345 = "1:00",
Q55518450 = "1:30",
Q41618006 = "2:00",
Q55521280 = "2:00",
Q55524996 = "2:30",
Q41618076 = "3:00",
Q55527754 = "3:00",
Q55560170 = "3:30",
Q41618081 = "4:00",
Q55810628 = "4:00",
Q55810646 = "4:15",
Q55811293 = "4:30",
Q55811308 = "4:45",
Q41618165 = "5:00",
Q55810695 = "5:00",
Q55810711 = "5:15",
Q55811314 = "5:30",
Q55811331 = "5:45",
Q41618168 = "6:00",
Q55810762 = "6:00",
Q55810778 = "6:15",
Q55810795 = "6:30",
Q55811354 = "6:45",
Q41618172 = "7:00",
Q55811431 = "7:00",
Q55810845 = "7:15",
Q55810863 = "7:30",
Q55811437 = "7:45",
Q41618176 = "8:00",
Q55811455 = "8:00",
Q55810913 = "8:15",
Q55810929 = "8:30",
Q55810940 = "8:40",
Q55812499 = "8:45",
Q41618181 = "9:00",
Q55811413 = "9:00",
Q55811478 = "9:15",
Q55810994 = "9:30",
Q55811012 = "9:45",
Q41618185 = "10:00",
Q55811483 = "10:00",
Q55811062 = "10:30",
Q41618189 = "11:00",
Q55811097 = "11:00",
Q55811133 = "11:30",
Q168182 = "12:00",
Q55812521 = "12:00",
Q55811197 = "12:30",
Q47454201 = "12:30",
Q41618345 = "13:00",
Q55811230 = "13:00",
Q55812556 = "13:15",
Q55811580 = "13:30",
Q55811277 = "13:45",
Q41620570 = "14:00",
Q55811610 = "14:00",
Q55811657 = "14:15",
Q55811674 = "14:30",
Q55811761 = "14:45",
Q41620574 = "15:00",
Q55811778 = "15:00",
Q55811726 = "15:15",
Q55811745 = "15:30",
Q55811798 = "15:45",
Q41620578 = "16:00",
Q55812393 = "16:00",
Q55812563 = "16:15",
Q55811847 = "16:30",
Q55811864 = "16:45",
Q41620582 = "17:00",
Q55811883 = "17:00",
Q55812585 = "17:15",
Q55812595 = "17:25",
Q55813015 = "17:30",
Q55811932 = "17:45",
Q41620584 = "18:00",
Q55811949 = "18:00",
Q55813021 = "18:15",
Q55813038 = "18:30",
Q55812002 = "18:45",
Q41620587 = "19:00",
Q55812019 = "19:00",
Q55812659 = "19:30",
Q41620591 = "20:00",
Q55812694 = "20:00",
Q55812122 = "20:30",
Q41620593 = "21:00",
Q55812716 = "21:00",
Q55812732 = "21:15",
Q55812192 = "21:30",
Q55812210 = "21:45",
Q41620595 = "22:00",
Q55813122 = "22:00",
Q55812769 = "22:30",
Q44529925 = "23:00",
Q55812301 = "23:00",
Q55813170 = "23:30",
Q55812370 = "24:00",
-- for P1264
Q41662 = "Ramadán",
-- for P5102
Q29509043 = "oficiální",
Q29509080 = "neoficiální",
Q132555 = "de jure",
Q712144 = "de facto",
Q28962310 = "zřídka",
Q28962312 = "často",
Q18603603 = "hypoteticky",
Q30230067 = "možná",
Q53737447 = "původně",
Q18912752 = "sporné",
Q28831311 = "nepotvrzené",
Q24025284 = "občas se mění",
Q4895105 = "prozatimní",
Q18122778 = "pravděpodobně",
Q32188232 = "údajně",
Q1520777 = "jistě",
Q5727902 = "cirka",
Q56644435 = "zřejmě",
-- for P5817
-- empty strings are not displayed
Q29933838 = "mimo provoz",
Q56651571 = "mimo provoz",
Q111802839 = "mimo provoz",
Q104664889 = "trvale uzavřeno",
Q55570821 = "", -- "otevřeno pro veřejnost"
Q55570340 = "zavřeno pro veřejnos",
Q55654238 = "", -- "v provozu"
Q811683 = "plánovaná stavba ",
Q12377751 = "ve výstavbě",
Q109551035 = "", -- "částečně funkční"
Q63065035 = "", -- "opuštěno"
Q11639308 = "vyřazeno z provozu",
Q55653430 = "dočasně uzavřeno",
Q63187954 = "v rekonstrukci",
Q4989906 = "", -- "památka"
Q2086116 = "", -- po použití
Q110713763 = "zatím se nepoužívá"
}
}
hewi4dh7wcuyf00mjvnmsdaubdc3hrh
Modul:Hours
828
1334
22103
17231
2026-05-20T12:14:36Z
LiMr
96
aktualizace na novější verzi
22103
Scribunto
text/plain
-- kopie z německých wikicest (https://de.wikivoyage.org/w/index.php?title=Modul:Hours&oldid=1775632)
-- copy from dewikivoyage (https://de.wikivoyage.org/w/index.php?title=Modul:Hours&oldid=1775632)
-- getting opening hours from Wikidata
-- module variable and administration
local hr = {
moduleInterface = {
suite = 'Hours',
serial = '2026-05-17',
item = 99600452
},
labelTable = nil,
typeTables = nil
}
-- module import
-- require( 'strict' )
local hi = require( 'Module:Hours/i18n' )
local wu = require( 'Module:Wikidata utilities' )
-- local variables
local categIds = {}
local showOptions = {}
local function isSet( s )
return s and s ~= ''
end
-- insert a value into a table only if it is set
local function tableInsert( tab, value )
if isSet( value ) then
table.insert( tab, value )
end
end
-- value count for any variable
local function getCount( tab )
return type( tab ) == 'table' and #tab or 0
end
local function getLabelFromTables( id )
local label = hi.dateIds[ id ]
if not label and hr.labelTable then
label = hr.labelTable[ id ]
end
if not label and hr.typeTables and hr.typeTables.idTable then
local item = hr.typeTables.typeTable[ hr.typeTables.idTable[ id ] ]
if item then
item = item.label or item.n or item
local at = mw.ustring.find( item, ',' )
if at then
item = mw.ustring.sub( item, 1, at - 1 )
end
label = mw.text.trim( item )
end
end
return label
end
-- getting normalized time hh:dd
local function getNormalizedTime( s )
local count
s, count = mw.ustring.gsub( s, hi.texts.timePattern, '%1:%2' )
return ( count > 0 ) and s or nil
end
function hr.formatTime( s )
local t = getNormalizedTime( s )
if not t then
return s
end
local formatStr = hi.texts.formatTime
t = mw.text.split( t, ':', true )
if #t == 1 then
t[ 2 ] = '00'
end
if hi.options.hour12 then
local isAM = true
local n = tonumber( t[ 1 ] )
if n > 12 then
isAM = false
t[ 1 ] = '' .. ( n - 12 )
end
formatStr = isAM and hi.texts.formatAM or hi.texts.formatPM
end
s = mw.ustring.format( formatStr, mw.text.trim( t[ 1 ] ),
mw.text.trim( t[ 2 ] ) )
if hi.options.leadingZero then
s = s:gsub( '^(%d):', '0%1:' )
else
s = s:gsub( '^0(%d):', '%1:' )
end
if hi.options.removeZeros then
s = s:gsub( '^(%d%d?):00', '%1' )
end
return s
end
-- getting label for a qualifier id
-- to save computing time firstly the id will fetched from Hours/i18n table
-- if available, otherwise from Wikidata
local function getLabelFromId( id, wikilang, fallbackLang )
if not isSet( id ) then
return ''
end
-- from table
local label = getLabelFromTables( id )
-- from Wikidata
if not label and mw.wikibase.isValidEntityId( id ) then
label = wu.getLabel( id, wikilang )
if not label and isSet( fallbackLang ) then
label = wu.getLabel( id, fallbackLang )
if label then
categIds.fallbackLabel = 1
end
end
if label then
categIds.hoursLabelFromWikidata = 1
end
end
-- abbreviate labels
if isSet( label ) then
for i, abbr in ipairs( hi.abbr ) do
label = mw.ustring.gsub( label, abbr.f, abbr.a )
end
label = mw.ustring.gsub( label, '', '' ) -- zero-width space
end
-- additional time formatting
if isSet( label ) then
if hi.months then
for full, short in pairs( hi.months ) do
label = mw.ustring.gsub( label, full, short )
end
end
label = hr.formatTime( label )
end
return label or ''
end
local function abbreviateTimeStr( s, all, pattern, repl )
if not isSet( s ) or not isSet( pattern ) or not repl then
return s or ''
end
if all then
s = mw.ustring.gsub( s, pattern, repl )
else
local matchPattern = mw.ustring.gsub( pattern, '%(%%d%)', '' )
local first, stop = mw.ustring.find( s, pattern )
if first then
local second = mw.ustring.find( s, pattern, stop + 1 )
if second and mw.ustring.match( s, matchPattern ) ==
mw.ustring.match( s, matchPattern, stop + 1 ) then
s = mw.ustring.gsub( s, pattern, repl, 1 )
end
end
end
return s
end
-- getting time period string
-- i: position in from and to arrays
-- id: label for P3035 value
local function getTimePeriod( from, to, i, id )
local result = ''
if id and ( id == getLabelFromTables( hi.times.daily )
or id == getLabelFromTables( hi.times.is24_7 ) )
and from and to and from[ i ] == getLabelFromTables( hi.times.Jan1 ) and
to[ i ] == getLabelFromTables( hi.times.Dec31 ) then
return ''
end
if from and isSet( from[ i ] ) and to and isSet( to[ i ] ) then
result = mw.ustring.format( hi.texts.fromTo, from[ i ], to[ i ] )
if isSet( hi.texts.hourPattern ) then
result = abbreviateTimeStr( result, hi.texts.hourReplAll,
hi.texts.hourPattern, hi.texts.hourRepl )
end
elseif from and isSet( from[ i ] ) then
result = mw.ustring.format( hi.texts.from, from[ i ] )
elseif to and isSet( to[ i ] ) then
result = mw.ustring.format( hi.texts.to, to[ i ] )
end
return result
end
-- collecting all maintenance categories
function hr.getCategories( formatStr )
local result = wu.getCategories( formatStr )
for k, v in pairs( categIds ) do
result = result .. ( hi.categories[ k ] or hi.categories.unknownError )
end
if showOptions.demo then
-- remove category links
result = result:gsub( '%[%[[^%[]*%]%]', '' )
end
return result
end
-- getting a string with listed days at which an establishment is closed
local function getClosed( arr )
return ( arr and #arr > 0 ) and mw.ustring.format( hi.texts.closed or '%s',
table.concat( arr, hi.texts.comma ) ) or ''
end
-- converting day range from Mo, Tu, We to Mo–We, and so on
local function getRange( arr, minPos, maxPos )
if maxPos > 0 and minPos > 0 and maxPos > minPos then
arr[ minPos ] = mw.ustring.format( hi.texts.fromTo, arr[ minPos ],
arr[ maxPos ] )
for i = maxPos, minPos + 1, -1 do
table.remove( arr, i )
end
end
end
-- looking for day ranges like Mo, Tu, We and so on and converting them
local function convertDayRange( arr )
local count = #arr
local minPos = 0
local maxPos = 0
local value, valueMin
while count > 0 do
value = hi.weekdays[ arr[ count ] ]
if not value then
getRange( arr, minPos, maxPos )
maxPos = 0
elseif maxPos == 0 then
maxPos = count
valueMin = value
elseif maxPos > 0 and value == valueMin - 1 then
minPos = count
valueMin = value
else
getRange( arr, minPos, maxPos )
maxPos = 0
end
count = count - 1
end
getRange( arr, minPos, maxPos )
end
-- concating non-empty strings
local function concatStrings( sep, str1, str2 )
local tab = {}
tableInsert( tab, str1 )
tableInsert( tab, str2 )
return table.concat( tab, sep )
end
-- add comment if not yet exists
local function addComment( tab, value )
if not isSet( value ) then
return
elseif #tab == 0 then
table.insert( tab, value )
else
for i = 1, #tab, 1 do
if tab[ i ] == value then
break
end
if i == #tab then
table.insert( tab, value )
end
end
end
end
-- main function for usage in Lua modules
-- entity: entity id or entity table
-- wikilang: content language of the wiki
-- fallbackLang: optional additional language for fallback
-- formatStr: optional format string for property categories
-- show: table of show options (addCategories, msg, nomsg) or nil
-- lastedit: dat of last edit. If false no date will be fetched
-- labelTabel: additional table with Q-id label pairs
function hr.getHoursFromWikidata( entity, wikilang, fallbackLang, formatStr,
show, lastEdit, labelTable, typeTables )
-- collecting days at which an establishment is closed
local closeDays = {}
local closeDaysHelper = {}
local withStateOfUse = false
local function mergeDays( days )
if not days or #days == 0 then
return
end
for i, day in ipairs( days ) do
if not closeDaysHelper[ day ] then
table.insert( closeDays, day )
closeDaysHelper[ day ] = ''
end
end
end
local function clearDays()
closeDays = {}
closeDaysHelper = {}
end
-- adding additional properties if an additional Q-id table is given
hr.labelTable = labelTable
hr.typeTables = typeTables
-- preparing show options
showOptions = show or {}
showOptions.addCategories = hi.options.addCategories
if showOptions.msg then
showOptions.addCategories = true
elseif showOptions.nomsg then
showOptions.addCategories = false
end
-- format string for property categories
if not isSet( formatStr ) then
formatStr = hi.categories.properties
end
-- 1st step: getting statements for P3025: open days
local statements = wu.getValuesWithQualifiers( entity, hi.wd.opened, nil,
hi.wd.all, hi.wd.retrieved, nil, getLabelFromId, wikilang, fallbackLang )
lastEdit = wu.getLastedit( lastEdit, statements )
-- converting statements to human-readable strings
local result = {}
local comments, s
local is24_7 = getLabelFromTables( hi.times.is24_7 )
for i, statement in ipairs( statements ) do
-- opening times
local times = {}
local count = math.max( getCount( statement[ hi.wd.hourOpenFrom ] ),
getCount( statement[ hi.wd.hourOpenTo ] ) )
if count > 0 then
for j = 1, count, 1 do
s = getTimePeriod( statement[ hi.wd.hourOpenFrom ],
statement[ hi.wd.hourOpenTo ], j )
if isSet( s ) then
table.insert( times, s )
elseif statement.value ~= is24_7 then
categIds.withoutTime = 1
end
end
elseif statement.value ~= is24_7 then
categIds.withoutTime = 1
end
s = table.concat( times, hi.texts.comma )
-- comments
comments = {}
count = math.max( getCount( statement[ hi.wd.dayOpenFrom ] ),
getCount( statement[ hi.wd.dayOpenTo ] ) )
for j = 1, count, 1 do
addComment( comments,
getTimePeriod( statement[ hi.wd.dayOpenFrom ],
statement[ hi.wd.dayOpenTo ], j, statement.value ) )
end
for j, key in ipairs( hi.wd.comments ) do
if statement[ key ] then
addComment( comments, table.concat( statement[ key ],
hi.texts.comma ) )
end
end
-- concating times and comments
times = {}
tableInsert( times, s )
s = table.concat( comments, hi.texts.comma )
if isSet( s ) then
table.insert( times, mw.ustring.format( hi.texts.parentheses, s ) )
end
local item = {}
tableInsert( item, table.concat( times, hi.texts.space ) )
-- close statements (P3026) as qualifiers for open days property (P3025)
mergeDays( statement[ hi.wd.closed ] )
if not hi.options.clusterClosed and ( i == #statements or
statements[ i ].value ~= statements[ i + 1 ].value ) then
convertDayRange( closeDays )
tableInsert( item, getClosed( closeDays ) )
clearDays()
end
s = table.concat( item, hi.texts.comma )
-- copying each statement to result table
if statement.sort2 == 1 then
tableInsert( result, { value = { statement.value }, times = s } )
elseif s ~= '' then
result[ #result ].times = concatStrings( hi.texts.comma,
result[ #result ].times, s )
end
end
-- checking for duplicates
for i = #result, 2, -1 do
if result[ i ].times == result[ i - 1 ].times then
for j, value in ipairs( result[ i ].value ) do
table.insert( result[ i - 1 ].value, value )
end
table.remove( result, i )
end
end
-- converting day range
for i = 1, #result, 1 do
local arr = result[ i ].value
convertDayRange( arr )
result[ i ] = concatStrings( hi.texts.space,
table.concat( arr, hi.texts.comma ), result[ i ].times )
end
-- 2nd step: getting separated close statements (P3026)
statements = wu.getValuesWithQualifiers( entity, hi.wd.closed,
nil, hi.wd.commentsForClosed, hi.wd.retrieved, nil, getLabelFromId, wikilang,
fallbackLang )
if #statements > 0 then
lastEdit = wu.getLastedit( lastEdit, statements )
-- getting closed values
local closed = {}
for i, statement in ipairs( statements ) do
local closedDate = {}
table.insert( closedDate, statement.value )
-- getting comments
comments = {}
for j, key in ipairs( hi.wd.commentsForClosed ) do
if statement[ key ] then
addComment( comments, table.concat( statement[ key ],
hi.texts.comma ) )
end
end
s = table.concat( comments, hi.texts.comma )
if isSet( s ) then
table.insert( closedDate, mw.ustring.format( hi.texts.parentheses, s ) )
end
table.insert( closed, table.concat( closedDate, hi.texts.space ) )
end
mergeDays( closed )
end
convertDayRange( closeDays )
tableInsert( result, getClosed( closeDays ) )
-- 3rd step: adding additional statements
statements = wu.getValuesWithQualifiers( entity, hi.wd.stateOfUse,
nil, {}, hi.wd.retrieved, nil, getLabelFromId, wikilang, fallbackLang )
if #statements > 0 then
lastEdit = wu.getLastedit( lastEdit, statements )
for i, statement in ipairs( statements ) do
if statement.value ~= '' then
withStateOfUse = true
table.insert( result, statement.value )
end
end
end
-- merging all statements
result = table.concat( result, hi.texts.semicolon )
-- adding maintenance categories
if result ~= '' then
categIds.hoursFromWikidata = 1
if withStateOfUse then
categIds.isClosed = 1
end
if showOptions.addCategories then
result = result .. hr.getCategories( formatStr )
end
end
return result, lastEdit
end
-- invoke helper functions
-- splitting show parameters
local function splitAndCheck( s )
local arr = {}
local err = {}
if isSet( s ) then
for i, v in ipairs( mw.text.split( s, ',', true ) ) do
v = mw.text.trim( v )
if not hi.show[ v ] then
table.insert( err, v )
else
arr[ v ] = ''
end
end
end
return arr, err
end
-- check if pareameters are valid
local function checkParameters( args )
local err = {}
if not args and type( args ) ~= 'table' then
return err
end
for k, v in pairs( args ) do
if not hi.params[ k ] then
table.insert( err, k )
end
end
return err
end
-- formating and concating error strings
local function getErrorStr( arr, formatStr )
return #arr == 0 and '' or
mw.ustring.format( formatStr, table.concat( arr, hi.texts.comma ) )
end
-- main function for template #invoke calls
-- id: Q id of an establishment
-- format: output format like 'opened at %s'
-- fallback: fallback language if labels are not available in content language
function hr.getHours( frame )
local args = frame.args
args.id = mw.text.trim( args.id or '' )
if not isSet( args.id ) or not mw.wikibase.isValidEntityId( args.id ) then
return hi.categories.invalidId
end
if not isSet( args.format ) then
args.format = hi.texts.format
else
local s, count = args.format:gsub( '%%s', '%%s' )
if count ~= 1 then
args.format = hi.texts.format
end
end
args.fallback = args.fallback or ''
local wikilang = mw.getContentLanguage():getCode()
local paramErr = checkParameters( args )
local show, showErr = splitAndCheck( args.show )
local result = hr.getHoursFromWikidata( args.id, wikilang,
args.fallback, '', show, false, nil )
if result ~= '' then
result = mw.ustring.format( args.format, result )
end
return result .. getErrorStr( paramErr, hi.categories.unknownParams )
.. getErrorStr( showErr, hi.categories.unknownShowOptions )
end
return hr
7iy3zw7sxfesklf9fjlgojnnrid06ol
Modul:Marker utilities/i18n
828
1336
22106
22093
2026-05-20T12:27:23Z
LiMr
96
formát data aktualizace
22106
Scribunto
text/plain
-- kopie z německých wikicest (https://de.wikivoyage.org/w/index.php?title=Modul:Marker_utilities/i18n&oldid=1768059)
-- copy from dewikivoyage (https://de.wikivoyage.org/w/index.php?title=Modul:Marker_utilities/i18n&oldid=1768059)
-- Separating code from internationalization
return {
-- module administration
moduleInterface = {
suite = 'Marker utilities',
sub = 'i18n',
serial = '2026-04-12',
item = 65441686
},
dates = { yyyymmdd = { p = '^20[0-5]%d%-[01]?%d%-[0-3]?%d$', f = 'j. M Y' },
yyyy = { p = '^20[0-5]%d$', f = 'Y' },
yy = { p = '^[0-5]%d$', f = 'Y' },
mmdd = { p = '^[01]?%d%-[0-3]?%d$', f = 'j. M' },
dd = { p = '^[0-3]?%d%.?$', f = 'j.' },
mm = { p = '^[01]?%d%.?$', f = 'M' },
lastedit = { f = 'F Y' },
asOf = { f = 'n/Y' }
},
fileExtensions = { 'tif', 'tiff', 'gif', 'png', 'jpg', 'jpeg', 'jpe',
'webp', 'xcf', 'ogg', 'ogv', 'svg', 'pdf', 'stl',
'djvu', 'webm', 'mpg', 'mpeg' },
months = { 'leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec',
'srpen', 'září', 'říjen', 'listopad', 'prosinec' },
monthAbbr = { 'led%.?', 'úno%.?', 'bře%.?', 'dub%.?', 'kvě%.?', 'čvn%.?',
'čvc%.?', 'srp%.?', 'zář%.?', 'říj%.?', 'lis%.?', 'pro%.?' },
-- Map related constants
map = {
coordURLformat = '//%s.wikivoyage.org/w/index.php?title=Special%%3AMapsources¶ms=%s_%s_%s&locname=%s',
defaultDmsFormat = 'f1', -- see: Module:Coordinates/i18n
defaultSiteType = 'type:landmark_globe:earth',
defaultZoomLevel = 17,
maxZoomLevel = 19, -- also to set in Module:GeoData, Module:Mapshape utilities/i18n
},
-- Wikidata properties
properties = {
appliesToJurisdiction = 'P1001',
appliesToPart = 'P518',
appliesToPeople = 'P6001',
capacity = 'P1083',
centerCoordinates = 'P5140',
commonsCategory = 'P373',
coordinates = 'P625',
endTime = 'P582', -- time
headquartersLoc = 'P159',
image = 'P18',
instanceOf = 'P31',
iso4217 = 'P498',
languageOfName = 'P407',
mainCategory = 'P910',
maximumAge = 'P4135',
minimumAge = 'P2899',
nameInNativeLang = 'P1559',
occupation = 'P106',
of = 'P642',
officialName = 'P1448',
pointInTime = 'P585',
propertyScope = 'P5314', -- for fees
quantity = 'P1114',
retrieved = 'P813',
roomNumber = 'P8733',
startTime = 'P580', -- time, for fees
streetAddress = 'P6375',
subclassOf = 'P279',
unitSymbol = 'P5061',
use = 'P366',
validInPeriod = 'P1264'
},
-- Groups of Wikidata properties
propTable = {
accessibility = { 'P2846' },
contactComments = { 'P366', 'P518', 'P642', 'P1001', 'P1559', 'P106' },
feeComments = { 'P5314', 'P518', 'P6001', 'P1264', 'P585', 'P2899',
'P4135', 'P642', 'P580' },
policyComments = { 'P518', 'P1001', 'P6001' },
quantity = { 'P1114', 'P1083' },
accessQuantity = { 'P1114', 'P1083', 'P2846' }
},
-- Wikidata properties representing a qualifier
qualifiers = {
mobilePhone = 'Q17517',
P8733 = 'Q180516',
roomNumber = 'Q180516'
},
-- Languages for fallbacks, except wiki language
langs = { 'en', 'cs', 'de' }, -- array can be empty
-- Display and performance options for vCard / Listing and Marker modules
-- additional options in Module:VCard/i18n
options = {
excludeColorTypes = true,
normalizeValues = { 'type', 'subtype', 'show', 'status', 'symbol' },
noStarParams = { 'nameExtra', 'nameLocal', 'alt', 'comment' },
noTypeMsgs = true, -- prevents display of maintenance( typeFromWD, typeIsGroup )
parameters = { 'commonscat', 'country', 'id', 'localLang', 'nameExtra', 'wikipedia' }, -- parameter is used
showLocalData = true, -- names, addresses, directions
showSisters = true, -- possible values true, false, 'atEnd'
usePropertyCateg = true, -- create maintenance categories for Wikidata properties
useTypeCateg = true, -- create maintenance categories for marker types
markerMetadata = true, -- add metadata at marker templates
-- text limit of content/description parameter
contentLimit = 1000,
groupsWithLimit = { buy = 1, drink = 1, eat = 1, sleep = 1 },
-- Wikidata related constants
searchLimit = 4, -- count of levels for P31-P279 search
-- useful but not necessary function calls
WDmediaCheck = false, -- check file names retrieved from Wikidata
mediaCheck = false, -- for better performance, otherwise expensive
-- mw.title.new( 'Media:' .. image ) call is used
secondaryCoords = false, -- adding listing coordinates to article database
-- using #coordinates parser function
skipPathCheck = false -- for URL check, see Module:UrlCheck
},
-- strings
texts = {
asOf = '; stav %s', -- with semicolon separator
from = 'od %s',
fromTo = '%s–%s',
to = 'do %s',
fromTo2 = '%s až %s',
-- General, i18n
-- black x-like cross
closeX = '[[File:Close x - black.png|15px|link=|class=noviewer|Unbekanntes Marker-Symbol]]',
missingName = 'Chybí název',
-- In case of CJK languages no spaces are used with punctuation
-- Enumeration commas. voy-listing-comma is used for alt names only
comma = '<span class="voy-listing-comma">, </span>', -- with zero-width space
commaSeparator = ', ',
period = '.',
periodSeparator= '. ',
-- Space following a punctuation mark
space = ' ',
nbSpace = ' ',
parentheses = ' (%s)',
emph = "''%s''",
-- Formatting numbers: replacement patterns
decimalPoint = ',',
groupSeparator = '.',
-- Anchor id
anchor = 'vCard_%s',
-- Marker
CategoryNS = { '[Cc]ategory', '[Kk]ategorie' },
FileNS = { '[Ff]ile', '[Ss]oubor', '[Oo]brázek' },
latitude = 'Zeměpisná šířka',
longitude = 'Zeměpisná délka',
tooltip = 'Kliknutím na značku se otevře mapa.',
-- vCard / Listing module
checkin = 'Check-in: %s',
checkout = 'Check-out: %s',
closed = 'Uzavřeno: %s',
closedPattern = '^[Uu]zavřeno:?%s*',
editInSource = 'upravit ve zdrojovém článku',
email = 'e-mail: %s',
expirationPeriod = 'now - 3 years',
fax = 'Fax: %s',
hintName = 'Název v místním jazyce %s',
hintLatin = 'Název v latinském přepisu',
hintAddress = 'Adresa v místním jazyce %s',
hintAddress2 = 'Adresa v %s',
hintDirections = 'Pokyny v místním jazyce %s',
hours = 'Otevřeno: %s',
iata = '[[International Air Transport Association|IATA]]: %s',
icao = '[[Mezinárodní organizace pro civilní letectví|ICAO]]: %s',
lastedit = 'Aktualizace: %s',
lasteditNone = 'není specifikováno',
maybeOutdated = '(Informace mohou být zastaralé)[[Kategorie:Údržba:Bod:zastaralé informace]]',
mobile = 'Mobil: %s',
payment = 'Přijímané způsoby platby: %s',
phone = '<abbr title="Telefon">Tel.</abbr>: %s',
price = 'Cena: %s',
subtype = 'Vlastnost: %s.',
subtypes = 'Vlastnosti: %s.',
subtypeAbbr = '<abbr title="%s">%s</abbr>',
subtypeFile = '[[File:%s|x14px|link=|class=noviewer voy-listing-subtype-icon|%s]]',
-- for subtype icons like Michelin stars
subtypeSpan = '<span title="%s">%s</span>',
subtypeWithCount = '%d %s',
tollfree = '<abbr title="Telefon">Tel.</abbr> zdarma: %s'
},
-- format strings for mu.addMaintenance
formats = {
category = '[[Kategorie:%s]]',
error = ' <span class="error">%s</span>',
hint = ' <span class="voy-listing-check-recommended" style="display: none;">%s</span>'
},
-- maintenance
maintenance = {
-- general
properties = '[[Kategorie:Monitoring:Data z Wikidat]]', --myslím že není třeba kategorizovat
type = { category = 'Monitoring:Data z Wikidat' }, --myslím že není třeba kategorizovat
group = { category = 'Monitoring:Data z Wikidat' }, --myslím že není třeba kategorizovat
urlWithIP = { category = 'Údržba:Špatná URL', hint = 'URL obsahuje IP adresu' },
wrongUrl = { category = 'Údržba:Neplatná URL', err = 'neplatná URL' },
commonscatWD = { category = 'Monitoring:Data z Wikidat' }, --myslím že není třeba kategorizovat
contentTooLong = { category = 'Údržba:Popis je příliš dlouhý', err = 'Popis je příliš dlouhý' },
-- currencyTooltip= { category = 'VCard: Währungstooltips eingesetzt' }, --myslím že není třeba kategorizovat
dmsCoordinate = { category = 'Údržba:DMS-souřadnice', hint = 'DMS-souřadnice' },
duplicateAliases = { category = 'Údržba:Stránky s duplicitním voláním šablon', err = 'Duplicitní aliasy: %s' },
headquarters = { category = 'VCard: Koordinate der Hauptverwaltung' },
labelFromWD = { category = 'Monitoring:Data z Wikidat', hint = 'Štítek z Wikidat' }, --myslím že není třeba kategorizovat; když tam kategorie není tak to hází chybu
-- linkIsRedirect = { category = 'VCard: Artikellink ist Weiterleitung' }, --myslím že není třeba kategorizovat
linkToOtherWV = { category = 'Údržba:Odkaz na jiné wikicesty' },
malformedName = { category = 'Údržba:Špatný název', err = 'Špatný název' },
missingImg = { category = 'Údržba:Stránky s neexistujícím souborem', err = 'Neexistující soubor: %s' },
missingNameMsg = { category = 'Údržba:Šablona Bod beze jména', err = 'Chybí název' },
missingType = { category = 'Údržba:Šablona Bod bez typu', hint = 'Chybí typ' },
nameFromWD = { category = 'Monitoring:Data z Wikidat', hint = 'Název z Wikidat' }, --myslím že není třeba kategorizovat
nameWithStar = { category = 'Údržba:Šablona Bod s hvězdičkou ve jméně', err = 'Název obsahuje hvězdičku' },
outdated = { category = 'Údržba:Akce ukončena', err = 'Akce ukončena' },
parameterUsed = { category = 'Údržba:Použitý parametr %s' }, --myslím že není třeba kategorizovat
deleteShowCopy = { category = 'Údržba:Kopie smazána', hint = 'show=kopie smazána' },
-- showInlineUsed = { category = 'VCard: show=inline gesetzt' }, --myslím že není třeba kategorizovat
-- showNoneUsed = { category = 'VCard: show=none gesetzt' },
-- showPoiUsed = { category = 'VCard: show=poi gesetzt' }, --myslím že není třeba kategorizovat
typeFromWDchain= { category = 'Monitoring:Data z Wikidat', hint = 'Typ z Wikidat' },
-- typeIsGroup = { category = 'Údržba:Chybné hodnoty', hint = 'Typ je název skupiny' },
-- typeIsColor = { category = 'Údržba:Chybné hodnoty', hint = 'Typ je název barvy' },
-- typeIsColor is not used if excludeColorTypes = true
unknownCountry = { category = 'Údržba:Články s neznámým kódem země', err = 'Neznámý kód země' },
unknownGroup = { category = 'Údržba:Šablona Bod s neznámou skupinou', err = 'Neznámá skupina' },
unknownLanguage= { category = 'Údržba:Šablona Bod s neznámým jazykem', hint = 'Neznámý místní jazyk' },
unknownParam = { category = 'Údržba:Články s neznámými parametry', err = 'Neznámý parametr: %s' },
unknownParams = { category = 'Údržba:Články s neznámými parametry', err = 'Neznámé parametry: %s' },
unknownPropertyLanguage= { category = 'Údržba:Šablona Bod s neznámým jazykem', hint = 'Neznámý jazyk pro vlastnost' },
unknownStatus = { category = 'Údržba:Šablona Bod s neznámým statusem', err = 'Neznámý status' },
unknownType = { category = 'Údržba:Chybné hodnoty', err = 'Neznámý typ: %s' },
-- unusedRedirect = { category = 'VCard: Unbenutzter Weiterleitungs-Sitelink' },
urlIsSocialMedia = { category = 'Údržba:Špatná URL', err = 'URL ze sociálních sítí' },
wikidata = { category = 'Monitoring:Data z Wikidat' },
wrongCoord = { category = 'Údržba:Šablona Bod s chybějícími souřadnicemi', err = 'Chybné souřadnice' },
wrongImgName = { category = 'Údržba:Chybný název souboru', err = 'Chybný název souboru' },
wrongQualifier = { category = 'Údržba:Nesprávný odkaz na Wikidata', err = 'Nesprávný odkaz na Wikidata' },
-- Marker module
missingCoord = { category = 'Údržba:Šablona Bod s chybějícími souřadnicemi', err = 'Chybí souřadnice' },
numberUsed = { category = 'Údržba:Chybné hodnoty' },
unknownIcon = { category = 'Údržba:Chybné hodnoty' },
-- vCard / Listing module
countryFromWD = { category = 'Monitoring:Data z Wikidat' },
missingCoordVc = { category = 'Údržba:Šablona Bod s chybějícími souřadnicemi' },
paymentUsed = { category = 'Monitoring:Zadána platební metoda' },
socialUrlUsed = { category = 'Údržba:URL sociálních sítí', hint = 'Použita URL sítě %s' },
unitFromWD = { category = 'Monitoring:Data z Wikidat' },
unknownLabel = { category = 'Údržba:Neznámý štítek nebo id' },
unknownMAKI = { category = 'Údržba:Neznámý symbol MAKI', hint = 'Neznámý symbol MAKI' },
unknownShow = { category = 'Údržba:Chybné hodnoty', err = 'Hodnota(y) pro show neznámá: %s' },
unknownSubtype = { category = 'Údržba:Chybné hodnoty', err = 'Hodnota(y) pro podtyp neznámý: %s' },
unknownUnit = { category = 'Údržba:Chybné hodnoty', hint = 'Neznámá entita' },
unknowWDfeatures = { category = 'Údržba:Šablona Bod s neznámými charakteristikami Wikidat', hint = 'Neznámé charakteristiky Wikidat' },
wdWithGoogleCid = { category = 'VCard: Parametr google-maps používaný společně s Wikidaty', hint = 'google-maps použito s Wikidaty' },
wikidataWithId = { category = 'VCard: Parametr id používaný společně s Wikidaty', hint = 'id použito s Wikidaty' },
wrongDate = { category = 'Údržba:Články s chybami v datech', hint = 'Nesprávné datum' },
wrongGoogleCid = { category = 'VCard: Nesprávné ID zákazníka Google map', err = 'Nesprávné ID zákazníka Google map' },
wrongId = { category = 'VCard: Nesprávné id', err = 'Nesprávné id' },
wrongSocialId = { category = 'Údrža:Nesprávné ID sociální sítě', err = 'Nesprávné ID %s' },
wrongSocialUrl = { category = 'Údržba:Neplatná URL', err = 'Chybná URL %s' }
},
iconTitles = {
commons = '%s na Wikimedia Commons',
facebook = '%s na Facebooku',
flickr = '%s na Flickru',
instagram = '%s na Instagramu',
internet = 'Web tohoto místa',
maps = '%s na mapách a v plánovačích tras',
rss = 'RSS webový zdroj této instituce',
tiktok = '%s na TikToku',
wikidata = '%s (%s) na Wikidatech',
wikipedia = '%s na Wikipedii',
wikivoyage = '%s na Wikicestách (Wikivoyage) v jiném jazyce',
x = '%s na X',
youtube = '%s na YouTube'
},
-- social media services
services = {
{ key = 'facebook', url = 'https://www.facebook.com/%s', pattern = { '^[-.%d%w][-_.%d%w]+$', '^[^%z\1-,/:-?\91-\94{-~]+/[1-9]%d+$' } },
{ key = 'flickr', url = 'https://www.flickr.com/photos/%s', pattern = '^%d%d%d%d%d+@N%d%d$' },
{ key = 'instagram', url = 'https://www.instagram.com/%s/', pattern = { '^[0-9a-z_][0-9a-z._]+[0-9a-z_]$', '^explore/locations/%d+$' } },
{ key = 'tiktok', url = 'https://www.tiktok.com/@%s', pattern = '^[0-9A-Za-z_][0-9A-Za-z_.]+$' },
{ key = 'x', url = 'https://x.com/%s', pattern = '^[0-9A-Za-z_]+$' },
{ key = 'youtube', url = { 'https://www.youtube.com/channel/%s', 'https://www.youtube.com/%s' },
pattern = { '^UC[-_0-9A-Za-z]+[AQgw]$', '^@[-0-9A-Za-z_.][-0-9A-Za-z_.][-0-9A-Za-z_.]+$' } }
},
--[[ status symbols
g: successive symbol group number
alias: status alias
label: image tag title
category = 1: add maintenance category
--]]
statuses = {
['top-hotel'] = { g = 1, label = 'Top-Hotel', category = 1 },
['top-restaurant'] = { g = 1, label = 'Top-Restaurace', category = 1 },
['top-sight'] = { g = 1, label = 'Top-Atrakce', category = 1 },
recommendation = { g = 1, label = 'Doporučení' },
none = { g = 2, alias = 'class-0', label = "Bez klasifikace" },
stub = { g = 2, alias = 'class-1', label = "Pahýl" },
outline = { g = 2, alias = 'class-2', label = "Návrh článku" },
usable = { g = 2, alias = 'class-3', label = "Užitečný článek" },
guide = { g = 2, alias = 'class-4', label = "Celý článek" },
star = { g = 2, alias = 'class-5', label = "Doporučený článek" }
},
-- Marker name styles
-- Colors in Template:VCard/styles.css
nameStyles = {
inherit = 'font-weight: inherit; font-style: inherit;',
italic = 'font-weight: normal; font-style: italic;',
kursiv = 'font-weight: normal; font-style: italic;', -- de: kursiv = italic
normal = 'font-weight: normal; font-style: normal;',
station = 'font-weight: normal; white-space: nowrap; padding-left: 2px; padding-right: 2px;'
},
-- yes/no variants
yesno = {
y = 'y',
yes = 'y',
j = 'y',
ja = 'y',
a = 'y',
ano = 'y',
n = 'n',
no = 'n',
nein = 'n',
ne = 'n'
},
-- List of currencies without conversion tooltips
noCurrencyConversion = {
-- all = 1, -- no rate conversion tooltips are shown
-- there is no confusion with (uppercase) ALL = "Q125999"
EUR = 1 -- local currency
},
-- Language-dependent sorting substitutes
substitutes = {
{ l = 'ä', as = 'a' },
{ l = 'ö', as = 'o' },
{ l = 'ü', as = 'u' },
{ l = 'ß', as = 'ss' }
}
}
5fz0w74j7zehv2sdervy438hefkl6bt
MediaWiki:Gadget-Poi2gpx.js
8
1461
22112
18326
2026-05-20T13:04:42Z
LiMr
96
aktualizace na novější verzi
22112
javascript
text/javascript
//<nowiki>
/********************************************************************/
// Přeneseno z https://de.wikivoyage.org/wiki/MediaWiki:Gadget-Poi2gpx.js
/*********************************************************************
* poi2gpx v1.5, 2026-04-21
* Download of article’s points of interest and tracks to a GPX file
* Original author: Roland Unger
* Support of desktop and mobile views
* Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:Gadget-Poi2gpx.js
* License: GPL-2.0+, CC-by-sa 3.0
*********************************************************************/
/* eslint-disable mediawiki/class-doc */
( function ( $, mw ) {
'use strict';
// technical constants
const version = '2026-04-21',
minervaPageActionsSelector = '.page-actions-menu #page-actions-edit',
imgSrc = '//upload.wikimedia.org/wikivoyage/de/thumb/5/5f/WV-poi2gpx-green.svg/60px-WV-poi2gpx-green.svg.png',
imgSrcMinerva = '//upload.wikimedia.org/wikivoyage/de/thumb/6/63/WV-poi2gpx-black.svg/60px-WV-poi2gpx-black.svg.png',
// image for download link
allowedNamespaces = [
0, // Main
2, // User
4 // Project
],
commentClasses = [ 'voy-listing-hours', 'voy-listing-checkin',
'voy-listing-checkout', 'voy-listing-price', 'voy-listing-credit' ],
containerClass = 'vcard',
// contains wrapper markup of a single marker or listing
contentClass = 'voy-listing-content',
dataColor = 'data-color',
dataName = 'data-name',
dataPhone = 'data-phone',
dataType = 'data-group', // other wikis: 'data-type'
dataUrl = 'data-url',
dataMw = 'data-mw',
fallbackLang = 'en',
kartographerClass = 'mw-kartographer-maplink',
nameClass = 'voy-listing-name',
noGpxClass = 'voy-listing-no-gpx';
// strings depending on page language
// depending on group names defined in Module:Marker utilities/Groups
const wikiStrings = {
de: {
track: 'Track'
},
en: {
track: 'track'
},
es: {
track: 'sendero'
},
fr: {
track: 'piste'
},
it: {
track: 'traccia'
},
cs: {
track: 'trasa'
}
};
// strings depending on user language
const userStrings = {
de: {
gpxFileDescr: 'Kartenpositionen aus dem deutschen Wikivoyage-Artikel',
gpxLabel: 'GPX',
gpxTitle: 'Download der Kartenpositionen als GPX-Datei'
},
en: {
gpxFileDescr: 'Map positions from the German Wikivoyage article',
gpxLabel: 'GPX',
gpxTitle: 'Download of the map positions as a GPX file'
},
es: {
gpxFileDescr: 'Posiciones en el mapa del artículo de Wikivoyage en alemán',
gpxLabel: 'GPX',
gpxTitle: 'Descarga de las posiciones del mapa como archivo GPX'
},
fr: {
gpxFileDescr: 'Positions sur la carte de l’article de Wikivoyage allemand',
gpxLabel: 'GPX',
gpxTitle: 'Téléchargement des positions de la carte sous forme de fichier GPX'
},
it: {
gpxFileDescr: 'Posizioni sulla mappa dall’articolo tedesco di Wikivoyage',
gpxLabel: 'GPX',
gpxTitle: 'Download delle posizioni della mappa come file GPX'
},
cs: {
gpxFileDescr: 'Pozice na mapě z článku na českých Wikicestách',
gpxLabel: 'GPX',
gpxTitle: 'Stáhnout mapové body jako soubor GPX'
}
};
// internal use
const pageLang = mw.config.get( 'wgPageContentLanguage' ),
userLang = mw.config.get( 'wgUserLanguage' ),
pageTitle = mw.config.get( 'wgTitle' ),
isMinerva = mw.config.get( 'skin' ) === 'minerva'; // mobile view
let gpxFile = null, // check for URL object
trackdata = null,
messages = {};
// copying translation strings to messages depending on chain languages
const addMessages = ( strings, chain ) => {
for ( let i = chain.length - 1; i >= 0; i-- ) {
if ( strings.hasOwnProperty( chain[ i ] ) ) {
$.extend( messages, strings[ chain[ i ] ] );
}
}
};
// copying translation strings to messages
const setupMessages = () => {
addMessages( wikiStrings, [ pageLang, fallbackLang ] );
const chain = ( userLang == pageLang ) ? [ pageLang, fallbackLang ] :
[ userLang, pageLang, fallbackLang ];
addMessages( userStrings, chain );
};
// to use text in XML tags
const htmlEncode = ( text ) => {
return text.replace( /\&/g, '&' )
.replace( /"/g, '"' )
.replace( /</g, '<' )
.replace( />/g, '>' );
};
const removeTags = ( s ) => {
return $( '<div>' + s + '</div>' ).text();
};
const getString = ( prop ) => {
if ( !prop ) {
return '';
}
if ( typeof( prop ) == 'string' ) {
return prop;
}
if ( prop[ pageLang ] ) {
return prop[ pageLang ];
} else if ( prop.en ) {
return prop.en;
}
for ( let i in prop ) {
return prop[ i ];
}
return '';
};
const makeFile = ( text ) => { // modern Browsers
const data = new Blob( [ text ], { type: 'application/gpx+xml' } );
if ( !gpxFile ) {
window.URL.revokeObjectURL( gpxFile );
}
gpxFile = window.URL.createObjectURL( data );
return gpxFile;
};
const getPhone = ( selector, $this ) => {
const v = $( selector, $this ).first();
if ( v.length ) {
let phone = v.attr( dataPhone );
if ( phone ) {
return phone;
}
}
return '';
};
// Getting GeoJSON data sets from external sources (OSM, Commons)
const getGeoJSON = ( obj ) => {
let promise, coordinates, geometry, i;
const properties = obj.properties; // for all but not for 'page'
promise = $.getJSON( obj.url ).then( function( geoJSON ) {
switch ( obj.service ) {
case 'page': // from Commons
if ( geoJSON.jsondata && geoJSON.jsondata.data ) {
$.extend( obj, geoJSON.jsondata.data );
}
break;
case 'geoline': // from OSM
case 'geoshape':
$.extend( obj, geoJSON );
if ( properties ) {
for ( i = 0; i < obj.features.length; i++ ) {
if ( $.isEmptyObject( obj.features[ i ].properties ) ) {
obj.features[ i ].properties = properties;
} else {
obj.features[ i ].properties =
$.extend( {}, properties, obj.features[ i ].properties );
}
}
}
}
}, function() {
// failed, no tracks will be added
} );
return promise;
};
// getting Kartographer live data. It is used to extract information on
// external data if these are members of the track group
const getKartographerLiveData = () => {
let i, obj, promiseArray = [];
const liveData = mw.config.get( 'wgKartographerLiveData' );
if ( liveData ) {
trackdata = liveData[ messages.track ];
if ( trackdata && !trackdata.length ) {
trackdata = null;
}
if ( trackdata ) {
for ( i = 0; i < trackdata.length; i++ ) {
obj = trackdata[ i ];
if ( obj.type === 'ExternalData' && obj.url ) {
promiseArray.push( getGeoJSON( obj ) );
}
}
}
}
// wait for getting all external data
if ( typeof Promise !== 'undefined' ) {
Promise.all( promiseArray )
.then( function() { createFile(); } )
.catch( function() { createFile(); } );
// create file also in case of failures
} else {
createFile();
}
return;
};
// format a single track for use in a gpx file
const writeTrack = ( coordinates, tracks, type, properties ) => {
if ( !coordinates || !coordinates.length ) {
return tracks;
}
let j, k, s, coords;
tracks += '\n <trk>\n';
if ( properties ) {
s = htmlEncode( removeTags( getString( properties.title ) ) );
if ( s ) {
tracks += ' <name>' + s + '</name>\n';
}
s = htmlEncode( removeTags( getString( properties.desc ) ) );
if ( s ) {
tracks += ' <desc>' + s + '</desc>\n';
}
if ( properties.stroke ) {
tracks += ' <extensions>\n' +
' <gpxx:WaypointExtension xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">\n' +
' <gpxx:DisplayColor>' + properties.stroke + '</gpxx:DisplayColor>\n' +
' </gpxx:WaypointExtension>\n' +
' </extensions>\n';
}
}
for ( j = 0; j < coordinates.length; j++ ) {
coords = coordinates[ j ];
if ( type === 'MultiPolygon' ) {
coords = coordinates[ j ][ 0 ];
// only first polygon
// tests not yet completed
}
if ( coords.length ) {
tracks += ' <trkseg>\n';
for ( k = 0; k < coords.length; k++ ) {
tracks += ' <trkpt lat="' + coords[ k ][ 1 ]
+ '" lon="' + coords[ k ][ 0 ] + '" />\n';
}
tracks += ' </trkseg>\n';
}
}
return tracks + ' </trk>\n';
};
// callect all tracks which are members of the track group
const writeTracks = () => {
if ( !trackdata || !trackdata.length ) {
return '';
}
let i, coordinates, geoJSON, geometry, properties,
tracks = '';
for ( i = 0; i < trackdata.length; i++ ) {
if ( trackdata[ i ].features ) {
geoJSON = trackdata[ i ].features[ 0 ];
geometry = geoJSON.type === 'Feature' ? geoJSON.geometry : geoJSON;
coordinates = geometry ? geometry.coordinates : null;
properties = geoJSON.properties;
switch ( geometry.type ) {
case 'LineString':
tracks = writeTrack( [ coordinates ], tracks, 'MultiLineString', properties );
break;
case 'MultiLineString':
case 'Polygon':
tracks = writeTrack( coordinates, tracks, 'MultiLineString', properties );
break;
case 'MultiPolygon':
tracks = writeTrack( coordinates, tracks, 'MultiPolygon', properties );
}
}
}
return tracks;
};
// get information from all markers (vCard and marker templates) exluding
// external data and put them into xml of gpx files. Adding track data
// at the end
const getText = () => { // generate GPX output
let markers = $( '.' + containerClass ).not( '.' + noGpxClass );
if ( !markers.length ) {
return '';
}
let aType, cmt, color, count, desc, gpxx, i, link, lat, lon, name,
text = '', params, v,
minlat = null, minlon = null, maxlat = null, maxlon = null; // for bounds
markers.each( function() {
const $this = $( this );
link = $( '.' + kartographerClass, $this ).first();
if ( link.length ) {
lat = link.attr( 'data-lat' );
lon = link.attr( 'data-lon' );
if ( minlat === null || lat < minlat ) {
minlat = lat;
}
if ( minlon === null || lon < minlon ) {
minlon = lon;
}
if ( maxlat === null || lat > maxlat ) {
maxlat = lat;
}
if ( maxlon === null || lon > maxlon ) {
maxlon = lon;
}
color = $this.attr( dataColor );
aType = $this.attr( dataType ); // fallback legacy parser
// dataMw is only available if Parsoid was used
params = link.attr( dataMw );
if ( params ) {
params = params.replace( /"/g, '"' );
try {
params = JSON.parse( params );
} catch ( e ) {
// invalid JSON
params = {};
}
// params.attrs.group contains the value of the group
// argument of the maplink tag, ie. the translated group
// value
if ( params.attrs && params.attrs.group ) {
aType = params.attrs.group;
}
}
count = link.html();
if ( count.indexOf( '<' ) >= 0 ) {
count= ''; // no number but html tag
} else {
count = ' ' + ( '0' + count ).slice( -2 );
}
name = $this.attr( dataName );
if ( !name ) {
name = $( '.' + nameClass, $this ).first();
}
name = htmlEncode( removeTags( name ) );
desc = $( '.' + contentClass, $this ).first();
desc.find( '.voy-listing-map, .voy-listing-coordinates' ).remove();
desc = ( desc.length ) ?
htmlEncode( desc.text().replace( //g, '' ).replace( /\s+/g, ' ' ) ) : '';
// removal of whitespaces and zero-width spaces
cmt = '';
for ( i = 0; i < commentClasses.length; i++ ) {
v = $( '.' + commentClasses[ i ], $this ).first();
if ( v.length ) {
if ( cmt ) {
cmt += ' ';
}
cmt += htmlEncode( v.text() );
}
}
gpxx = '';
v = $( '.voy-listing-address', $this ).first();
if ( v.length ) {
gpxx += ' <gpxx:Address>\n' +
' <gpxx:StreetAddress>' + htmlEncode( v.text() ) + '</gpxx:StreetAddress>\n' +
' </gpxx:Address>\n';
}
v = getPhone( '.voy-listing-landline .voy-listing-phone-number', $this );
if ( v ) {
gpxx += ' <gpxx:PhoneNumber Category="Phone">' + v + '</gpxx:PhoneNumber>\n';
}
v = getPhone( '.voy-listing-tollfree .voy-listing-phone-number', $this );
if ( v ) {
gpxx += ' <gpxx:PhoneNumber Category="Tollfree">' + v + '</gpxx:PhoneNumber>\n';
}
v = getPhone( '.voy-listing-mobile .voy-listing-phone-number', $this );
if ( v ) {
gpxx += ' <gpxx:PhoneNumber Category="Mobile">' + v + '</gpxx:PhoneNumber>\n';
}
v = getPhone( '.voy-listing-fax .voy-listing-phone-number', $this );
if ( v ) {
gpxx += ' <gpxx:PhoneNumber Category="Fax">' + v + '</gpxx:PhoneNumber>\n';
}
v = $( '.voy-listing-email a', $this ).first();
if ( v.length ) {
gpxx += ' <gpxx:PhoneNumber Category="Email">' + v.text() + '</gpxx:PhoneNumber>\n';
}
v = $this.attr( dataUrl );
if ( v ) {
gpxx += ' <gpxx:PhoneNumber Category="URL">' + htmlEncode( v ) + '</gpxx:PhoneNumber>\n';
}
text += ' <wpt lat="' + lat + '" lon="' + lon + '">\n' +
' <name>[' + aType + count + '] ' + name + '</name>\n' +
' <type>' + aType + '</type>\n' +
' <extensions>\n' +
// ' <color>' + color + '</color>\n' +
' <gpxx:WaypointExtension xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">\n' +
' <gpxx:DisplayColor>' + color + '</gpxx:DisplayColor>\n' +
' <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>\n' +
gpxx +
' </gpxx:WaypointExtension>\n' +
' </extensions>\n';
if ( desc ) {
text += ' <desc>' + desc + '</desc>\n';
}
if ( cmt ) {
text += ' <cmt>' + cmt + '</cmt>\n';
}
text += ' </wpt>\n';
}
});
text += writeTracks();
if ( !text ) {
return '';
}
return '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n' +
'<gpx version="1.1" creator="Wikivoyage"\n' +
' xmlns="http://www.topografix.com/GPX/1/1"\n' +
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' +
' xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"\n' +
' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\n' +
' http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd">\n\n' +
' <metadata>\n' +
' <name>' + htmlEncode( pageTitle ) + '</name>\n' +
' <desc>' + messages.gpxFileDescr + '</desc>\n' +
' <author>\n' +
' <name>Wikivoyage</name>\n' +
' </author>\n' +
' <copyright>\n' +
// ' <license>https://creativecommons.org/publicdomain/zero/1.0/</license>\n' +
' <license>https://creativecommons.org/licenses/by-sa/3.0/</license>\n' + // desc is CC-by-sa 3.0
' </copyright>\n' +
' <bounds minlat="'+ minlat + '" maxlat="' + maxlat + '" minlon="' + minlon +'" maxlon="' + maxlon + '"></bounds>\n' +
' </metadata>\n\n' +
text +
'</gpx>';
};
const createFile = () => {
const downloadText = getText();
if ( !downloadText ) {
return;
}
let fileName = pageTitle + '_' + pageLang + '.gpx';
fileName = fileName.replace( / |:|\/|\\/gi, '_' );
const image = $( '<img>', {
class: 'voy-indicator-img',
src: isMinerva ? imgSrcMinerva : imgSrc,
width: isMinerva ? '15' : '25',
height: isMinerva ? '20' : '25'
});
if ( isMinerva ) {
image.css( { 'margin-left': '3px' } ); // = ( 20 - 15 ) / 2
}
let indicator = $( '<a>', {
id: 'mw-indicator-i3-gpx',
class: 'mw-indicator', /* evtl + cdx-button */
title: messages.gpxTitle,
'data-version': version
} )
.css( { display: 'inline-block' } )
.append( image )
.attr( {
href: makeFile( downloadText ),
download: fileName
} );
if ( isMinerva ) { // mobile view
indicator.append( $( `<span>${messages.gpxLabel}</span>` ) );
indicator = $( '<li></li>', {
id: 'page-actions-poi2gpx',
class: 'page-actions-menu__list-item'
} )
.append( indicator );
$( minervaPageActionsSelector ).after( indicator );
} else {
const indicators = $( '.mw-indicators' ).first(); // always on desktop
let geoIndicator;
// international version: only:
// indicators.prepend( indicator );
indicators.each( function() {
geoIndicator = $( '#mw-indicator-i3-geo', $( this ) );
if ( geoIndicator.length ) {
geoIndicator.after( indicator );
} else {
$( this ).prepend( indicator );
}
});
}
};
const allowedForCurrentPage = () => {
const namespace = mw.config.get( 'wgNamespaceNumber' );
return allowedNamespaces.includes( namespace ) &&
mw.config.get( 'wgAction' ) == 'view';
};
const init = () => {
if ( !allowedForCurrentPage() ) {
return;
}
if ( typeof Blob === 'undefined' ) { // very old browsers
return;
}
setupMessages();
getKartographerLiveData();
// calls createFile
};
init();
} ( jQuery, mediaWiki ) );
//</nowiki>
pr29xia2ozcn1ngeayx4mxx9pjkv194
MediaWiki:Gadget-MapTools.js
8
1463
22111
18327
2026-05-20T12:59:16Z
LiMr
96
aktualizace na novější verzi
22111
javascript
text/javascript
//<nowiki>
/********************************************************************/
// Přeneseno z https://de.wikivoyage.org/wiki/MediaWiki:Gadget-MapTools.js
/*****************************************************************************
* mapTools v2.2, 2026-04-01
* Several map creation and supporting tools
* Original author: Roland Unger
* Support of desktop and mobile views
* Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:Gadget-MapTools.js
* License: GPL-2.0+, CC-by-sa 3.0
****************************************************************************/
/* eslint-disable mediawiki/class-doc */
( function( $, mw ) {
'use strict';
// technical constants
const version = '2026-04-01',
dataLat = 'data-lat',
dataLon = 'data-lon',
dataZoom = 'data-zoom',
dataName = 'data-name',
dataHeight = 'data-height',
dataOverlays = 'data-overlays',
fallbackLang = 'en';
// technical constants
const maxZoomLevel = 19,
defaultMaplinkZoomLevel = 17,
defaultMapZoomLevel = 14,
defaultProperties = {
'stroke-width': 2,
'fill-opacity': 0.5
},
indicatorSelector = '.voy-coord-indicator',
indicatorCoordsSelector = '.voy-coords a',
indicatorGlobeImgSrc = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Earth_-_The_Noun_Project.svg/20px-Earth_-_The_Noun_Project.svg.png',
indicatorMapContainerId = 'voy-topMap',
fullScreenContainerId = 'voy-fullScreenMap',
mapframeContainerSelector = '.mw-kartographer-container',
mapframeMapSelector = '.mw-kartographer-map',
markerSelector = '.vcard', // wrapper selector of a single marker or listing
kartographerSelector = '.mw-kartographer-maplink',
nameClass = 'voy-listing-name',
imageClass = 'voy-listing-image',
footCaptionSelector = '.oo-ui-windowManager-fullscreen .mw-kartographer-captionfoot',
captionMarkerClass = 'voy-caption-marker',
captionInverseMarkerClass = 'voy-caption-marker-invers',
minervaPageActionsSelector = '.page-actions-menu #page-actions-edit';
// strings depending on page content language
const wikiStrings = {
de: {
defaultShow: '["Maske","Track","Aktivität","Anderes","Anreise","Ausgehen","Aussicht","Besiedelt","Fehler","Gebiet","Gesundheit","Kaufen","Küche","Natur","Religion","Sehenswert","Unterkunft","aquamarinblau","cosmos","gold","hellgrün","orange","pflaumenblau","rot","silber","violett"]',
defaultGroupName: 'Karte',
mask: 'Maske',
track: 'Track'
},
en: {
defaultShow: '["mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]',
defaultGroupName: 'map',
mask: 'mask',
track: 'track'
},
es: {
defaultShow: '["máscara","sendero","área","beber","comer","comprar","dormir","error","habitadas","hacer","ir","otro","ver","vista","aguamarina","ciruela","cosmos","oro","lima","naranja","violeta","plata","rojo"]',
defaultGroupName: 'mapa',
mask: 'máscara',
track: 'sendero'
},
fr: {
defaultShow: '["aller","destination","diplomatie","loger","manger","sortir","ville","voir","mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]',
defaultGroupName: 'carte',
mask: 'mask',
track: 'piste'
},
it: {
defaultShow: '["mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]',
defaultGroupName: 'mappa',
mask: 'mask',
track: 'traccia'
}
};
// strings depending on user language
const userStrings = {
de: {
closeButtonTitle: 'Schließen',
indicatorActionLabel: 'Karte',
indicatorButtonTitle: 'Klick öffnet oder schließt die Karte für $1',
magnifyButtonTitle: 'Karte vergrößern',
mapCenter: 'Kartenzentrum',
mapOf: 'Karte von $1'
},
en: {
closeButtonTitle: 'Close',
indicatorActionLabel: 'Map',
indicatorButtonTitle: 'Click to open or close the map of $1',
magnifyButtonTitle: 'Enlarge map',
mapCenter: 'Map center',
mapOf: 'Map of $1'
},
es: {
closeButtonTitle: 'Cerrar',
indicatorActionLabel: 'Mapa',
indicatorButtonTitle: 'Haga clic para abrir o cerrar el mapa de $1',
magnifyButtonTitle: 'Aumentar mapa',
mapCenter: 'Centro del mapa',
mapOf: 'Mapa de $1'
},
fr: {
closeButtonTitle: 'Fermer',
indicatorActionLabel: 'Carte',
indicatorButtonTitle: 'Cliquez pour ouvrir ou fermer le carte de $1',
magnifyButtonTitle: 'Agrandir la carte',
mapCenter: 'Centre de la carte',
mapOf: 'Carte de $1'
},
it: {
closeButtonTitle: 'Chiudi',
indicatorActionLabel: 'Mappa',
indicatorButtonTitle: 'Clicca per aprire o chiudere la mappa di $1',
magnifyButtonTitle: 'Ingrandisci mappa',
mapCenter: 'Centro mappa',
mapOf: 'Mappa di $1'
}
};
// internal use
const $body = $( 'body' ),
pageLang = mw.config.get( 'wgPageContentLanguage' ),
userLang = mw.config.get( 'wgUserLanguage' ),
pageTitle = mw.config.get( 'wgTitle' ),
articlePath = mw.config.get( 'wgArticlePath' ),
thumbPath = '//upload.wikimedia.org/wikipedia/commons/thumb/',
scriptUrl = mw.format( 'https://wikivoyage.toolforge.org/w/data/$1-articles.js', pageLang ),
isMinerva = mw.config.get( 'skin' ) === 'minerva'; // mobile view
let defaultShowArray,
messages = {};
// storing GeoJSON data
let data = {};
// array of objects: { name: group.name, attribution: attributions }
let groups = [],
multiPointUsed = false;
// copying translation strings to messages depending on chain languages
const addMessages = ( strings, chain ) => {
for ( let i = chain.length - 1; i >= 0; i-- ) {
if ( strings.hasOwnProperty( chain[ i ] ) ) {
$.extend( messages, strings[ chain[ i ] ] );
}
}
};
// copying translation strings to messages
const setupMessages = () => {
addMessages( wikiStrings, [ pageLang, fallbackLang ] );
const chain = ( userLang == pageLang ) ? [ pageLang, fallbackLang ] :
[ userLang, pageLang, fallbackLang ];
addMessages( userStrings, chain );
};
// creating a Kartographer map
const createMap = ( id, center, zoom, caption, options, bgColor, textColor ) => {
mw.loader.using( [ 'ext.kartographer.box' ] ).then( function() {
const $id = $( '#' + id );
// for simple full-screen map
if ( !options.withDialog && options.isFullScreen ) {
$body.css( { overflow: 'hidden' } );
$id.css( { position: 'fixed', height: '100%', width: '100%',
top: 0, left: 0, 'z-index': 101 } ); // vector skin
}
// creating base map
// fortunately ext.kartographer.box is not validating the
// GeoJSON against the GeoJSON+simplestyle schema
// as it is done by maplink/mapframe tags
// https://github.com/mapbox/simplestyle-spec/tree/master/1.1.0
const kartoBox = require( 'ext.kartographer.box' ),
map = kartoBox.map( {
container: $id[ 0 ],
center: center,
zoom: zoom,
allowFullScreen: options.allowFullScreen,
alwaysInteractive: true,
captionText: caption,
fullscreen: options.isFullScreen,
featureType: options.featureType
} );
// following line is necessary for proper loading of
// map-dialog sidebar
map.initView( center, zoom );
// adding markers by group names to separate layers
let group, i, j, layerOptions;
if ( options.withData && groups.length ) {
for ( i = 0; i < options.show.length; i++ ) {
for ( j = 0; j < groups.length; j++ ) {
group = groups[ j ];
if ( group.name === options.show[ i ] ) {
layerOptions = { name: group.name };
if ( group.attribution !== '' ) {
layerOptions.attribution = group.attribution;
}
map.addGeoJSONLayer( data[ group.name ], layerOptions );
break;
}
}
}
}
// adding dialog to full-screen map
if ( options.withDialog ) {
$id.addClass( 'mw-kartographer-mapDialog-map' );
mw.loader.using( 'ext.kartographer.dialog' ).done( function() {
map.doWhenReady( function() {
require( 'ext.kartographer.dialog' ).render( map );
} );
} );
} else {
// adding Close control to non-full-screen map if required
if ( options.withClose ) {
const controls = $( '.leaflet-top.leaflet-right', $id ),
control = $( '<div class="leaflet-bar leaflet-control-static leaflet-control"></div>' )
.append( $( '<a class="voy-icon-close"></a>',
{ title: messages.closeButtonTitle,
role: 'button', 'aria-disabled': 'false' } )
.click( function() {
$id.remove();
if ( options.isFullScreen ) {
$body.css( { overflow: 'auto' } );
}
} )
);
controls.prepend( control );
}
// adding Nearby and Layers controls using Kartographer.js
if ( options.withControls ) {
mw.hook( 'wikipage.maps' ).fire( map );
}
}
map.doWhenReady( function() {
// remove inert attribute
$id.removeAttr( 'inert' );
if ( bgColor && options.withDialog ) {
setTimeout( function() {
const footCaption = $( footCaptionSelector );
if ( footCaption.length ) {
const captionArray = footCaption.text().split(":"),
classes = captionMarkerClass;
footCaption.html( mw.format(
'<span class="$1" style="background-color: $2; color: $3">$4</span>$5',
classes, bgColor, textColor, captionArray[ 0 ], captionArray[ 1 ] || '' ) );
}
}, 700);
}
} );
} );
};
// creating GeoJSON data separated by group
const singleDataset = ( bgColor, symbol, title, lat, lon, description, group ) => {
if ( !data.hasOwnProperty( group ) ) {
data[ group ] = [];
}
data[ group ].push( {
'type': 'Feature',
properties: {
'marker-color': bgColor,
'marker-size': 'medium',
'marker-symbol': symbol ? symbol.toLowerCase() : symbol,
title: title,
description: description
},
geometry: {
'type': 'Point',
coordinates: [ lon, lat ]
}
} );
};
// Getting GeoJSON data sets from external sources (OSM, Commons)
const getGeoJSON = ( obj ) => {
const world = [ [ [ 3600, -180 ], [ 3600, 180 ], [ -3600, 180 ], [ -3600, -180 ], [ 3600, -180 ] ] ];
let promise, coordinates, feature, geometry, i, j,
properties = obj.properties; // for all but not for 'page'
promise = $.ajax( { // instead of $.getJSON
dataType: 'json',
url: obj.url,
timeout: 3000
} ).then( function( geoJSON ) {
switch ( obj.service ) {
case 'page':
if ( geoJSON.jsondata && geoJSON.jsondata.data ) {
$.extend( obj, geoJSON.jsondata.data );
}
break;
case 'geomask':
coordinates = world;
for ( i = 0; i < geoJSON.features.length; i++ ) {
geometry = geoJSON.features[ i ].geometry;
if ( !geometry ) {
continue;
}
// push only first polygon
switch ( geometry.type ) {
case 'Polygon':
coordinates.push( geometry.coordinates[ 0 ] );
break;
case 'MultiPolygon':
for ( j = 0; j < geometry.coordinates.length; j++ ) {
coordinates.push( geometry.coordinates[ j ][ 0 ] );
}
}
}
obj.type = 'Feature';
obj.geometry = { type: 'Polygon', coordinates: coordinates };
if ( !properties ) {
properties = defaultProperties;
}
if ( $.isEmptyObject( obj.properties ) ) {
obj.properties = properties;
} else {
obj.properties = $.extend( {}, properties, obj.properties );
}
break;
case 'geoline':
case 'geoshape':
$.extend( obj, geoJSON );
if ( properties ) {
for ( i = 0; i < obj.features.length; i++ ) {
feature = obj.features[ i ];
if ( $.isEmptyObject( feature.properties ) ) {
feature.properties = properties;
} else {
feature.properties =
$.extend( {}, properties, feature.properties );
}
}
}
}
}, function() {
// failed. Do nothing.
} );
return promise;
};
// Creating attribution strings
const getAttribution = ( obj ) => {
let link = '';
switch ( obj.service ) {
case 'page':
const url = new URL( obj.url, location.origin ),
title = url.searchParams.get( 'title' );
link = mw.msg( 'project-localized-name-commonswiki' ) + ': ' +
'<a target="_blank" href="' +
'//commons.wikimedia.org/wiki/Data:' + encodeURI( title ) +
'">' + title + '</a>';
break;
default: // other services
}
return link;
};
// getting Kartographer live data
const getKartographerLiveData = () => {
let group, i, obj,
promiseArray = [],
attributions, link;
data = mw.config.get( 'wgKartographerLiveData' );
if ( data ) {
groups = []; // start with empty global array
for ( group in data ) {
// ignoring empty groups
if ( data[ group ].length ) {
attributions = [];
for ( i = 0; i < data[ group ].length; i++ ) {
obj = data[ group ][ i ];
if ( obj.geometry && obj.geometry.type === 'MultiPoint' ) {
multiPointUsed = true;
}
// expand external data
if ( obj.type === 'ExternalData' && obj.url ) {
promiseArray.push( getGeoJSON( obj ) );
}
if ( obj.service ) {
link = getAttribution( obj );
if ( link !== '' ) {
attributions.push( link );
}
}
}
attributions = attributions.join( ', ' );
groups.push( { name: group, attribution: attributions } );
}
}
}
// wait for getting all external data
// regardless of failures, addMapTools() will be executed
if ( data && typeof Promise !== 'undefined' ) {
Promise.all( promiseArray )
.then( function() {
addMapTools();
} )
// initialization also in case of failures
// maybe external data are not shown
.catch( function() {
addMapTools();
} );
} else {
addMapTools(); // for really old browsers
}
};
// returning zoom parameter string as a valid number
const getZoom = ( s, defaultValue ) => {
const zoom = ( typeof s == 'string' ) ? parseInt( s ) : -1;
if ( zoom < 0 || zoom > maxZoomLevel ) {
return defaultValue || defaultMapZoomLevel;
}
return zoom;
};
const makeContainer = ( id ) => {
$( '#' + id ).remove();
return $( '<div></div>', { id: id, role: 'dialog', 'data-version': version } );
};
// displaying a map by clicking the geo-indicator button
const indicatorMap = () => {
let indicator = $( indicatorSelector ).first();
if ( !indicator.length ) {
return;
}
if ( !data ) {
data = {};
groups = [];
defaultShowArray.push( messages.defaultGroupName );
}
$( indicatorCoordsSelector ).attr( 'target', '_blank' );
const id = indicatorMapContainerId,
options = {
withClose: true,
withControls: true,
withData: true,
show: defaultShowArray,
withDialog: false,
allowFullScreen: true,
isFullScreen: false,
featureType: 'mapframe'
};
const zoom = getZoom( indicator.attr( dataZoom ) ),
lat = indicator.attr( dataLat ),
lon = indicator.attr( dataLon ),
center = [ lat, lon ];
// no POIs --> show blue map-center marker
if ( !groups.length ) {
singleDataset( '#3366cc', '', messages.mapCenter, lat, lon, '',
messages.defaultGroupName );
groups = [ { name: messages.defaultGroupName, attribution: '' } ];
}
// add or modify indicator action buttons
const mapTitle = mw.format( messages.mapOf, pageTitle );
if ( isMinerva ) { // mobile view
// add indicator action button and event handler
const indicatorImg = $( '<img>', {
class: 'voy-indicator-img',
src: indicatorGlobeImgSrc,
width: '20', height: '20'
} );
indicator = $( '<a>', {
id: 'mw-indicator-i3-geo',
title: mw.format( messages.indicatorButtonTitle, pageTitle ),
class: 'mw-indicator', // cdx-button
href: '#'
} )
.css( { display: 'inline-block' } )
.append( indicatorImg )
.append( $( `<span>${messages.indicatorActionLabel}</span>` ) );
indicator = $( '<li>', {
id: 'page-actions-i3-geo',
class: 'page-actions-menu__list-item'
} )
.append( indicator )
.click( function() {
$( '#bodyContent' ).prepend( makeContainer( id ) );
createMap( id, center, zoom, mapTitle, options );
} );
$( minervaPageActionsSelector ).after( indicator );
} else { // desktop views
// replace indicator image and add an event handler
$( indicatorSelector + ' .voy-map-globe-default' )
.css( { display: 'none' } );
$( indicatorSelector + ' .voy-map-globe-js' )
.css( { display: 'inline', cursor: 'pointer' } )
.attr( 'title', mw.format( messages.indicatorButtonTitle, pageTitle ) )
.click( function() {
const container = $( '#' + id );
if ( container.length ) {
container.remove();
} else {
$( '#contentSub' ).after( makeContainer( id ) );
createMap( id, center, zoom, mapTitle, options );
}
} );
}
};
// returning show parameter string as an array
const getShow = ( s ) => {
return ( s ) ? JSON.parse( s ) : defaultShowArray;
};
// replace the Maplink links by MapTools to show Wikivoyage controls
const replaceMaplinks = () => {
const links = $( kartographerSelector );
if ( !links.length || multiPointUsed ) {
return;
}
const id = fullScreenContainerId,
options = {
withClose: true,
withControls: true,
withData: true,
show: defaultShowArray,
withDialog: true,
allowFullScreen: false,
isFullScreen: true,
featureType: 'maplink'
};
links.each( function() {
const $this = $( this );
$this.attr( 'href', '#' )
.css( { cursor: 'pointer', 'pointer-events': 'auto',
'text-decoration': 'none' } );
$this.click( function( event ) {
event.stopImmediatePropagation();
event.preventDefault();
// marker could contain an image -> closest
const target = $( event.target ).closest( kartographerSelector ),
wrapper = target.closest( markerSelector ),
lat = target.attr( dataLat ),
lon = target.attr( dataLon ),
center = [ lat, lon ],
zoom = getZoom( target.attr( dataZoom ), defaultMaplinkZoomLevel ),
bgColor = target.css( 'background-color' ),
textColor = target.css( 'color' );
let name = wrapper.attr( dataName ) || '',
symbolText = target.text();
if ( name === '' ) {
name = symbolText;
} else if ( name !== '' && symbolText !== '' ) {
name = symbolText + ': ' + name;
}
options.show = getShow( target.attr( dataOverlays ) );
$body.append( makeContainer( id ) );
createMap( id, center, zoom, name, options, bgColor, textColor );
return false; // don't follow the link
} );
} );
};
// adding a magnify button to Kartographer container
const addMagnifyButton = () => {
const maps = $( mapframeContainerSelector );
if ( !maps.length || multiPointUsed ) {
return;
}
const id = fullScreenContainerId,
options = {
withClose: true,
withControls: true,
withData: true,
show: defaultShowArray,
withDialog: true,
allowFullScreen: false,
isFullScreen: true,
featureType: 'maplink'
};
maps.each( function() {
const $this = $( this );
// no magnify button if zoom is already maxZoomLevel
// not in frameless mode
const map = $( mapframeMapSelector, $this ).first(),
caption = $( '.thumbcaption', $this ).first();
let zoom = getZoom( map.attr( dataZoom ) );
if ( map.length && caption.length && zoom < maxZoomLevel ) {
const link = $( '<a class="internal"></a>' )
.css( { cursor: 'pointer' } )
.attr( 'title', messages.magnifyButtonTitle )
.click( function( event ) {
const target = $( event.target );
let map = target.closest( mapframeContainerSelector );
const caption = $( '.thumbcaption', map ).first(),
name = caption.text();
// getting initial position from data if lat or lon
// or zoom are undefined
map = $( mapframeMapSelector, map ).first();
const center = [ map.attr( dataLat ), map.attr( dataLon ) ];
let zoom = Number( map.attr( dataZoom ) );
if ( isNaN( zoom ) ) {
zoom = undefined;
} else {
let zoomIncr = 1;
const height = screen.height / map.attr( dataHeight );
if ( height > 4 ) {
zoomIncr++;
}
if ( height > 8 ) {
zoomIncr++;
}
zoom += zoomIncr;
if ( zoom > maxZoomLevel ) {
zoom = maxZoomLevel;
}
}
options.show = getShow( map.attr( dataOverlays ) );
$body.append( makeContainer( id ) );
createMap( id, center, zoom, name, options );
} );
caption.prepend( $( '<div class="magnify"></div>' ).append( link ) );
}
} );
};
// adding all tools
// called by getKartographerLiveData()
const addMapTools = () => {
addMagnifyButton();
indicatorMap();
replaceMaplinks();
};
const init = () => {
setupMessages();
defaultShowArray = JSON.parse( messages.defaultShow );
getKartographerLiveData(); // calling addMapTools()
};
init();
} ( jQuery, mediaWiki ) );
//</nowiki>
788a1efr20uu1et60d34ymfjv4sepnj
MediaWiki:Gadget-MapTools.css
8
1464
22110
18329
2026-05-20T12:55:06Z
LiMr
96
aktualizace na novější verzi
22110
css
text/css
/*
Styles for MapTools gadget
Version: 2025-12-20
*/
/* Mobile-view page-actions menu: for MapTools and Poi2gpx */
.skin-minerva .content ul {
list-style: square outside;
padding-left: 1em;
}
.skin-minerva .content .tocUl, .skin-minerva .content .tocUl ul {
list-style: none;
}
.skin-minerva .mw-indicator {
margin: 0 !important;
padding: 0.5em 0.75em 0 !important;
height: 1.85em;
color: #54595d !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border: 1px solid transparent;
border-radius: 2px;
font-weight: 500 !important;
box-sizing: content-box !important;
text-decoration: none !important;
}
.skin-minerva .mw-indicator:focus {
border-color: #3366cc;
box-shadow: inset 0 0 0 1px #3366cc,inset 0 0 0 2px #ffffff;
outline: 0;
}
.skin-minerva .mw-indicator:active {
border-color: #72777d;
box-shadow: none;
background-color: rgba(0,36,73,0.08235294);
}
.skin-minerva .mw-indicator:hover {
background-color: rgba(0,0,0,0.03);
}
.skin-minerva .mw-indicator img {
vertical-align: text-bottom;
margin-right: 10px;
}
@media (max-width: 1119px) {
.skin-minerva .mw-indicator {
width: 1.25em;
color: transparent !important;
}
.skin-minerva .mw-indicator img {
margin-right: 0;
vertical-align: 0;
}
}
/* Map container */
#voy-topMap {
height: 400px;
border: 1px solid #c8ccd1;
margin: 0.7em 0 1em;
}
#voy-articles-map {
height: 600px;
border: 1px solid #c8ccd1;
}
@media (max-width: 1300px) { /* laptop and smartphone support */
#voy-articles-map {
height: 450px;
}
}
@media (max-width: 800px) {
#voy-articles-map {
height: 350px;
}
}
@media (max-width: 600px) {
#voy-articles-map {
height: 300px;
}
}
/* Caption marker */
.voy-caption-marker {
font-size: 80%;
font-weight: bold;
text-align: center;
display: inline-block;
min-width: 1em;
padding: 0 0.2em 0;
border-radius: 3px;
}
/* Close icon */
#voy-topMap .voy-icon-close, #voy-fullScreenMap .voy-icon-close, #voy-articles-map .voy-icon-close {
background-image: url(/w/load.php?modules=oojs-ui.styles.icons-interactions&image=close&format=rasterized&lang=de&skin=vector&version=12ligfd);
background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2220%22 height=%2220%22 viewBox=%220 0 20 20%22%3E%3Ctitle%3Eclose%3C/title%3E%3Cpath d=%22M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z%22/%3E%3Cpath d=%22M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z%22/%3E%3C/svg%3E");
background-position: center center;
}
/* Border of the map itself */
.mw-kartographer-container.thumb:not(.mw-kartographer-full) .thumbinner > .mw-kartographer-map {
border: 1px solid #ccc;
box-sizing: border-box;
}
/* Magnify symbol */
.mw-kartographer-container .magnify { /* magnify button of Minerva skin */
float: right;
margin-left: 3px;
margin-right: 0;
display: block !important;
}
.mw-kartographer-container div.magnify a {
background-image: url(/w/resources/src/mediawiki.skinning/images/magnify-clip-ltr.png?4f704);
background-image: linear-gradient(transparent,transparent),url("data:image/svg+xml,%3C%3Fxml version=%221.0%22 encoding=%22UTF-8%22 standalone=%22no%22%3F%3E%0A%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 11 15%22 width=%2215%22 height=%2211%22%3E%0A %3Cg id=%22magnify-clip%22 fill=%22%23fff%22 stroke=%22%23000%22%3E%0A %3Cpath id=%22bigbox%22 d=%22M1.509 1.865h10.99v7.919h-10.99z%22/%3E%0A %3Cpath id=%22smallbox%22 d=%22M-1.499 6.868h5.943v4.904h-5.943z%22/%3E%0A %3C/g%3E%0A%3C/svg%3E%0A") !important;
text-indent: 15px;
white-space: nowrap;
overflow: hidden;
width: 15px;
height: 11px;
text-decoration: none;
}
/* Kartographer-Popup */
.leaflet-popup-content {
width: 141px !important;
}
.leaflet-popup-content .marker-title {
font-weight: normal;
}
.leaflet-popup-content img {
display: block;
width: 100% !important;
height: auto !important;
}
.leaflet-container img {
border: none;
}
/* Layers control */
.mw-kartographer-interactive .leaflet-control-layers-expanded {
overflow-x: hidden;
overflow-y: auto;
width: 200px;
}
@media print {
.leaflet-bar, .leaflet-control {
display: none;
}
}
crqurvcvndjnben24cexif11k6sxbgg
MediaWiki:Gadget-MarkerTooltip.js
8
1465
22108
20852
2026-05-20T12:51:08Z
LiMr
96
aktualizace na novější verzi
22108
javascript
text/javascript
//<nowiki>
/********************************************************************/
// Přeneseno z https://de.wikivoyage.org/wiki/MediaWiki:Gadget-MarkerTooltip.js
/***************************************************************************
* MarkerTooltip.js v1.6, 2026-04-06
* Displays an extended marker tooltip on mouse over on desktops
* or on click on smartphones
* Displays tooltip for abbreviations on smartphones
* Original author: Roland Unger
* Support of both desktop and mobile views
* Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:Gadget-MarkerTooltip.js
* License: GPL-2.0+, CC-by-sa 3.0
***************************************************************************/
/* eslint-disable mediawiki/class-doc */
( function ( $ ) {
'use strict';
const version = "2026-04-06";
const strings = {
de: {
hint: 'Click auf den Marker öffnet die Karte direkt.',
hint2: 'Bitte nutzen Sie zur Anzeige die Kartendienste.',
ch1903: 'CH1903',
ch1903Title: 'Es folgt die Koordinate in der Form der Schweizer Landeskoordinaten.',
dec: 'Dezimal',
decTitle: 'Es folgt die Koordinate in Dezimalform. Über den nebenstehenden Geo-URI-Link kann eine Karten-Anwendung gestartet werden.',
geoUriTitle: 'Über diesen Link startet der Browser eine Karten-Anwendung, z. B. Google Maps. Auf vielen Smartphones bereits eingerichtet.',
hex: 'GMS',
hexTitle: 'Es folgt die Koordinate in der Form Grad-Minuten-Sekunden.',
plus: 'Plus Code',
plusTitle: 'Es folgt die Koordinate als Plus Code.',
anchor: 'Anker',
anchorTitle: 'Zeigt den Namen des Vorlagen-Ankers an.',
anchorText: 'Der Name des Vorlagen-Ankers lautet:\n\n',
clipboard: 'Ablage',
clipboardTitle:'Kopiert die nebenstehende Angabe in die Zwischenablage. Insbesondere ältere Browser unterstützten diese Funktion leider nicht.',
mapSources: 'Kartendienste',
mapSourcesTitle: 'Es folgen verschiedene Listen mit Kartenquellen und -diensten',
tools: 'Werkzeuge',
toolsTitle: 'Es folgen verschiedene Vorlagen-Werkzeuge',
voy: 'Wikivoyage',
voyTitle: 'Öffnet eine Wikivoyage-eigene Internetseite, die zahlreiche Kartenquellen und -dienste auflistet.',
voyURL: '/w/index.php?title=Special%3AMapsources',
wmflabs: 'WMF-Labs',
wmflabsTitle: 'Öffnet eine Internetseite von WMF Labs, die zahlreiche Kartenquellen und -dienste auflistet.',
wmflabsURL: 'https://tools.wmflabs.org/geohack/geohack.php',
EW: 'OW', // international: 'EW'
NS: 'NS'
},
en: {
hint: 'Clicking on the marker directly opens the map.',
hint2: 'Please use the map tools for display.',
ch1903: 'CH1903',
ch1903Title: 'Coordinates are shown in the form of the Swiss national coordinates.',
dec: 'Decimal',
decTitle: 'Coordinates are shown as decimal values. A map application can be started via the adjacent Geo-URI link.',
geoUriTitle: 'The browser starts a map application using this link, e. g. Google Maps. Already set up on many smartphones.',
hex: 'DMS',
hexTitle: 'Coordinates are shown as degree-minutes-seconds.',
plus: 'Plus Code',
plusTitle: 'Coordinates are shown as Plus Code.',
anchor: 'Anchor',
anchorTitle: 'Shows the name of the template anchor.',
anchorText: 'The name of the template anchor is:\n\n',
clipboard: 'Clipboard',
clipboardTitle:'Copies the adjacent information to the clipboard. Unfortunately, older browsers do not support this feature.',
mapSources: 'Map tools',
mapSourcesTitle: 'The following lists with map sources and services are available',
tools: 'Tools',
toolsTitle: 'The following tools are available',
voy: 'Wikivoyage',
voyTitle: 'Opens Wikivoyage’s own webpage which lists numerous map sources and services.',
voyURL: '/w/index.php?title=Special%3AMapsources',
wmflabs: 'WMF Labs',
wmflabsTitle: 'Opens a WMF Labs webpage which lists numerous map sources and services.',
wmflabsURL: 'https://tools.wmflabs.org/geohack/geohack.php',
EW: 'EW',
NS: 'NS'
},
es: {
hint: 'Haga clic aquí para abrir el mapa.',
hint2: 'Utilice los servicios de mapas para visualizar.',
ch1903: 'CH1903',
ch1903Title: 'A esto le sigue la coordenada en forma de coordenadas nacionales suizas.',
dec: 'Decimal',
decTitle: 'La coordenada sigue en forma decimal. Se puede iniciar una aplicación de mapas a través del enlace Geo-URI adyacente.',
geoUriTitle: 'El navegador inicia una aplicación de mapas a través de este enlace, p. ej. mapas de Google. Ya está configurado en muchos teléfonos inteligentes Android.',
hex: 'GMS',
hexTitle: 'La coordenada sigue en forma de grados-minutos-segundos.',
plus: 'Plus Code',
plusTitle: 'La coordenada sigue como un código de ubicación abierto.',
anchor: 'Ancla',
anchorTitle: 'Muestra el nombre del ancla de la plantilla.',
anchorText: 'El nombre del ancla de la plantilla es:\n\n',
clipboard: 'Portapapeles',
clipboardTitle:'Copia la información adyacente al portapapeles. Lamentablemente, los navegadores más antiguos no admiten esta función.',
mapSources: 'Instrumentos de mapas',
mapSourcesTitle: 'Las siguientes listas con fuentes y instrumentos de mapas están disponibles.',
tools: 'Instrumentos',
toolsTitle: 'Los siguientes instrumentos están disponibles.',
voy: 'Wikiviajes',
voyTitle: 'Abre un sitio web de Wikiviajes que enumera numerosas fuentes y instrumentos de mapas.',
voyURL: '/w/index.php?title=Special%3AMapsources',
wmflabs: 'WMF Labs',
wmflabsTitle: 'Abre un sitio web de WMF Labs que enumera numerosas fuentes y instrumentos de mapas.',
wmflabsURL: 'https://tools.wmflabs.org/geohack/geohack.php',
EW: 'EO', // international: 'EW'
NS: 'NS'
},
cs: {
hint: 'Kliknutím přímo na bod se otevře mapa.',
hint2: 'K zobrazení použijte mapové služby.',
ch1903: 'CH1903',
ch1903Title: 'Souřadnice jsou zobrazeny ve formátu švýcarských národních souřadnic.',
dec: 'Desetinný',
decTitle: 'Souřadnice jsou zobrazeny jako desetinné hodnoty. Mapová aplikace se spustí přes sousední Geo-URI odkaz.',
geoUriTitle: 'Prohlížeč spustí mapovou aplikaci pomocí tohoto odkazu, např. Google Maps. Na mnoha chytrých telefonech už je nastaveno.',
hex: 'DMS',
hexTitle: 'Souřadnice jsou zobrazeny jako stupně, minuty a sekundy.',
plus: 'Plus Code',
plusTitle: 'Souřadnice jsou zobrazeny jako Plus Code.',
anchor: 'Kotva',
anchorTitle: 'Zobrazuje název kotvy šablony.',
anchorText: 'Název kotvy šablony je:\n\n',
clipboard: 'Zkopírovat',
clipboardTitle:'Zkopíruje sousední údaj do schránky. Bohužel tuto možnost nepodporují starší prohlížeče.',
mapSources: 'Mapové nástroje',
mapSourcesTitle: 'K dispozici jsou následující seznamy s mapovými zdroji a službami',
tools: 'Nástroje',
toolsTitle: 'K dispozici jsou následující nástroje',
voy: 'Wikicesty',
voyTitle: 'Otevře webovou stránku Wikicest s mnoha mapovými zdroji a službami.',
voyURL: '/w/index.php?title=Special%3AMapsources',
wmflabs: 'WMF Labs',
wmflabsTitle: 'Otevře webovou stránku WMF Labs s mnoha mapovými zdroji a službami.',
wmflabsURL: 'https://tools.wmflabs.org/geohack/geohack.php',
EW: 'EW',
NS: 'NS'
}
};
const fallbackLang = 'en',
maxZoomLevel = 19; // see also getScaleFromZoom
const options = {
plusCode: false,
ch1903: true
};
const classes = {
copyMarker: 'voy-copy-marker',
idRegex: /vCard_.+/, // see [[Module:Marker_utilities/i18n]], texts.anchor
listingTooltip: 'voy-listing-tooltip',
listingTooltipMobile: 'voy-listing-tooltip-mobile',
withoutMarker: 'voy-without-marker'
};
const selectors = {
kartographerLink: '.mw-kartographer-maplink',
latitude: '.p-latitude',
longitude: '.p-longitude',
lCoordinates: '.voy-listing-coordinates',
lEditButton: '.voy-listing-edit-button button',
lInfoButton: '.voy-listing-info-button button',
lMap: '.voy-listing-map, .voy-listing-without-marker',
lName: '.voy-listing-name',
vcard: '.vcard'
};
const data = {
color: 'data-color',
id: 'data-tooltip-id',
lat: 'data-lat',
lon: 'data-lon',
mAttribute: 'data-copy-marker-attribute',
mContent: 'data-copy-marker-content',
name: 'data-name',
region: 'data-region',
zoom: 'data-zoom',
version: 'data-version'
};
// internal use
const pageLang = mw.config.get( 'wgPageContentLanguage' ),
userLang = mw.config.get( 'wgUserLanguage' ),
// isMobile = window.matchMedia( '(any-pointer: coarse)' ).matches && // has touch screen or similar
// !window.matchMedia( '(any-pointer: fine)' ).matches, // has mouse
isMobile = ( /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( navigator.userAgent.toLowerCase() ) ),
timeouts = [];
let messages = {};
const addMessages = ( str, chain ) => {
for ( let i = chain.length - 1; i >= 0; i-- ) {
if ( str.hasOwnProperty( chain[ i ] ) ) {
$.extend( messages, strings[ chain[ i ] ] );
}
}
};
const setupMessages = () => {
const chain = ( userLang == pageLang ) ? [ pageLang, fallbackLang ] :
[ userLang, pageLang, fallbackLang ];
addMessages( strings, chain );
};
// Only n digits
const round = ( coord, n ) => {
const m = Math.pow( 10, n );
return Math.round( coord * m ) / m;
};
// Converting decimal to DMS coordinates
const toDMS = ( dec, letters ) => {
const letter = letters.charAt( ( dec >= 0 ) ? 0 : 1 ),
angle = Math.abs( dec );
let deg = Math.floor( angle ),
min = ( angle - deg ) * 60,
sec = Math.round( ( min - Math.floor( min ) ) * 60 );
min = Math.floor( min );
if ( sec >= 60 ) {
sec -= 60;
min += 1;
}
if ( min >= 60 ) {
min -= 60;
deg += 1;
}
return `${deg}° ${min}′ ${sec}″ ${letter}`;
};
// Converting decimal to CH1903 coordinates
// see: https://de.wikipedia.org/wiki/Schweizer_Landeskoordinaten
const toCH1903 = ( lat, lon ) => {
const ch1903 = {
easting: 0,
northing: 0,
error: true
};
if ( lat < 45.5 || lat > 48 || lon < 5.0 || lon > 11 ) {
return ch1903;
}
const phi = ( lat * 3600 - 169028.66 ) / 10000,
phi2 = phi * phi,
lambda = ( lon * 3600 - 26782.5 ) / 10000,
lambda2 = lambda * lambda;
ch1903.northing = Math.round( 200147.07 + 308807.95 * phi + 3745.25 * lambda2 +
76.63 * phi2 - 194.56 * lambda2 * phi + 119.79 * phi2 * phi );
ch1903.easting = Math.round( 600072.37 + 211455.93 * lambda - 10938.51 * lambda * phi -
0.36 * lambda * phi2 - 44.54 * lambda2 * lambda );
ch1903.error = false;
return ch1903;
};
// Converting decimal to Open Location Code (Plus Code)
// see: https://en.wikipedia.org/wiki/Open_Location_Code
const toPlusCode = ( lat, lon ) => {
const codeChars = '23456789CFGHJMPQRVWX',
resolutions = [ 20.0, 1.0, 0.05, 0.0025, 0.000125 ];
let code = '';
let modLat = lat;
modLat = Math.max( -90, modLat );
modLat = Math.min( modLat, 90 - 0.000025 );
// 0.000025 = resolutions[ 4 ] / 5 [rows]
modLat += 90; // starting from 0
let modLon = lon;
while ( modLon < -180 ) {
modLon += 360;
}
while ( modLon >= 180 ) {
modLon -= 360;
}
modLon += 180; // starting from 0
// first 10 + 1 digits
for ( let i = 0; i < 5; i++ ) {
const res = resolutions[ i ];
let digit = Math.floor( modLat / res );
modLat -= digit * res;
code += codeChars.charAt( digit );
digit = Math.floor( modLon / res );
modLon -= digit * res;
code += codeChars.charAt( digit );
if ( i === 3 ) {
code += '+';
}
}
// last digit
const row = Math.floor( 5 * modLat / resolutions[ 4 ] ),
col = Math.floor( 4 * modLon / resolutions[ 4 ] );
code += codeChars.charAt( 4 * row + col );
return code;
};
const shortenCoordinate = ( coord ) => {
return Math.round( coord * 1E5 ) / 1E5; // only 5 decimals
};
// zoom level 19 -> 1:1000, 0 -> 500000000
const getScaleFromZoom = ( zoom ) => {
const scales = [ 1000, 2000, 4000, 8000, 15000, 35000, 70000, 150000, 250000,
500000, 1000000, 2000000, 4000000, 10000000, 15000000, 35000000, 70000000,
150000000, 250000000, 500000000 ];
if ( zoom >= maxZoomLevel ) {
return scales[ 0 ];
} else if ( zoom <= 0 ) {
return scales[ scales.length - 1 ];
}
return scales[ maxZoomLevel - Math.round( zoom ) ];
};
const copyToClipboard = ( selector, container ) => {
const clipboard = $( '<textarea id="mkClipboard"></textarea>' )
.css( { 'width': 1, 'border': 'none', 'opacity': 0 } );
$( 'body' ).append( clipboard );
const text = ( selector !== '.mkClip5' ) ? $( selector, container ).text()
: $( '#anchorId', container ).text();
clipboard.val( text ).select();
document.execCommand( 'copy' );
clipboard.remove();
};
const clipboardLink = ( aClass ) => {
return aClass ?
`[ <a href="javascript:" class="${aClass}" title="${messages.clipboardTitle}">${messages.clipboard}</a> ]` : '';
};
const makeTableRow = ( label, title, clipClass, buttonClass, text ) => {
return `<tr><td><span title="${title}">${label}:</span> <span class="${clipClass}">${text}</span></td><td>${clipboardLink( buttonClass )}</td></tr>`;
};
const makeContent = ( $origin ) => {
let link = $( selectors.kartographerLink, $origin ).first(),
lat, lon, withMarker, zoom;
if ( link.length ) {
lat = round( link.attr( data.lat ), 6 );
lon = round( link.attr( data.lon ), 6 );
zoom = link.attr( data.zoom );
withMarker = true;
} else {
link = $origin.closest( selectors.vcard ).find( selectors.lCoordinates );
lat = round( $( selectors.latitude, link ).text(), 6 );
lon = round( $( selectors.longitude, link ).text(), 6 );
zoom = 16;
withMarker = false;
}
const latStr = toDMS( lat, messages.NS ),
lonStr = toDMS( lon, messages.EW );
const wrapper = $origin.closest( selectors.vcard ),
color = wrapper.attr( data.color ),
region = wrapper.attr( data.region ) || '';
let name = wrapper.attr( data.name );
if ( !name ) {
name = $( selectors.lName, wrapper ).first();
const wikiLink = $( 'a', name ).first();
name = ( wikiLink.length ) ? wikiLink.text() : name = name.text();
}
name = encodeURI( name.replace( /\s/g, '+' ) ).replace( /&/g, '%26' );
let params = '¶ms=' +
Math.abs( lat ) + ( lat < 0 ? '_S_' : '_N_' ) +
Math.abs( lon ) + ( lon < 0 ? '_W' : '_E' ) +
`_scale%3A${getScaleFromZoom( zoom )}_type%3Alandmark_globe%3Aearth`;
if ( region !== '' ) {
params += '_region%3A' + region;
}
const ch1903 = toCH1903( lat, lon ),
plusCode = toPlusCode( lat, lon ),
latDec = shortenCoordinate( lat ),
lonDec = shortenCoordinate( lon );
let table = '<table>' +
makeTableRow( messages.hex, messages.hexTitle, 'mkClip1', 'mkButton1',
latStr + ' ' + lonStr ) +
makeTableRow( messages.dec, messages.decTitle, 'mkClip2', 'mkButton2',
`<a href="geo:${latDec},${lonDec}" title="${messages.geoUriTitle}">${latDec}, ${lonDec}</a>` );
if ( options.plusCode ) {
table += makeTableRow( messages.plus, messages.plusTitle, 'mkClip3', 'mkButton3',
`<span class="voy-mkTooltipPlusCode">${plusCode.substr( 0, 4 ) }</span>` +
plusCode.substr( 4 ) );
}
if ( options.ch1903 && !ch1903.error ) {
table += makeTableRow( messages.ch1903, messages.ch1903Title,
'mkClip4', 'mkButton4',
`<span title="CH1903 easting">${ch1903.easting}</span> / <span title="CH1903 northing">${ch1903.northing}</span>` );
}
const html = [],
infobutton = $( selectors.lInfoButton, wrapper ).prop( 'outerHTML' ) || '';
if ( infobutton !== '' ) {
html.push( `<span id="infobutton">${infobutton}</span>` );
}
const editbutton = $( selectors.lEditButton, wrapper ).prop( 'outerHTML' ) || '';
if ( editbutton !== '' ) {
html.push( `<span id="editbutton">${editbutton}</span>` );
}
let id = wrapper.attr( 'id' );
id = id && id.match( classes.idRegex );
if ( id ) {
const anchor = `<a href="#" id="anchorIdLink" title="${messages.anchorTitle}">${messages.anchor}</a>` +
`<span id="anchorId" style="display: none">${id}</span>`;
html.push( anchor );
}
if ( html.length ) {
table += makeTableRow( messages.tools, messages.toolsTitle, 'mkClip5',
id ? 'mkButton5' : null, html.join( ' | ' ) );
}
table += '</table>';
const mapSources = `<div title="${messages.mapSourcesTitle}">${messages.mapSources}: ` +
`<a href="${messages.voyURL + params}&locname=${name}" title="${messages.voyTitle}" target="_blank" rel="noopener">${messages.voy}</a> | ` +
`<a href="${messages.wmflabsURL}?pagename=${name}&language=${pageLang + params}" title="${messages.wmflabsTitle}" target="_blank" rel="noopener">${messages.wmflabs}</a>` +
'</div>';
return $( '<div class="voy-mkTooltipInner"></div>' )
.css( 'border-left-color', color )
.append( $( '<div class="voy-mkTooltipHint">' + (withMarker ? messages.hint : messages.hint2 ) + '</div>' )
.css( { 'margin-bottom': '0.5em' } ) )
.append( $( table ) )
.append( $( mapSources ) )
.append( $( '<div class="voy-mkTooltipTail"></div>' ) );
};
// setting tooltip position
const setTooltipPosition = ( e, tooltip, $this ) => {
const tail = $( '.voy-mkTooltipTail', tooltip ),
winWidth = $( window ).width();
let left, offset, right, width;
if ( e.clientY < $( window ).height() / 2 ) {
tooltip.css( 'top', $this.innerHeight() - 4 )
.addClass('voy-mkBelow');
} else {
tooltip.css( 'bottom', $this.innerHeight() - 4 )
.addClass('voy-mkAbove');
}
if ( e.clientX < winWidth / 2 ) {
tooltip.css( 'left', $this.innerWidth() / 2 - 16 )
.addClass('voy-mkLeft');
if ( isMobile ) {
offset = tooltip.offset();
right = offset.left + tooltip.outerWidth();
if ( right > winWidth - 1 ) {
left = offset.left - ( right - winWidth ) - 2;
if ( left < 2 ) {
left = 2;
}
width = tooltip.innerWidth();
tooltip.offset( { top: offset.top, left: left } );
tooltip.innerWidth( width );
width = offset.left - left;
offset = tail.offset();
offset.left += width;
tail.offset( offset );
}
}
} else {
tooltip.css( 'right', $this.innerWidth() / 2 - 13 )
.addClass('voy-mkRight');
if ( isMobile ) {
offset = tooltip.offset();
left = offset.left;
if ( left < 2 ) {
width = tooltip.innerWidth();
tooltip.offset( { top: offset.top, left: 2 } );
tooltip.innerWidth( width );
offset = tail.offset();
offset.left += left;
tail.offset( offset );
}
}
}
};
const showMarkerTooltip = ( e ) => {
const $this = $( e.target ).closest( '.' + classes.listingTooltip ),
id = $this.attr( data.id ),
isCopyMarker = $this.hasClass( classes.copyMarker ),
wrapper = $this.closest( selectors.vcard ),
withoutMarker = wrapper.hasClass( classes.withoutMarker ),
triggerWrapper = withoutMarker || !isCopyMarker;
let $origin = $this;
e.stopPropagation();
if ( isCopyMarker ) {
// getting from original marker
const attr = $this.attr( data.mAttribute ),
content = $this.attr( data.mContent );
$origin = $( `*[${attr}="${content}"]` ).first();
}
const tooltip = $( `<div class="voy-mkTooltip" role="tooltip" ${data.version}="${version}"/>` )
.append( makeContent( $origin ) );
if ( isMobile ) {
tooltip.addClass( 'voy-mkTooltipMobile' );
} else {
tooltip.hide(); // later fade-in;
}
$this.append( tooltip );
setTooltipPosition( e, tooltip, $this );
$( '.mkButton1', tooltip )
.click( function() { copyToClipboard( '.mkClip1', tooltip ); } );
$( '.mkButton2', tooltip )
.click( function() { copyToClipboard( '.mkClip2', tooltip ); } );
$( '.mkButton3', tooltip )
.click( function() { copyToClipboard( '.mkClip3', tooltip ); } );
$( '.mkButton4', tooltip )
.click( function() { copyToClipboard( '.mkClip4', tooltip ); } );
$( '.mkButton5', tooltip )
.click( function() { copyToClipboard( '.mkClip5', tooltip ); } );
$( '#anchorIdLink', tooltip )
.click( function() {
const alertText = messages.anchorText + $( '#anchorId', tooltip ).text();
removeAllTooltips();
alert( alertText );
} );
$( '#infobutton', tooltip )
.click( function( e ) {
e.stopImmediatePropagation();
$( selectors.lInfoButton, triggerWrapper ? wrapper : $origin ).trigger( 'click' );
removeAllTooltips();
} );
$( '#editbutton', tooltip )
.click( function( e ) {
e.stopImmediatePropagation();
$( selectors.lEditButton, triggerWrapper ? wrapper : $origin ).trigger( 'click' );
removeAllTooltips();
} );
if ( isMobile ) {
// removing tooltip after 10 sec in mobile mode
timeouts[ id ] =
setTimeout( function() { removeTooltip( $this ); }, 10000 );
$( 'body' ).click( handleOutsideClick );
} else {
// fading-in hidden tooltip in desktop mode
setTimeout( function() { tooltip.fadeIn( 500 ); }, 300 );
}
return;
};
// Click event handler if clicked outside any tooltip
const handleOutsideClick = ( event ) => {
if ( !$( event.target ).closest( '.voy-mkTooltip' ).length &&
$( '.voy-mkTooltip' ).is( ':visible' ) ) {
removeAllTooltips();
}
};
const removeTooltip = ( marker ) => {
const id = marker.attr( data.id );
if ( id ) {
clearTimeout( timeouts[ id ] );
}
$( '.voy-mkTooltip', marker ).remove();
$( '.voy-mkTooltipButton', marker ).text( '▼' );
};
const removeAllTooltips = () => {
if ( isMobile ) {
$( 'body' ).off( 'click', handleOutsideClick );
}
const markers = $( '.' + classes.listingTooltip ).add( $( 'abbr' ) );
markers.each( function() {
removeTooltip( $( this ) );
});
};
const showMobileMarker = ( e ) => {
const $this = $( e.target ).closest( '.voy-mkTooltipButton' ),
text = $this.text();
removeAllTooltips();
if ( text === '▼' ) {
$this.text( '▲' );
showMarkerTooltip( e );
}
};
const initMarkerTooltip = () => {
$( selectors.lMap ).addClass( classes.listingTooltip )
.css( { position: 'relative' } );
if ( isMobile ) {
$( selectors.lMap ).addClass( classes.listingTooltipMobile );
}
const markers = $( '.' + classes.listingTooltip )
.removeAttr( 'title' );
let id = 0;
// setting id for timeout handler
markers.each( function() {
$( this ).attr( data.id, 'tt' + id );
id += 1;
} );
if ( isMobile ) {
const mobileMarker = $( '<span class="voy-mkTooltipButton">▼</span>' )
.click( function( e ) {
showMobileMarker( e );
});
markers.append( mobileMarker );
} else {
markers.mouseenter( function( e ) {
showMarkerTooltip( e );
})
.mouseleave( function( e ) {
$( '.voy-mkTooltip' ).remove();
});
}
};
const initAbbrTooltip = () => {
const abbr = $( 'abbr' )
.css( { 'position': 'relative', 'cursor': 'pointer' } );
let id = 0;
// setting id for timeout handler
abbr.each( function() {
$( this ).attr( data.id, 'at' + id );
id += 1;
} );
abbr.click( function( e ) {
e.stopPropagation();
const $this = $( e.target ).closest( 'abbr' ),
id = $this.attr( data.id );
let tooltip = $( '.voy-mkTooltip', $this );
removeAllTooltips();
if ( tooltip.length === 0 ) {
const title = $this.attr( 'title' );
if ( title ) {
const div = $( `<div class="voy-mkTooltipInner voy-mkTooltipMaxWidth">${title}</div>` )
.append( $( '<div class="voy-mkTooltipTail"></div>' ) );
tooltip = $( '<div class="voy-mkTooltip voy-mkTooltipMobile" role="tooltip"></div>' )
.append( div );
$this.append( tooltip );
setTooltipPosition( e, tooltip, $this );
timeouts[ id ] =
setTimeout( function() { removeTooltip( $this ); }, 10000 );
$( 'body' ).click( handleOutsideClick );
}
}
} );
};
const init = () => {
setupMessages();
initMarkerTooltip();
if ( isMobile ) {
$( 'body' ).addClass( 'voy-is-mobile' );
initAbbrTooltip();
}
};
init();
} ( jQuery ) );
//</nowiki>
fzpnc6t4guqhb6b8rx8z28smqorq7qe
MediaWiki:Gadget-MarkerTooltip.css
8
1466
22109
18335
2026-05-20T12:53:07Z
LiMr
96
aktualizace na novější verzi
22109
css
text/css
/*
Marker tooltip styles
Version: 2026-04-23
*/
/*
Styles for tooltip box
*/
.voy-mkTooltip {
position: absolute;
background-color: transparent;
color: var(--color-base,#202122);
font-weight: normal;
font-size: 90%;
font-style: normal;
line-height: 1.25em;
text-align: left;
z-index: 10; /* markers: z-index: 2; wikiEditor-ui-toolbar: z-index: 7 */
cursor: auto;
}
.voy-mkTooltipMobile {
line-height: 1.5em;
}
.voy-mkTooltipInner {
position: relative;
background-color: #ffffe3;
border: 1px solid #808080;
border-left-width: 4px;
border-radius: 3px;
box-shadow: 0 0 2px 1px rgba(0,0,0,0.5);
padding: 2px 4px;
}
.voy-mkTooltipInner div, .voy-mkTooltipInner table {
white-space: nowrap;
}
.voy-mkTooltipInner table {
width: 100% !important; /* !important for Minerva Skin */
display: table !important;
margin: 0 !important;
border-collapse: collapse;
border-spacing: 0;
border-style: none;
}
.voy-mkTooltipInner table td {
padding: 0;
text-align: left;
border-style: none;
}
.voy-mkTooltipInner table td:last-child {
padding-left: 2em;
text-align: right;
font-size: 80%;
}
.voy-mkTooltipMaxWidth {
max-width: 12.5em;
width: -moz-max-content;
width: -webkit-max-content;
width: max-content;
}
/*
Edit and info buttons
*/
.voy-mkTooltipInner button {
border: none;
background-color: transparent;
font-family: sans-serif;
font-size: 1em;
cursor: pointer;
padding: 0;
color: var(--color-progressive,#36c);
}
.voy-mkTooltipInner button:hover, .voy-mkTooltipInner button:focus,
.voy-mkTooltipInner button:active {
text-decoration: underline;
color: var(--color-progressive--hover,#3056a9);
}
.voy-mkTooltipInner #editbutton button:before, .voy-mkTooltipInner #infobutton button:before {
content: " ";
display: block;
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 15px;
background-repeat: no-repeat;
background-position: 0 25%;
background-size: 12px;
filter: opacity(0.45);
}
.voy-mkTooltipInner #editbutton button {
position: relative;
padding-left: 15px;
}
.voy-mkTooltipInner #editbutton button:before {
background-image: url( "//upload.wikimedia.org/wikipedia/commons/thumb/8/8a/OOjs_UI_icon_edit-ltr.svg/120px-OOjs_UI_icon_edit-ltr.svg.png" );
}
.voy-mkTooltipInner #infobutton button {
position: relative;
padding-left: 12px;
}
.voy-mkTooltipInner #infobutton button:before {
left: -2px;
top: -1px;
background-image: url( "//upload.wikimedia.org/wikipedia/commons/thumb/0/02/Maki-information-15.svg/120px-Maki-information-15.svg.png" );
background-size: 14px;
}
@media screen {
html.skin-theme-clientpref-night .voy-mkTooltipInner #editbutton button:before,
html.skin-theme-clientpref-night .voy-mkTooltipInner #infobutton button:before {
filter: invert(0.5);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .voy-mkTooltipInner #editbutton button:before,
html.skin-theme-clientpref-os .voy-mkTooltipInner #infobutton button:before {
filter: invert(0.5);
}
}
/*
Plus code and other text styles
*/
.voy-mkTooltipHint {
font-weight: bold;
}
.voy-mkTooltipPlusCode {
color: #808080;
}
/*
Styles for tooltip tail
*/
.voy-mkTooltipTail {
background-color: transparent;
width: 14px;
height: 10px;
position: absolute;
overflow: hidden;
}
.voy-mkTooltipTail:before {
background-color: #ffffe3; /* same colors as .voy-mkTooltipInner */
border: 1px solid #808080;
box-shadow: 0 0 2px 1px rgba(0,0,0,0.5);
box-sizing: border-box;
position: absolute;
content:"";
width: 10px;
height: 10px;
top: 0;
left: 0;
}
@media screen {
html.skin-theme-clientpref-night .voy-mkTooltipInner,
html.skin-theme-clientpref-night .voy-mkTooltipTail:before {
background-color: #333;
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .voy-mkTooltipInner,
html.skin-theme-clientpref-os .voy-mkTooltipTail:before {
background-color: #333;
}
}
/*
Position-dependent styles for tooltip box
*/
.voy-mkBelow {
padding-top: 15px;
}
.voy-mkAbove {
padding-bottom: 15px;
}
.voy-mkLeft .voy-mkTooltipTail {
left: 5px;
}
.voy-mkRight .voy-mkTooltipTail {
right: 5px;
}
.voy-mkAbove .voy-mkTooltipTail {
bottom: -10px;
}
.voy-mkAbove .voy-mkTooltipTail:before {
transform-origin: 0 0;
transform: rotate(-45deg);
}
.voy-mkBelow .voy-mkTooltipTail {
top: -10px;
}
.voy-mkBelow .voy-mkTooltipTail:before {
transform-origin: 0 100%;
transform: rotate(45deg);
}
/*
Marker arrow extension for mobile devices
*/
.voy-mkTooltipButton {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
padding: 0 0.15em;
background-color: #fff;
color: #000;
cursor: pointer;
font-size: 90%;
}
@media print {
.voy-mkTooltipButton {
display: none;
}
}
/*
Show complete tooltip if positioned an image container
*/
div.thumbinner.with-vCard, div.thumbinner.with-Marker {
overflow: visible;
}
m3idscl4ry0bu5a3gwzyzvsdqehrfz4