Änderungen von Dokument Solr Search

Zuletzt geändert von Daniel Herrmann am 2026/02/04 20:23

Von Version Icon 2.1 Icon
bearbeitet von Daniel Herrmann
am 2025/12/16 11:14
Änderungskommentar: Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.10.0]
Auf Version 1.1 Icon
bearbeitet von admin
am 2025/02/23 19:33
Änderungskommentar: Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.0.0]

Zusammenfassung

Details

Icon Seiteneigenschaften
Dokument-Autor
... ... @@ -1,1 +1,1 @@
1 -XWiki.dherrman
1 +XWiki.admin
Icon XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,7 +1,11 @@
1 1  require(['jquery', 'xwiki-events-bridge'], function($) {
2 2   var enhanceSearchResultHighlights = function() {
3 - const highlights = $(this).removeClass('hidden').prev('.search-result-highlights').addClass('preview');
3 + var highlights = $(this).removeClass('hidden').parent().prev('.search-result-highlights').addClass('preview');
4 4  
5 + // Workaround for IE8 which doesn't support :first-of-type CSS selector.
6 + highlights.find('.search-result-highlight').first().addClass('first').parent('dd').addClass('first')
7 + .prev('dt').addClass('first');
8 +
5 5   $(this).one('click', function(event) {
6 6   event.preventDefault();
7 7   $(event.target).remove();
... ... @@ -33,16 +33,10 @@
33 33   }
34 34   };
35 35  
36 - var addFacetValueCheckbox = function() {
40 + var addFacetValueCheckbox = function(index) {
37 37   // Create an id unique to the facet value.
38 38   let facetContainer = $(this).parents('.search-facet').first();
39 - // We need the ids of the target facet elements to stay stable through the change, in order to refocus the item
40 - // that was clicked and triggered the change.
41 - // We use the JQuery index, so that id indexes are reset across facetContainers.
42 - // This allows for stable indexes: when reloading the facets after changing the filter for the target facet X,
43 - // the ids of all the checkbox for the target facet X will keep the same index.
44 - // This property is lost if multiple facets are changed in the query at once.
45 - $(this).attr('id', facetContainer.attr('data-name') + '-' + facetContainer.find('a.itemName').index($(this)));
43 + $(this).attr('id', facetContainer.attr('data-name') + '-' + index.toString());
46 46   // Initialize the checkbox.
47 47   let checkBox = $(document.createElement('input')).attr('type', 'checkbox');
48 48   checkBox.attr('aria-labelledby', $(this).attr('id'));
... ... @@ -70,7 +70,7 @@
70 70   updateExpandCollapseAllFacetsState(facetsContainer);
71 71  
72 72   // Expand/Collapse toggle for each facet.
73 - facetsContainer.find('.facet-toggle').on('click', function(event) {
71 + facetsContainer.find('.facet-toggler').on('click', function(event) {
74 74   $(event.target).parents('.search-facet').toggleClass('expanded');
75 75   updateExpandCollapseAllFacetsState(facetsContainer);
76 76   });
... ... @@ -85,11 +85,6 @@
85 85   var queryIndex = url.indexOf('?');
86 86   return queryIndex < 0 ? '' : url.substr(queryIndex + 1);
87 87   };
88 -
89 - let removeQueryString = function(url) {
90 - let queryIndex = url.indexOf('?');
91 - return queryIndex < 0 ? url : url.substring(0, queryIndex);
92 - };
93 93  
94 94   var getSearchUIState = function() {
95 95   var expandedFacets = [];
... ... @@ -119,9 +119,7 @@
119 119  
120 120   var searchRequest = null;
121 121  
122 - // changeTargetSelector is the CSS selector of the facet anchor that initiated this reload. '
123 - // We expect the focus to go back to this place once the UI is reloaded.
124 - var pushSearchUIState = function(viewURL, changeTargetSelector) {
115 + var pushSearchUIState = function(viewURL) {
125 125   // If there is a request in progress, abort it to prevent its callback from being called.
126 126   searchRequest && searchRequest.abort();
127 127   $('.search-ui').attr('aria-busy', true);
... ... @@ -134,7 +134,6 @@
134 134   window.history.replaceState && window.history.replaceState(state, document.title);
135 135   // Make sure the browser address bar reflects the new state (and thus the new state can be bookmarked).
136 136   window.history.pushState && window.history.pushState(state, document.title, viewURL);
137 - document.querySelector(changeTargetSelector)?.focus();
138 138   });
139 139   };
140 140  
... ... @@ -141,12 +141,12 @@
141 141   var reloadSearchUI = function(event) {
142 142   event.preventDefault();
143 143   var anchor = $(event.target).closest('a');
144 - anchor.length && anchor.first().trigger('xwiki:search:update', anchor.attr('href'));
134 + anchor.length && $(document).trigger('xwiki:search:update', anchor.attr('href'));
145 145   };
146 146  
147 147   // Others (e.g. a custom facet) can trigger a search UI update by firing this event.
148 148   $(document).on('xwiki:search:update', function(event, viewURL) {
149 - pushSearchUIState(viewURL, `[data-facetvalue='${CSS.escape(event.target.dataset.facetvalue)}']`);
139 + pushSearchUIState(viewURL);
150 150   });
151 151  
152 152   $(window).on('popstate', function(event) {
... ... @@ -186,41 +186,10 @@
186 186   });
187 187  
188 188   var enhanceSearchUI = function() {
189 - // Enhance search options
190 - document.querySelectorAll('input.options-item').forEach(function (option){
191 - option.addEventListener('change', function() {
192 - let queryFieldName = this.getAttribute('data-query-name');
193 - let queryField = document.querySelector('input[name="' + queryFieldName + '"]');
194 - queryField.value = this.checked ? 'true' : 'false';
195 - // We want to build the URL the same way it's done in the velocimacro #extendQueryString
196 - // We retrieve the search parameters of the latest request
197 - let params = new URLSearchParams(window.location.search);
198 - let formParams = new URLSearchParams(new FormData(this.form));
199 - // We replace the existing parameters with their value from the form
200 - for (let param of formParams.keys()) {
201 - if (params.has(param)) params.delete(param);
202 - for (let paramValue of formParams.getAll(param)) {
203 - params.append(param,paramValue);
204 - }
205 - }
206 - pushSearchUIState(window.location.pathname + '?' + params.toString(),
207 - 'input[data-query-name="' + queryFieldName + '"]');
208 - });
209 - });
210 - // Enhance search result sorting
211 - document.querySelectorAll('.search-results-sort select#sort-by-input, ' +
212 - '.search-results-sort input#sort-order-input').forEach(function (sortInput){
213 - sortInput.addEventListener('change', function() {
214 - let baseURL = removeQueryString(this.form.getAttribute('action'));
215 - pushSearchUIState(baseURL + "?" +
216 - new URLSearchParams(new FormData(this.form)).toString(),
217 - 'input[data-query-name="' + this.getAttribute('name') + '"]');
218 - });
219 - });
220 -
221 221   $('.search-result-highlightAll').each(enhanceSearchResultHighlights);
222 222   $('.search-facets').each(enhanceSearchFacets);
223 223   $([
182 + '.search-results-sort a.sort-item',
224 224   '.search-options a.options-item',
225 225   '.pagination a',
226 226   '.controlPagination a',
Icon XWiki.StyleSheetExtension[0]
Code
... ... @@ -1,7 +1,7 @@
1 1  #template('colorThemeInit.vm')
2 2  
3 3  /* Hide the 'Created by', 'Modified by' and 'Tags' document sections. */
4 -.xdocLastModification, #xdocFooter {
4 +.xdocLastModification, .skin-colibri #document-info, #xdocFooter {
5 5   display: none;
6 6  }
7 7  #document-title > h1 {
... ... @@ -9,99 +9,86 @@
9 9   margin-bottom: 0;
10 10  }
11 11  
12 -/**
13 - * Layout for the search bar
14 - */
15 -.search-bar {
16 - margin: .5em 0;
17 -}
18 -
19 -@media (min-width: 768px) {
20 - .search-bar {
21 - max-width: 50%;
22 - }
23 -}
24 -
25 25  /**
26 - * Layout for search controls (sort + options)
13 + * Search form
27 27   */
28 28  
29 -.search-results-controls {
30 - display: flex;
31 - flex-wrap: wrap;
32 - gap: 1em;
33 -
34 - & label {
35 - /* Reset the styles of the labels. */
36 - margin: 0;
37 - font-weight: unset;
38 - }
16 +.skin-colibri .search-form {
17 + /* There is no space after the title in Colibri. */
18 + margin-top: 1.5em;
39 39  }
40 40  
41 -.search-results-sort,
42 -.search-options, .search-options > ul, .search-options > ul > li,
43 -.search-options > ul > li > label {
44 - display: flex;
45 - gap: .4em;
46 - align-items: center;
21 +.skin-colibri .search-form input[type="search"] {
22 + /* Colibri doesn't have the grid system. */
23 + width: 50%;
47 47  }
48 48  
49 49  /**
50 50   * Sort
51 51   */
52 -/* This select should be especially lightweight on the UI. We're removing the default border and shadow. */
53 -#sort-by-input {
54 - cursor: pointer;
55 55  
56 - &:hover, &:focus {
57 - cursor: pointer;
58 - }
59 -}
60 -
61 -/* This checkbox input should be styled as a switch between ascending and descending states. */
62 -.search-results-sort #sort-order-input {
63 - /* Hide the default checkbox. We rely on the style of the icon in its label to make it work. */
64 - appearance: none;
30 +ul.search-results-sort {
31 + color: $theme.textSecondaryColor;
32 + font-size: .9em;
33 + padding: 5px 0 2px 0;
65 65   margin: 0;
66 66  }
67 -
68 -#sort-by-input, .search-results-sort label:has(>#sort-order-input) {
69 - /* We want most of the styles from "form-control", but not the shadow that comes from bootstrap. */
70 - box-shadow: none;
71 - & :hover,& :focus,& :focus-within {
72 - border-color: var(--input-border-focus);
73 - }
36 +.search-results-sort li {
37 + display: inline;
38 + list-style-type: none;
39 + padding-left: 1.5em;
74 74  }
75 -
76 -/* Flip the second icon so that it's the arrow going up and down. */
77 -.search-results-sort label #sort-order-input + * + * {
78 - transform: scaleY(-1);
41 +.search-results-sort li:first-of-type {
42 + padding: 0;
79 79  }
80 -
81 -/* When the box is checked, we want to hide the first icon.
82 -When the box is not checked, we want to hide the second icon. */
83 -.search-results-sort label #sort-order-input:checked + *,
84 -.search-results-sort label #sort-order-input:not(:checked) + * + * {
85 - display: none;
44 +a.sort-item {
45 + color: inherit;
46 + text-decoration: none;
86 86  }
48 +a.sort-item:hover {
49 + color: $theme.linkColor;
50 + text-decoration: underline;
51 +}
52 +a.sort-item.active, a.sort-item.active:hover {
53 + font-weight: bold;
54 + color: $theme.textColor;
55 + text-decoration: none;
56 +}
57 +.sort-item-order {
58 + margin-left: .3em;
59 +}
87 87  
88 88  /**
89 89   * Options
90 90   */
91 91  
92 -.search-options ul {
65 +ul.search-options {
66 + color: $theme.textSecondaryColor;
67 + font-size: .9em;
68 + padding: 5px 0 2px 0;
93 93   margin: 0;
70 +}
71 +.search-options li {
72 + display: inline;
73 + list-style-type: none;
74 + padding-left: 1.5em;
75 +}
76 +.search-options li:first-of-type {
94 94   padding: 0;
95 -
96 - & input[type="checkbox"] {
97 - position: unset;
98 - margin: 0;
99 - }
100 -
101 - & label {
102 - margin-right: 1em;
103 - }
104 104  }
79 +a.options-item {
80 + color: inherit;
81 + text-decoration: none;
82 +}
83 +a.options-item:hover {
84 + color: $theme.linkColor;
85 + text-decoration: underline;
86 +}
87 +a.options-item.active, a.options-item.active:hover{
88 + font-weight: bold;
89 + color: $theme.textColor;
90 + text-decoration: none;
91 +}
105 105  
106 106  /**
107 107   * Search Results
... ... @@ -111,6 +111,12 @@
111 111   margin-top: 1em;
112 112  }
113 113  
101 +/* Colibri skin doesn't have the grid system. */
102 +.skin-colibri .search-results-left {
103 + margin: 0.5em 20em 0.5em 0;
104 + padding: 0.5em 0.5em 0.5em 0;
105 +}
106 +
114 114  .search-results {
115 115   padding: .3em 0 .8em 0;
116 116  }
... ... @@ -174,8 +174,6 @@
174 174  
175 175  dl.search-result-highlights > dt {
176 176   margin-top: .3em;
177 - color: var(--text-muted);
178 - font-weight: var(--font-weight-semibold);
179 179  }
180 180  
181 181  blockquote.search-result-highlight {
... ... @@ -196,6 +196,11 @@
196 196   font-weight: bold;
197 197  }
198 198  
190 +dl.search-result-highlights > dt {
191 + color: $theme.textSecondaryColor;
192 + font-weight: normal;
193 +}
194 +
199 199  dl.search-result-highlights.preview dt,
200 200  dl.search-result-highlights.preview dd > * {
201 201   display: none;
... ... @@ -202,10 +202,17 @@
202 202  }
203 203  
204 204  dl.search-result-highlights.preview dt:first-of-type,
205 -dl.search-result-highlights.preview dd:first-of-type blockquote:first-of-type {
201 +dl.search-result-highlights.preview dd:first-of-type blockquote:first-of-type,
202 +/* Workaround for IE8 which doesn't support :first-of-type CSS selector. */
203 +dl.search-result-highlights.preview dt.first,
204 +dl.search-result-highlights.preview dd.first blockquote.first {
206 206   display: block;
207 207  }
208 208  
208 +a.search-result-highlightAll:after {
209 + content: ' \bb';
210 +}
211 +
209 209  .search-result-debug {
210 210   white-space: pre;
211 211  }
... ... @@ -214,23 +214,40 @@
214 214   * Facets
215 215   */
216 216  
217 -.search-facets-header{
218 - border-bottom: 1px solid var(--xwiki-border-color);
220 +.search-facets {
221 + background-color: $theme.backgroundSecondaryColor;
222 + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
223 + /* Leave space for the bottom shadow. */
224 + margin-bottom: 1em;
225 + border-radius: 7px;
219 219  }
227 +/* Colibri skin doesn't have the grid system. */
228 +.skin-colibri .search-facets {
229 + float: right;
230 + max-width: 19.5em;
231 + width: 19.5em;
232 +}
220 220  
221 -.search-facets-header strong {
222 - font-size: 1.25em;
234 +.search-facets-header,
235 +.search-facets-actions,
236 +.search-facet {
237 + border-bottom: 1px solid $theme.borderColor;
238 + border-top: 1px solid $theme.pageContentBackgroundColor;
239 + position: relative;
223 223  }
224 224  
225 225  .search-facets-header,
226 226  .search-facets-actions {
227 - padding: .5em 0;
244 + padding: 0.5em 1em;
228 228  }
229 -
230 230  .search-facet {
231 - padding: .2em 0;
247 + padding: 0.5em .8em;
232 232  }
233 233  
250 +.search-facets-header {
251 + border-top: none;
252 +}
253 +
234 234  .search-facets-header > p,
235 235  .search-facets-actions > p {
236 236   /* The wiki syntax generates paragraphs which have bottom margin. */
... ... @@ -241,6 +241,16 @@
241 241   font-size: .8em;
242 242  }
243 243  
264 +.search-facets-actions a {
265 + color: $theme.textSecondaryColor;
266 + text-decoration: none;
267 +}
268 +
269 +.search-facets-actions a:hover {
270 + color: $theme.linkColor;
271 + text-decoration: underline;
272 +}
273 +
244 244  .search-facets-action-collapseAll,
245 245  .search-facets-action-expandAll {
246 246   float: right;
... ... @@ -252,37 +252,35 @@
252 252   margin: 0;
253 253  }
254 254  
255 -.search-facet-header, .search-facet-body {
256 - padding-left: .5em;
257 - border: 1px solid var(--xwiki-border-color);
258 - border-radius: var(--border-radius-small);
285 +.search-facet:last-of-type {
286 + border-bottom: none;
259 259  }
260 260  
261 261  .search-facet-header {
262 - background-color: var(--xwiki-background-secondary-color);
263 -}
264 -
265 -.search-facet-header label {
266 266   color: $theme.titleColor;
267 267   cursor: pointer;
292 + line-height: 1.4em;
293 + margin: 0 .2em;
268 268   display: flex;
269 269   justify-content: space-between;
270 - align-items: center;
296 + position: relative;
271 271  }
272 272  
273 -.search-facet-body {
274 - opacity: 0;
275 - visibility: hidden; /* This makes sure the element is removed from the accessibility tree. */
299 +.search-facet:last-of-type .search-facet-header:after {
300 + border: medium none;
301 +}
276 276  
277 - position: absolute;
278 - transform: translateY(-10px); /* Start the animation slightly above */
279 - padding-top: .5em;
280 -
281 - border-top-width: 0;
282 - border-top-left-radius: 0;
283 - border-top-right-radius: 0;
303 +.search-facet.expanded:last-of-type .search-facet-header:after {
304 + border-bottom: 1px dotted $theme.pageContentBackgroundColor;
305 + border-top: 1px dotted $theme.borderColor;
284 284  }
285 285  
308 +.search-facet-body {
309 + overflow: hidden; /* required for effect */
310 + display: none;
311 + margin-top: .5em;
312 +}
313 +
286 286  .search-facet-body ul,
287 287  .search-facet-body ol {
288 288   font-size: .9em;
... ... @@ -291,55 +291,37 @@
291 291  .search-facet-body li {
292 292   display: flex;
293 293   flex-wrap: wrap;
294 - padding: .3em .5em;
322 + padding: .1em .2em;
295 295  }
296 296  
297 -.search-facet .search-facet-header .facet-toggle, button.facet-value-toggle {
325 +.search-facet .search-facet-header .facet-toggler, button.facet-value-toggler {
298 298   background: transparent;
299 299   transition: background-color .2s ease-in-out;
300 300  }
301 301  
302 -.search-facet .search-facet-header .facet-toggle:active, button.facet-value-toggle:active {
330 +.search-facet .search-facet-header .facet-toggler:active, button.facet-value-toggler:active {
303 303   box-shadow: unset;
304 304  }
305 305  
306 -.search-facet .search-facet-header .facet-toggle > span, button.facet-value-toggle > span,
307 -.search-facet .search-facet-header .facet-toggle > img, button.facet-value-toggle > img {
334 +.search-facet .search-facet-header .facet-toggler > span, button.facet-value-toggler > span,
335 +.search-facet .search-facet-header .facet-toggler > img, button.facet-value-toggler > img {
308 308   transform: rotate(90deg);
309 309  }
310 310  
311 -.search-facet.expanded .search-facet-header .facet-toggle > span, .expanded > button.facet-value-toggle > span,
312 -.search-facet.expanded .search-facet-header .facet-toggle > img, .expanded > button.facet-value-toggle > img {
339 +.search-facet.expanded .search-facet-header .facet-toggler > span, .expanded > button.facet-value-toggler > span,
340 +.search-facet.expanded .search-facet-header .facet-toggler > img, .expanded > button.facet-value-toggler > img {
313 313   transform: rotate(0deg);
314 314  }
315 315  
316 -@media (prefers-reduced-motion: no-preference) {
317 - .search-facet .search-facet-header .facet-toggle > span, button.facet-value-toggle > span,
318 - .search-facet .search-facet-header .facet-toggle > img, button.facet-value-toggle > img {
344 +@media not (prefers-reduced-motion) {
345 + .search-facet .search-facet-header .facet-toggler > span, button.facet-value-toggler > span,
346 + .search-facet .search-facet-header .facet-toggler > img, button.facet-value-toggler > img {
319 319   transition: transform 0.2s ease;
320 320   }
321 -
322 - .search-facet-body {
323 - transition: opacity 0.3s ease, transform 0.3s ease;
324 - }
325 325  }
326 326  
327 -.search-facet.expanded {
328 - & .search-facet-header {
329 - border-bottom-width: 0;
330 - border-bottom-left-radius: 0;
331 - border-bottom-right-radius: 0;
332 -
333 - & label {
334 - font-weight: var(--font-weight-semibold);
335 - }
336 - }
337 - & .search-facet-body {
338 - opacity: 1;
339 - position: unset; /* This element should be positioned normally when shown. */
340 - visibility: visible;
341 - transform: translateY(0);
342 - }
351 +.search-facet.expanded .search-facet-body {
352 + display: block;
343 343  }
344 344  
345 345  .search-facet-body ul, .search-facet-body ul.users {
... ... @@ -350,6 +350,10 @@
350 350   margin: .5em 0;
351 351  }
352 352  
363 +.search-facet-body li:hover {
364 + background-color: $theme.highlightColor;
365 +}
366 +
353 353  .search-facet-body input[type="checkbox"] {
354 354   margin: .2em 0;
355 355  }
... ... @@ -374,8 +374,7 @@
374 374  }
375 375  
376 376  .search-facet-body .itemName,
377 -.search-facet-body .itemNameempty,
378 -.search-facet-body .facet-value-toggle,
391 +.search-facet-body .facet-value-toggler,
379 379  .search-facet-body .more {
380 380   /* Remove link styling */
381 381   color: $theme.textColor;
... ... @@ -393,11 +393,8 @@
393 393  }
394 394  
395 395  .search-facet-body .itemCount {
396 - padding: .1em .5em;
409 + padding: .1em 0;
397 397   margin-left: auto;
398 - background-color: var(--nav-link-hover-bg);
399 - /* We want those item count blocks to be pill shaped. */
400 - border-radius: 1em / 50%;
401 401  }
402 402  
403 403  @media (max-width: 768px) {
... ... @@ -417,6 +417,17 @@
417 417  }
418 418  
419 419  /**
430 + * Fix the breadcrumb in Colibri skin.
431 + */
432 +.skin-colibri .breadcrumb > li {
433 + display: inline;
434 +}
435 +.skin-colibri .breadcrumb > li + li:before {
436 + color: $theme.textSecondaryColor;
437 + content: ' \00BB ';
438 +}
439 +
440 +/**
420 420   * Miscellaneous
421 421   */
422 422  
... ... @@ -425,3 +425,13 @@
425 425   padding-left: 0;
426 426  }
427 427  
449 +.paginationFilter .resultsNo,
450 +.paginationFilter .controlPagination,
451 +.paginationFilter .pagination {
452 + line-height: 22px;
453 +}
454 +
455 +.iconRSS {
456 + background: url("$xwiki.getSkinFile('icons/silk/feed.png')") no-repeat scroll 0 0 transparent;
457 + padding-left: 20px;
458 +}

Community

https://wiki.makerspace-darmstadt.de/bin/download/Panels/MKSP%20Slack/Slack_MKSP.png

Wir benutzen Slack, um miteinander zu kommunizieren. Melde Dich an und werde Teil unserer Maker-Community!

Zum Slack Workspace

Frage? FAQ!

Du hast eine Frage, die sich nicht direkt im Wiki findet?

Natürlich kannst Du die Frage jederzeit gerne in der Slack Community stellen. Bevor Du das machst, schau doch bitte einmal auf unserer Homepage bei den Häufig gestellten Fragen vorbei. Wir versuchen diese Fragen stets aktuell zu halten, eventuell hilft Dir das ja schon weiter.

Offene Werkstatt

Ohne Anmeldung einfach vorbei kommen. Am besten bringst Du direkt den ausgefüllten Haftungsauschluss mit.

Jeden Donnerstag ab 19 Uhr

Während der offenen Werkstatt kannst Du einfach vorbei kommen und an Deinem Projekt arbeiten. Bitte beachte aber, dass zur Verwendung der Maschinen eine Einweisung erforderlich ist, die Du gegebenfalls vorher absolvieren musst. Wenn ein Mitglied mit entsprechender Einweisung vor Ort ist und Zeit hat, helfen wir natürlich gerne aus. Dies können wir aber nicht garantieren, da Rundgänge Priorität haben.

Sprich Dich idealerweise schon vor der offenen Werkstatt mit einem Mitglied in unserem Slack ab. So kannst Du sicherstellen, dass Du auf jeden Fall arbeiten kannst.

Übrigens: Du kannst Dich mit einem Mitglied gerne auch außerhalb der offenen Werkstattzeiten zum Arbeiten verabreden!

Führungen und Rundgänge

Im Rahmen der offenen Werkstatt bieten wir euch auch gerne einen Rundgang durch unsere Werkstatt. Hier könnt ihr den Verein und unser Konzept kennenlernen sowie die Maschinen und Möglichkeiten der Werkstatt gezeigt bekommen.

Jeden Donnerstag wird eine Führung angeboten:

  • Um 19:15 Uhr (bitte um 19:00 Uhr da sein)

Der Rundgang dauert ca. 45 Minuten und ihr habt natürlich auch die Möglichkeit, eure Fragen loszuwerden.

Bitte beachtet folgendes: Die Werkstatt beinhaltet gefährliche Maschinen. Bringt daher bitte nach Möglichkeit den ausgefüllten und unterschrieben Haftungsauschluss schon mit. Dieser kann aber auch vor Ort ausgefüllt werden, das verzögert allerdings die Abläufe.