Refuge, the shelter of excellence

The Alcântara Marina has capacity for 376 boats, with places that allow vessels of 20 meters in length.
The dock benefits from various services: reception, electricity on the footbridges, collection of waste and oils, security systems, communication systems, bathroom facilities and weather forecast.

9 am – 1 pm and 2 pm – 6 pm (weekdays)

9 am – 1 pm and 2 pm – 7 pm (weekends and holidays)

Advice: This dock closes the reception at 1st January, Easter Sunday, 1st May and 25th December

Contactos

Telefone: +351 213 922 048/58

Fax: +351 213 922 085

Email: doca.alcantara@portodelisboa.pt

An error occurred while processing the template.
The following has evaluated to null or missing:
==> title  [in template "20097#20125#66237" at line 125, column 51]

----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: ${title.getData()}  [in template "20097#20125#66237" at line 125, column 49]
----
1<#-- SliderNumbers.ftl --> 
2<#-- _<@portlet.namespace /> --> 
3<style> 
4 
5/* Seção de apresentação com margem superior */ 
6.maringTopPresentation { 
7  margin-top: 7%; 
8  min-height: 770px; 
9
10 
11/* Paginação do slider */ 
12.sliderPagination${randomNamespace} { 
13  display: none; 
14
15 
16.sliderPagination${randomNamespace} .is-active { 
17  transform: unset; 
18  background: #82c6e2; 
19  opacity: 1; 
20
21 
22/* Indicadores do slider */ 
23.sliderIndicators${randomNamespace} { 
24  background: #82c6e2; 
25  opacity: 0.2; 
26  width: 6px; 
27  height: 6px; 
28
29 
30/* Botões de navegação do slider */ 
31.sliderPrev_${randomNamespace}, 
32.sliderNext_${randomNamespace} { 
33  width: 44px; 
34  height: 44px; 
35  background-color: #fff; 
36  opacity: 0.5; 
37  border-radius: 5px; 
38
39 
40.sliderPrev_${randomNamespace} { 
41  left: 0; 
42
43 
44.sliderNext_${randomNamespace} { 
45  right: 0; 
46
47 
48/* Media Query para telas menores que 767px */ 
49@media only screen and (max-width: 767px) { 
50  .sliderPagination${randomNamespace} { 
51    display: flex; 
52    bottom: 2.5em; 
53
54 
55  .numbDiv { 
56    padding: 65px 0; 
57
58 
59  .sliderPrev_${randomNamespace}, 
60  .sliderNext_${randomNamespace} { 
61    top: 60%; 
62
63 
64  .sliderNext_${randomNamespace} { 
65    right: 48%; 
66    transform: translateX(100%); 
67
68 
69  .sliderPrev_${randomNamespace} { 
70    left: 48%; 
71    transform: translateX(-100%); 
72
73  .gfi .slider-DeepSea .silhuetas_lisboa { 
74       margin-top: 0; 
75
76  .gfi .slider-DeepSea .silhuetas_lisboa .wave-contents.buildings { 
77    min-height: 300px; 
78
79  .gfi .slider-DeepSea .silhuetas_lisboa .back div { 
80    height: 250px !important; 
81
82
83 
84/* Estilos gerais para a classe .back */ 
85.back div { 
86  height: 350px !important; 
87  align-content: end !important; 
88
89 
90.back img { 
91  max-height: 350px; 
92  width: auto; 
93
94 
95/* Imagens flutuadas para diferentes variantes */ 
96.back_1 img { 
97  float: right; 
98
99 
100.back_3 img { 
101  float: left; 
102
103 
104/* Container centralizado com z-index */ 
105.back_2, 
106.back_3 { 
107  width: 100%; 
108  position: absolute; 
109  z-index: 5; 
110  top: 0; 
111  height: 306px; 
112  text-align: center; 
113
114 
115.back_3 { 
116  align-content: end; 
117
118 
119</style> 
120<#assign counterEntries = 0> 
121<div class="slider-DeepSea sliderContainer  deepSea_Bk"  style="margin-top:-10px"> 
122	<div class="wave" style="background-color: #E5EEF1"></div> 
123	 
124	<div  class="container deepSea_Bk block-numbers"  data-aos="fade-up" data-aos-duration="1000"> 
125	    <h2 class=" descriptiveBannerTitle">${title.getData()}</h2> 
126		<div id="splide_${randomNamespace}" class="splide"> 
127			<div class="splide__arrows"> 
128				<button class="splide__arrow splide__arrow--prev sliderPrev_${randomNamespace}"> 
129					<svg style="width:30px; height:30px; fill: #14213d"> 
130						<use href="/o/apl-theme/images/icons.svg#IconKeyboardArrowRightRounded"></use> 
131					</svg> 
132				</button> 
133				<button class="splide__arrow splide__arrow--next sliderNext_${randomNamespace}"> 
134					<svg style="width: 30px; height: 30px; fill: #14213d"> 
135						<use href="/o/apl-theme/images/icons.svg#IconKeyboardArrowRightRounded"></use> 
136					</svg> 
137				</button> 
138			</div> 
139			<div class="splide__track"> 
140				<div class="splide__list"> 
141					<#if numb?? && numb.getSiblings()?has_content> 
142						<#list numb.getSiblings() as cur_numb> 
143							<#assign counterEntries=counterEntries + 1> 
144								<div class="splide__slide"> 
145									<div class="numbDiv"> 
146										<p class="numbInfo">${cur_numb.getData()}</p> 
147										<p class="numbDesc">${cur_numb.desc.getData()}</p> 
148									</div> 
149								</div> 
150						</#list> 
151					</#if> 
152				</div> 
153			</div> 
154		</div> 
155	</div> 
156	<div class="silhuetas_lisboa"> 
157		<div class="wave-contents buildings"> 
158			<div class="back"> 
159			 
160			   <div class="back_3"> 
161			     <div data-aos="fade-left" data-aos-duration="1000" class="aos-init aos-animate"> 
162			       <img src="/o/apl-theme/images/background/silhuetas_lisboa_back3.svg" alt="" style="float: left;     margin-bottom: 0 !important;" > 
163			     </div>  
164			     </div> 
165			  
166			 <div class="back_2"> 
167			     <div data-aos="fade-right" data-aos-duration="1500" class="aos-init aos-animate"> 
168			        <img src="/o/apl-theme/images/background/silhuetas_lisboa_back2.svg" alt="" > 
169			     </div> 
170			 </div> 
171			  
172            <div class="back_1" data-aos="fade-left" data-aos-duration="2000" class="aos-init aos-animate"> 
173                <img src="/o/apl-theme/images/background/silhuetas_lisboa_back1.svg" alt=""  > 
174            </div> 
175             
176            <div class="mid"> 
177				<div data-aos="fade-right" data-aos-duration="1000" class="aos-init aos-animate"> 
178					<img src="/o/apl-theme/images/background/silhuetas_lisboa_mid.svg" alt=""> 
179				</div> 
180			</div> 
181			<div class="front"> 
182				<div data-aos="fade-right" data-aos-duration="3000" class="aos-init aos-animate"> 
183					<img src="/o/apl-theme/images/background/silhuetas_lisboa_front.svg" alt=""> 
184				</div> 
185			</div> 
186			</div> 
187		</div>			 
188	</div> 
189</div> 
190 
191<script> 
192<#-- IMPORTANTE: DEFINIR AQUI O NUMERO DE ITENS POR PAGINA PARA MOBILE / TABLET / DESKTOP --> 
193<#-- Desktop --> 
194<#assign slidesPerPageDesktop = 3> 
195<#-- Tablet --> 
196<#assign slidesPerPageTablet = 3> 
197<#-- Mobile --> 
198<#assign slidesPerPageMobile = 1> 
199 
200<#-- Define drag default --> 
201var isDraggableDesktop = true; 
202var isDraggableTablet = true; 
203var isDraggableMobile = true; 
204 
205<#-- Desativa o drag se o numero de entradas for menor que o numero de itens por página--> 
206if (${counterEntries} < (${slidesPerPageDesktop} + 1)){ 
207    isDraggableDesktop = false; 
208
209if (${counterEntries} < (${slidesPerPageTablet} + 1)){ 
210    isDraggableTablet = false; 
211
212if (${counterEntries} < (${slidesPerPageMobile} + 1)){ 
213    isDraggableMobile = false; 
214
215 
216<#-- Configuração do slider que irá ser criado --> 
217    var splide_${randomNamespace} = new Splide( '#splide_${randomNamespace}', { 
218    perPage: 3, 
219   <#-- perPage: ${slidesPerPageDesktop},  -->   
220    perMove: 1, 
221    type: 'loop', 
222    height: 100, 
223    pagination: true, 
224    drag: isDraggableDesktop, 
225    classes: { 
226		// Add classes for pagination. 
227		pagination: 'splide__pagination sliderPagination${randomNamespace}', // container 
228		page      : 'splide__pagination__page sliderIndicators${randomNamespace}', // each button 
229	}, 
230    breakpoints: { 
231		767: { 
232			perPage: ${slidesPerPageMobile}, 
233			height: 300, 
234			drag: isDraggableMobile, 
235
236
237}); 
238 
239<#-- Fazer aparecer ou desaparecer as setas dependendo do numero de páginas (se houver só uma página não queremos setas) --> 
240splide_${randomNamespace}.on( 'mounted resize', function() { 
241    var slid_${randomNamespace} = document.getElementById('splide_${randomNamespace}'); 
242    var uls_${randomNamespace} = slid_${randomNamespace}.getElementsByClassName('splide__pagination'); // todos os ul's 
243    var ul_${randomNamespace} = uls_${randomNamespace}[uls_${randomNamespace}.length - 1]; // ul's com os lis da paginação 
244    var lisCount_${randomNamespace} = ul_${randomNamespace}.childElementCount; // 2 
245    <#-- var lis_${randomNamespace} = ul_${randomNamespace}.children; --> 
246    if (lisCount_${randomNamespace} > 1){ 
247        $(".sliderPrev_${randomNamespace}").css("display", "flex"); 
248        $(".sliderNext_${randomNamespace}").css("display", "flex"); 
249    } else { 
250        document.querySelector("#splide_${randomNamespace} > ul > li:nth-child(1) > button").click(); 
251        $(".sliderPrev_${randomNamespace}").css("display", "none"); 
252        $(".sliderNext_${randomNamespace}").css("display", "none"); 
253
254} ); 
255 
256<#-- Codigo que lança a criação do slider --> 
257splide_${randomNamespace}.mount(); 
258 
259 
260 
261<#-- anime elemento numeros --> 
262document.addEventListener('DOMContentLoaded', () => { 
263  const blockNumbers = document.querySelector('.block-numbers'); 
264 
265  const observer = new IntersectionObserver(entries => { 
266    entries.forEach(entry => { 
267      if (entry.isIntersecting) { 
268        blockNumbers.classList.add('show'); 
269        // Opcional: Para evitar que a animação aconteça várias vezes 
270        observer.unobserve(entry.target); 
271
272    }); 
273  }, { threshold: 0.5 }); // Ativa quando 50% do elemento estiver visível 
274 
275  observer.observe(blockNumbers); 
276}); 
277 
278  
279</script> 
280<script> 
281    AOS.init(); 
282</script>