Änderungen von Dokument Home
Zuletzt geändert von Steffen Rehfuß am 14.08.2026 18:48
Von Version 1.1
bearbeitet von Steffen Rehfuß
am 14.08.2026 18:21
am 14.08.2026 18:21
Änderungskommentar:
Copied from xwiki:Main.WebHome
Auf Version 4.1
bearbeitet von Steffen Rehfuß
am 14.08.2026 18:47
am 14.08.2026 18:47
Änderungskommentar:
Es gibt keinen Kommentar für diese Version
Zusammenfassung
-
Seiteneigenschaften (1 geändert, 0 hinzugefügt, 0 gelöscht)
Details
- Seiteneigenschaften
-
- Inhalt
-
... ... @@ -4,25 +4,26 @@ 4 4 ## Einfach in den Seiten-Editor (Quelltext/Wiki) einfuegen. 5 5 ## ===================================================================== 6 6 ## 7 -## ---- KONFIG 1: Blog-Space + Hero-Kategorie ---- 7 +## ---- KONFIG 1: Blog-Space + Hero-Kategorie + Laufschrift-Kategorie ---- 8 8 #set ($blogSpace = 'Blog') ## technischer Space-Name des Blogs 9 9 #set ($heroCategory = 'TOP') ## Kategorie, die gross dargestellt wird 10 +#set ($breakingCategory = 'Breaking News') ## Kategorie fuer die Laufschrift oben 10 10 ## 11 11 ## ---- KONFIG 2: Die 12 App-Buttons (Text / Icon / Link / Farbe) ---- 12 12 ## icon = Font-Awesome-Name (ohne "fa-"). Farbe = beliebiger Hex-Wert. 13 13 #set ($apps = [ 14 - {'label':' Wissensmanagement', 'icon':'book', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Wissensmanagement', 'color':'#c30759', 'fg':'#ffffff'},15 - {'label':'MyPage', 'icon':'key', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/MyPage/', 'color':'#c30759', 'fg':'#ffffff'},16 - {'label':'Blog', 'icon':' bell','url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Blog/', 'color':'#c30759', 'fg':'#ffffff'},17 - {'label':'Chatbot', 'icon':'pencil-square-o', 'url':"javascript:document.getElementById('toggle-chat-button').click();void(0);",'color':'#385c6b', 'fg':'#ffffff'},18 - {'label':'Forum', 'icon':'group', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Forums/', 'color':'#385c6b', 'fg':'#ffffff'},19 - {'label':'Umfragen', 'icon':'question', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/XPoll/', 'color':'#385c6b', 'fg':'#ffffff'},20 - {'label':'Gruppenräume', 'icon':'life-ring', ' url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Rooms/', 'color':'#4d0f26', 'fg':'#ffffff'},21 - {'label':' Onboarding','icon':'graduation-cap', 'url':'', 'color':'#4d0f26', 'fg':'#ffffff'},22 - {'label':' MeineFavoriten', 'icon':'star', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Internes/Favoriten/', 'color':'#4d0f26', 'fg':'#ffffff'},23 - {'label':'Orga nigramm', 'icon':'sitemap', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Internes/Organigramm', 'color':'#73dddd', 'fg':'#4d0f26'},24 - {'label':'Tag Filter', 'icon':'filter', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/KBC%20Anwendungen/Tag%20Filter/', 'color':'#73dddd', 'fg':'#4d0f26'},25 - {'label':'Kantine', 'icon':'coffee', 'url':'https://xwiki.unternehmens-wiki.de/wiki/kbv/view/Internes/Kantine/Speiseplan%20vom%2013.07.2026%20-%2017.07.2026','color':'#73dddd', 'fg':'#4d0f26'}15 + {'label':'Haupt-Wiki', 'icon':'search', 'ref':'Main.WebHome', 'color':'#16a085'}, 16 + {'label':'MyPage', 'icon':'key', 'ref':'MyPage.WebHome', 'color':'#2980b9'}, 17 + {'label':'Blog', 'icon':'star', 'ref':'Blog.WebHome', 'color':'#8e44ad'}, 18 + {'label':'Chatbot', 'icon':'pencil-square-o', 'url':"javascript:document.getElementById('toggle-chat-button').click();void(0);", 'color':'#16a085'}, 19 + {'label':'Forum', 'icon':'group', 'ref':'Forums.WebHome', 'color':'#2980b9'}, 20 + {'label':'Umfragen', 'icon':'question', 'ref':'XPoll.WebHome', 'color':'#8e44ad'}, 21 + {'label':'Gruppenräume', 'icon':'life-ring', 'ref':'Rooms.WebHome', 'color':'#16a085'}, 22 + {'label':'Meine Favoriten', 'icon':'star', 'ref':'Internes.Favoriten.WebHome', 'color':'#2980b9'}, 23 + {'label':'Kalender', 'icon':'clock-o', 'ref':'MoccaCalendar.WebHome', 'color':'#8e44ad'}, 24 + {'label':'Org-Chart', 'icon':'sitemap', 'ref':'Internes.Organigramm.WebHome', 'color':'#2c3e50'}, 25 + {'label':'Tag Filter', 'icon':'filter', 'ref':'KBC Anwendungen.Tag Filter.WebHome', 'color':'#2c3e50'}, 26 + {'label':'Kantine', 'icon':'coffee', 'ref':'Internes.Kantine.Speiseplan vom 13\.07\.2026 - 17\.07\.2026.WebHome', 'color':'#2c3e50'} 26 26 ]) 27 27 ## 28 28 ## ---- Posts laden (neueste zuerst) ---- ... ... @@ -37,14 +37,17 @@ 37 37 #end 38 38 #set ($postNames = $q.execute()) 39 39 ## 40 -## ---- Hero (erster TOP-Post) + bis zu 4 Kachel-Posts bestimmen ---- 41 +## ---- Hero (erster TOP-Post) + bis zu 4 Kachel-Posts + neuester Breaking-News-Post bestimmen ---- 41 41 #set ($heroDoc = $NULL) 42 42 #set ($heroObj = $NULL) 43 43 #set ($tilePosts = []) 45 +#set ($breakingDoc = $NULL) 46 +#set ($breakingObj = $NULL) 44 44 #foreach ($pn in $postNames) 45 45 #set ($pd = $xwiki.getDocument($pn)) 46 46 #set ($po = $pd.getObject('Blog.BlogPostClass')) 47 47 #set ($isTop = false) 51 + #set ($isBreaking = false) 48 48 #set ($cats = $po.getValue('category')) 49 49 #if ($cats) 50 50 #foreach ($c in $cats) ... ... @@ -53,8 +53,15 @@ 53 53 #if ($cn == $heroCategory) 54 54 #set ($isTop = true) 55 55 #end 60 + #if ($cn == $breakingCategory) 61 + #set ($isBreaking = true) 62 + #end 56 56 #end 57 57 #end 65 + #if ($isBreaking && !$breakingDoc) 66 + #set ($breakingDoc = $pd) 67 + #set ($breakingObj = $po) 68 + #end 58 58 #if ($isTop && !$heroDoc) 59 59 #set ($heroDoc = $pd) 60 60 #set ($heroObj = $po) ... ... @@ -87,6 +87,14 @@ 87 87 #set ($heroDate = $heroObj.getValue('publishDate')) 88 88 #end 89 89 ## 101 +## ---- Laufschrift-Daten aufbereiten ---- 102 +#if ($breakingDoc) 103 + #set ($breakingTitle = $breakingDoc.getPlainTitle()) 104 + #set ($breakingText = "$!breakingObj.getValue('extract')") 105 + #set ($breakingURL = $breakingDoc.getURL('view')) 106 + #set ($breakingDate = $breakingObj.getValue('publishDate')) 107 +#end 108 +## 90 90 {{html clean="false" wiki="false"}} 91 91 <style> 92 92 ## Seitenkopf (Titel + "Zuletzt geaendert" + Aktionsmenue) auf DIESER Seite ausblenden ... ... @@ -102,6 +102,34 @@ 102 102 ## Fusszeile: Tags + "Gefaellt mir" + "Erstellt von / uebersetzt von" ausblenden 103 103 #xdocTags, .doc-tags, .like-container, .xdocCreation { display: none !important; } 104 104 .intra-wrap { width: 90%; max-width: 90%; margin: 0 auto; } 124 +.intra-ticker { 125 + display: flex; align-items: stretch; height: 38px; 126 + background: #c0392b; margin-bottom: 20px; overflow: hidden; border-radius: 8px; 127 +} 128 +.intra-ticker-label { 129 + flex: 0 0 auto; display: flex; align-items: center; 130 + background: #922b21; color: #fff !important; text-decoration: none; 131 + font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; 132 + padding: 0 18px; white-space: nowrap; 133 +} 134 +.intra-ticker-viewport { flex: 1 1 auto; position: relative; overflow: hidden; } 135 +.intra-ticker-date { 136 + flex: 0 0 auto; display: flex; align-items: center; 137 + color: #ffd7d0 !important; font-size: 13px; font-weight: 700; 138 + padding: 0 6px 0 18px; white-space: nowrap; 139 +} 140 +.intra-ticker-track { 141 + position: absolute; top: 0; left: 100%; height: 100%; 142 + display: flex; align-items: center; white-space: nowrap; 143 + color: #fff !important; text-decoration: none; font-size: 14px; font-weight: 600; 144 + padding: 0 18px; 145 + animation: intra-ticker-scroll 22s linear infinite; 146 +} 147 +.intra-ticker-track:hover { animation-play-state: paused; text-decoration: underline; } 148 +@keyframes intra-ticker-scroll { 149 + from { left: 100%; } 150 + to { left: -100%; } 151 +} 105 105 .intra-cols { display: flex; gap: 20px; align-items: stretch; } 106 106 .intra-main { flex: 2 1 0; min-width: 0; } 107 107 .intra-side { flex: 1 1 0; display: flex; flex-direction: column; gap: 16px; } ... ... @@ -109,7 +109,13 @@ 109 109 position: relative; width: 100%; min-height: 360px; border-radius: 14px; 110 110 overflow: hidden; background: #223; background-size: cover; background-position: center; 111 111 box-shadow: 0 6px 18px rgba(0,0,0,.15); text-decoration: none; display: block; 159 + transition: transform .15s ease, box-shadow .15s ease; 112 112 } 161 +.intra-hero:hover { 162 + transform: translateY(-3px); 163 + box-shadow: 0 12px 28px rgba(0,0,0,.22); 164 +} 165 +.intra-hero:hover .intra-btn { filter: brightness(1.08); } 113 113 .intra-hero::after { 114 114 content: ""; position: absolute; inset: 0; 115 115 background: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,.75) 100%); ... ... @@ -127,32 +127,12 @@ 127 127 } 128 128 .intra-btn:hover { filter: brightness(1.08); } 129 129 .intra-apps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } 130 - 131 131 .intra-app { 132 - display: flex; 133 - flex-direction: column; 134 - justify-content: space-between; 135 - border-radius: 10px; 136 - padding: 12px 12px 10px; 137 - min-height: 84px; 138 - color: #fff !important; 139 - text-decoration: none; 140 - transition: transform .15s ease, 141 - box-shadow .15s ease, 142 - filter .15s ease; 184 + display: flex; flex-direction: column; justify-content: space-between; 185 + border-radius: 10px; padding: 12px 12px 10px; min-height: 84px; color: #fff !important; 186 + text-decoration: none; transition: transform .15s ease, box-shadow .15s ease; 143 143 } 144 - 145 -.intra-app:hover { 146 - transform: translateY(-2px); 147 - filter: brightness(.90); /* ca. 8 % dunkler */ 148 - box-shadow: 0 6px 14px rgba(0,0,0,.18); 149 -} 150 - 151 -.intra-app:active { 152 - filter: brightness(.86); 153 -} 154 - 155 - 188 +.intra-app:hover { transform: translateY(-2px); box-shadow: 0 6px 14px rgba(0,0,0,.18); } 156 156 .intra-app-ic { font-size: 22px; line-height: 1; } 157 157 .intra-app-ic .fa { color: #fff; } 158 158 .intra-app-lbl { font-size: 13px; font-weight: 600; margin-top: 8px; } ... ... @@ -164,6 +164,8 @@ 164 164 } 165 165 .intra-widget { background: #fff; border: 0.5px solid #e2e6ea; border-radius: 12px; padding: 16px 18px; box-shadow: 0 3px 12px rgba(0,0,0,.06); margin-top: 35px; } 166 166 .intra-widget-h { font-size: 14px; font-weight: 700; color: #16324f; margin-bottom: 10px; } 200 +.intra-cal-link { color: #16324f; text-decoration: none; transition: color .15s ease; } 201 +.intra-cal-link:hover { color: #2c6fbb; } 167 167 .intra-tagcloud { line-height: 2; } 168 168 .intra-tag { display: inline-block; margin: 0 9px 4px 0; color: #2c6fbb; text-decoration: none; } 169 169 .intra-tag:hover { text-decoration: underline; } ... ... @@ -173,6 +173,7 @@ 173 173 .intra-cal-item:hover .intra-cal-title { text-decoration: underline; } 174 174 .intra-cal-date { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: #2c6fbb; min-width: 52px; letter-spacing: .02em; } 175 175 .intra-cal-title { font-size: 13px; color: #16324f; } 211 +.intra-cal-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; align-self: center; box-shadow: 0 0 0 1px rgba(0,0,0,.06) inset; } 176 176 .intra-cal-empty { color: #8a97a6; font-size: 13px; } 177 177 .intra-tile { 178 178 display: flex; background: #fff; border-radius: 12px; overflow: hidden; ... ... @@ -199,7 +199,7 @@ 199 199 position: relative; 200 200 transform-style: preserve-3d; 201 201 transition: transform .6s cubic-bezier(.2,.7,.2,1); 202 - transition-delay: 0s;/*RichtungserkennungimJS verhindertFehl-Flips*/238 + transition-delay: .12s; /* kein Flip beim blossen Vorbeiziehen */ 203 203 } 204 204 .intra-flip.is-back .intra-flip-inner { transform: rotateY(180deg); } 205 205 ... ... @@ -226,6 +226,18 @@ 226 226 </style> 227 227 228 228 <div class="intra-wrap"> 265 + 266 + ## ----- LAUFSCHRIFT: neuester Post mit Kategorie "Breaking News" ----- 267 + #if ($breakingDoc) 268 + <div class="intra-ticker"> 269 + <a class="intra-ticker-label" href="$breakingURL">$escapetool.xml($breakingCategory)</a> 270 + #if ($breakingDate)<span class="intra-ticker-date">$datetool.format('dd.MM.yyyy', $breakingDate)</span>#end 271 + <div class="intra-ticker-viewport"> 272 + <a class="intra-ticker-track" href="$breakingURL">$escapetool.xml($breakingTitle)#if($breakingText != '') — $escapetool.xml($breakingText)#end</a> 273 + </div> 274 + </div> 275 + #end 276 + 229 229 <div class="intra-cols"> 230 230 231 231 ## ===== LINKE SPALTE: Hero + 4 Blog-Kacheln ===== ... ... @@ -284,11 +284,17 @@ 284 284 ## ----- 12 APP-BUTTONS ----- 285 285 <div class="intra-apps"> 286 286 #foreach ($app in $apps) 287 - <a class="intra-app" style="background: $app.color;" href="#if($app.url != '')$app.url#else#end"> 288 - <span class="intra-app-ic"><span class="fa fa-$app.icon" aria-hidden="true"></span></span> 289 - <span class="intra-app-lbl">$escapetool.xml($app.label)</span> 290 - </a> 291 - #end 335 + #set ($href = '') 336 + #if ("$!app.ref" != '') 337 + #set ($href = $xwiki.getURL($app.ref)) 338 + #elseif ("$!app.url" != '') 339 + #set ($href = $app.url) 340 + #end 341 + <a class="intra-app" style="background: $app.color;"#if($href != '') href="$href"#end> 342 + <span class="intra-app-ic"><span class="fa fa-$app.icon" aria-hidden="true"></span></span> 343 + <span class="intra-app-lbl">$escapetool.xml($app.label)</span> 344 + </a> 345 +#end 292 292 </div> 293 293 294 294 ## ----- NAECHSTE TERMINE (Mocca Calendar) / RUECKSEITE: TAGCLOUD ----- ... ... @@ -298,10 +298,19 @@ 298 298 299 299 <!-- VORDERSEITE: Naechste Termine --> 300 300 <div class="intra-flip-face intra-flip-front"> 301 - <span class="intra-flip-hint">⋮ Maus von unten</span> 302 - <div class="intra-widget-h">Nächste Termine</div> 355 + <div class="intra-widget-h"><a class="intra-cal-link" href="$xwiki.getURL('MoccaCalendar.WebHome', 'view')">Nächste Termine</a></div> 303 303 <div class="intra-cal-list"> 304 304 #set ($now = $datetool.date) 358 + ## ---- Kalenderfarben einmalig laden: Event-Elternseite (= Kalender) -> Farbe/Titel ---- 359 + #set ($calXwql = "select doc.fullName, calendar.color, calendar.title from Document doc, doc.object(MoccaCalendar.MoccaCalendarClass) calendar") 360 + #set ($calResults = $services.query.xwql($calXwql).execute()) 361 + #set ($calColorMap = {}) 362 + #set ($calTitleMap = {}) 363 + #foreach ($cr in $calResults) 364 + #set ($discard = $calColorMap.put("$cr.get(0)", "$!cr.get(1)")) 365 + #set ($discard = $calTitleMap.put("$cr.get(0)", "$!cr.get(2)")) 366 + #end 367 + #set ($defaultCalColor = '#8a97a6') 305 305 #set ($evtXwql = "from doc.object(MoccaCalendar.MoccaCalendarEventClass) as event where event.startDate >= :now and doc.hidden = false order by event.startDate asc") 306 306 #set ($evtNames = $services.query.xwql($evtXwql).bindValue('now', $now).setLimit(6).execute()) 307 307 #if ($evtNames && $evtNames.size() > 0) ... ... @@ -312,7 +312,18 @@ 312 312 #set ($eAllDay = $eo.getValue('allDay')) 313 313 #set ($eTitle = $ed.getPlainTitle()) 314 314 #if ($eTitle == '')#set ($eTitle = "$!eo.getValue('title')")#end 378 + ## Kalender der Elternseite ermitteln (Events liegen als Kind-Seite unter ihrem Kalender) 379 + #set ($eParent = "$!ed.getParent()") 380 + #set ($eColor = $calColorMap.get($eParent)) 381 + #if (!$eColor || $eColor == '') 382 + #set ($eColor = $defaultCalColor) 383 + #end 384 + #set ($eCalName = $calTitleMap.get($eParent)) 385 + #if (!$eCalName || $eCalName == '') 386 + #set ($eCalName = $xwiki.getDocument($eParent).getPlainTitle()) 387 + #end 315 315 <a class="intra-cal-item" href="$ed.getURL('view')"> 389 + <span class="intra-cal-dot" style="background: $escapetool.xml($eColor);" title="$escapetool.xml($eCalName)"></span> 316 316 <span class="intra-cal-date">#if($eStart)$datetool.format('dd.MM.', $eStart)#if("$!eAllDay" != '1') $datetool.format('HH:mm', $eStart)#end#end</span> 317 317 <span class="intra-cal-title">$escapetool.xml($eTitle)</span> 318 318 </a> ... ... @@ -373,21 +373,18 @@ 373 373 var box = document.getElementById('intra-flip-side'); 374 374 if(!box){ return; } 375 375 var hoverCapable = !!(window.matchMedia && window.matchMedia('(hover: hover)').matches); 376 - 377 - // Letzte bekannte Maus-Y-Position global mitverfolgen, um beim Betreten der Karte 378 - // die Bewegungsrichtung zu kennen (Y waechst nach unten -> "von unten" = Y wird kleiner). 450 + ## Letzte bekannte Maus-Y-Position global mitverfolgen, um beim Betreten der Karte 451 + ## die Bewegungsrichtung zu kennen (Y waechst nach unten -> "von unten" = Y wird kleiner). 379 379 var lastY = null; 380 380 document.addEventListener('mousemove', function(e){ lastY = e.clientY; }, {passive:true}); 381 - 382 382 box.addEventListener('mouseenter', function(e){ 383 383 if (!hoverCapable) { return; } 384 - var enteredFromBelow = (lastY !== null && (lastY -e.clientY)>2);456 + var enteredFromBelow = (lastY !== null && e.clientY < lastY); 385 385 if (enteredFromBelow) { 386 386 box.classList.toggle('is-back'); 387 387 } 388 388 lastY = e.clientY; 389 389 }); 390 - 391 391 box.addEventListener('click', function(e){ 392 392 if(e.target.closest('a')){ return; } 393 393 if(hoverCapable){ return; }