Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> categoryResponse[0]  [in template "62757443695457#32456#108258" at line 10, column 27]

----
Tip: It's the final [] step that caused this error, not those before it.
----
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: #assign categoryId = categoryResponse...  [in template "62757443695457#32456#108258" at line 10, column 5]
----
1<#assign contents = []> 
2<#assign categoryName = ""> 
3<#assign peti = "/headless-delivery/v1.0/sites/" + groupId + "/content-structures?filter=name eq 'Hotel Card'"/> 
4<#assign structures = restClient.get("/headless-delivery/v1.0/sites/" + groupId + "/content-structures?filter=name eq 'Hotel Card'").items/> 
5<#if (structures?size > 0)> 
6    <#assign categoryName = (shortName.getData()!"")> 
7    <#assign vocabularyResponse = restClient.get("/headless-admin-taxonomy/v1.0/sites/" + groupId + "/taxonomy-vocabularies?filter=name eq 'Destinations'").items> 
8    <#assign vocabularyId = vocabularyResponse[0].id> 
9    <#assign categoryResponse = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-vocabularies/" + vocabularyId + "/taxonomy-categories?filter=name eq '" + categoryName + "'").items> 
10    <#assign categoryId = categoryResponse[0].id> 
11 
12    <#assign response = restClient.get("/headless-delivery/v1.0/content-structures/" + structures[0].id + "/structured-contents?filter=taxonomyCategoryIds/any(t:t eq " + categoryId + ")&pageSize=100")> 
13    <#assign contents = response.items> 
14</#if> 
15<#if (contents?size >0)> 
16    <section class="mp-max-width-section"> 
17        <div class="our-accomodations__wrapper" id="hotelesDestino"> 
18            <h2 class="mp-title-section mp-text-center"> 
19                 
20								<#if containsCircuits?? && getterUtil.getBoolean(containsCircuits.getData())>     
21										Información adicional y alojamientos en ${categoryName?lower_case?cap_first} 
22								<#elseif containCruises?? && getterUtil.getBoolean(containCruises.getData())> 
23								    Información adicional y tipos de camarotes en ${categoryName?lower_case?cap_first} 
24								<#else> 
25                    Nuestros alojamientos en ${categoryName?lower_case?cap_first} 
26                </#if> 
27 
28            </h2> 
29            <div class="swiper"> 
30                <ul class="cards-list__wrapper swiper-wrapper" aria-label="Carousel"> 
31                    <#list contents as content> 
32 
33                    <li class="swiper-slide"> 
34                        <a href="/viajes/${content.friendlyUrlPath}"> 
35                            <div class="card-2__wrapper card-2__wrapper--resume"> 
36                                <div class="image-container"> 
37                                    <#assign imageField = getFieldByName(content.contentFields, "images")> 
38                                    <#if imageField?has_content && imageField.contentFieldValue.image?has_content> 
39                                        <img src="${imageField.contentFieldValue.image.contentUrl}" 
40                                             alt="${imageField.contentFieldValue.image.description}" 
41                                             loading="lazy"> 
42                                    </#if> 
43                                </div> 
44                                <div class="data__wrapper"> 
45                                    <#assign nameField = getFieldByName(content.contentFields, "name")> 
46                                    <#if nameField?has_content> 
47                                        <h3>${nameField.contentFieldValue.data}</h3> 
48                                    </#if> 
49                                    <#assign categoryField = getFieldByName(content.contentFields, "category")> 
50                                    <#if categoryField?has_content> 
51                                        <#assign category = categoryField.contentFieldValue.data> 
52                                        <#attempt> 
53                                            <#assign stars = category?split("*")[0]?number> 
54                                            <#recover> 
55                                                <#assign stars = 0> 
56                                        </#recover> 
57                                        <#if (stars > 0)> 
58                                            <ul class="stars__wrapper" role="img" aria-label="Rating: ${stars} de 5 estrellas"> 
59                                                <#list 1..stars as i> 
60                                                    <li aria-hidden="true"> 
61                                                        <svg width="16" height="16" viewBox="0 0 16 16" data-icon="star"> 
62                                                            <symbol id="ai:local:star"> 
63                                                                <path fill="currentColor" d="m8 12.689-3.89 2.346a.72.72 0 0 1-.436.107.79.79 0 0 1-.396-.147.84.84 0 0 1-.273-.332.648.648 0 0 1-.03-.453l1.032-4.417L.573 6.82a.737.737 0 0 1-.245-.388.702.702 0 0 1 .027-.428.845.845 0 0 1 .233-.34.807.807 0 0 1 .416-.171l4.532-.396L7.296.925a.68.68 0 0 1 .291-.344.819.819 0 0 1 .825 0 .68.68 0 0 1 .291.344l1.76 4.172 4.533.396a.807.807 0 0 1 .415.172.846.846 0 0 1 .233.34.703.703 0 0 1 .028.427.737.737 0 0 1-.245.388l-3.435 2.973 1.033 4.417a.648.648 0 0 1-.031.453.839.839 0 0 1-.273.332.79.79 0 0 1-.396.147.72.72 0 0 1-.435-.107L8 12.689Z"></path> 
64                                                            </symbol> 
65                                                            <use xlink:href="#ai:local:star"></use> 
66                                                        </svg> 
67                                                    </li> 
68                                                </#list> 
69                                            </ul> 
70                                        </#if> 
71                                    </#if> 
72                                    <div class="info__description"> 
73                                        <svg width="24" height="24" viewBox="0 0 12 20" data-icon="distance"> 
74                                            <symbol id="ai:local:distance"> 
75                                                <path fill="currentColor" 
76                                                      d="M6.441 19.5c-1.612 0-2.932-.231-3.96-.693C1.456 18.345.942 17.742.942 17c0-.391.168-.749.504-1.073.336-.324.8-.605 1.394-.842l.287.957c-.347.148-.619.303-.813.467-.195.163-.315.327-.36.491.114.446.598.808 1.452 1.085.854.276 1.866.415 3.036.415 1.158 0 2.168-.139 3.03-.415.862-.277 1.35-.639 1.465-1.085-.045-.164-.165-.325-.36-.482a3.956 3.956 0 0 0-.813-.476l.305-.957c.594.237 1.055.518 1.382.842.328.324.491.682.491 1.073 0 .742-.513 1.345-1.54 1.807-1.027.462-2.347.693-3.96.693Zm0-5.137c.3-.588.656-1.188 1.066-1.8.41-.613.831-1.198 1.263-1.755.643-.839 1.157-1.601 1.543-2.288.385-.686.578-1.543.578-2.57 0-1.228-.434-2.277-1.303-3.146C8.718 1.934 7.67 1.5 6.44 1.5c-1.228 0-2.277.435-3.146 1.304-.869.87-1.304 1.918-1.304 3.146 0 1.027.197 1.884.589 2.57a22.38 22.38 0 0 0 1.533 2.288c.432.557.853 1.142 1.263 1.755.41.612.765 1.212 1.065 1.8Zm0 1.522a.603.603 0 0 1-.403-.163 1.077 1.077 0 0 1-.287-.399c-.435-1.055-.924-1.94-1.47-2.658l-1.565-2.06a12.42 12.42 0 0 1-1.224-2.043c-.334-.707-.5-1.577-.5-2.612 0-1.526.526-2.815 1.58-3.87C3.626 1.028 4.916.5 6.442.5c1.525 0 2.815.527 3.869 1.58 1.053 1.055 1.58 2.344 1.58 3.87 0 1.035-.162 1.905-.488 2.612a10.973 10.973 0 0 1-1.237 2.044c-.482.656-1 1.343-1.552 2.06-.554.716-1.048 1.602-1.482 2.657a1.09 1.09 0 0 1-.287.4.603.603 0 0 1-.404.162Zm0-8.406c.43 0 .792-.148 1.087-.442.295-.295.442-.658.442-1.087 0-.43-.147-.792-.442-1.087a1.477 1.477 0 0 0-1.087-.442c-.43 0-.791.148-1.086.442a1.477 1.477 0 0 0-.442 1.087c0 .43.147.792.442 1.087a1.48 1.48 0 0 0 1.086.442Z"></path> 
77                                            </symbol> 
78                                            <use xlink:href="#ai:local:distance"></use> 
79                                        </svg> 
80                                        <#assign streetField = getFieldByName(content.contentFields, "street")> 
81                                        <#if streetField?has_content> 
82                                            <p>${streetField.contentFieldValue.data}</p> 
83                                        </#if> 
84                                    </div> 
85                                    <#assign codeField = getFieldByName(content.contentFields, "code")> 
86                                    <#assign dataHotel = ""> 
87                                    <#if codeField?has_content> 
88                                        <#assign dataHotel = "data-hotel='" + codeField.contentFieldValue.data + "'"> 
89                                        <div class="data__wrapper__footer d-none"> 
90                                            <p class="data__wrapper__footer__price"> 
91                                                <span class="price-line"> 
92                                                  Desde 
93                                                  <span ${dataHotel} class="price"></span> 
94                                                </span> 
95                                                 
96																								<#-- asigno subtitulo del precio --> 
97                                                 <#assign subtitleForPriceField = getFieldByName(content.contentFields, "subtitleForPrice")> 
98                                                 <#if subtitleForPriceField.contentFieldValue.data?has_content> 
99                                                     <#-- muestro subtitulo del precio (por defecto muestra "por persona") --> 
100                                                     <span class="extra-fees">${subtitleForPriceField.contentFieldValue.data!"por persona"}</span> 
101                                                 <#else> 
102                                                     <span class="extra-fees">por persona</span> 
103                                                 </#if> 
104                                            </p> 
105                                        </div> 
106                                    </#if> 
107                                </div> 
108                            </div> 
109                        </a> 
110                    <li> 
111                        </#list> 
112                </ul> 
113            </div> 
114        </div> 
115    </section> 
116</#if> 
117 
118<#function getFieldByName contentFields, name> 
119    <#list contentFields as field> 
120        <#if field.name == name> 
121            <#return field> 
122        </#if> 
123    </#list> 
124    <#return ""> 
125</#function> 
126 
127<script> 
128(function () { 
129    let hotelElements = [ 
130        <#list contents as content> 
131
132            <#assign nameField = getFieldByName(content.contentFields, "name")> 
133            <#if nameField?has_content> 
134                <#assign title = nameField.contentFieldValue.data> 
135            </#if> 
136            'title': '${title!""}', 
137 
138            <#assign codeField = getFieldByName(content.contentFields, "code")> 
139            <#if codeField?has_content> 
140                <#assign code = codeField.contentFieldValue.data> 
141            </#if> 
142            'code': '${code!""}', 
143            'price': 0, 
144            'index': ${content?index + 1}, 
145            <#assign categoryField = getFieldByName(content.contentFields, "category")> 
146            <#if categoryField?has_content> 
147                <#assign category = categoryField.contentFieldValue.data> 
148                <#attempt> 
149                    <#assign stars = category?split("*")[0]?number> 
150                <#recover> 
151                    <#assign stars = 0> 
152                </#recover> 
153            </#if> 
154            'stars': ${stars}, 
155            <#assign isCircuitField = getFieldByName(content.contentFields, "isCircuit")> 
156            <#if isCircuitField?has_content> 
157                <#assign isCircuit = isCircuitField.contentFieldValue.data> 
158            </#if> 
159            'isCircuit': ${isCircuit!""}, 
160						<#assign isCruiseField = getFieldByName(content.contentFields, "isCruise")> 
161            <#if isCruiseField?has_content> 
162            <#assign isCruise = isCruiseField.contentFieldValue.data> 
163            </#if> 
164            'isCruise': ${isCruise!""}, 
165						<#assign cruiseFeeDiscountField = getFieldByName(content.contentFields, "cruiseFeeDiscount")> 
166            <#assign cruiseFeeDiscountValue = 0> 
167            <#if cruiseFeeDiscountField?has_content> 
168                <#attempt> 
169                    <#assign cruiseFeeDiscountValue = cruiseFeeDiscountField.contentFieldValue.data?number> 
170                <#recover> 
171                    <#assign cruiseFeeDiscountValue = 0> 
172                </#recover> 
173            </#if> 
174            'cruiseFeeDiscount': ${cruiseFeeDiscountValue?int?abs}, 
175        }, 
176        </#list> 
177    ]; 
178    console.log(hotelElements); 
179    //let currentDestination = undefined; 
180		 
181  new Swiper(".our-accomodations__wrapper .swiper", { 
182    direction: 'horizontal', 
183    spaceBetween: 0, 
184    slidesPerView: 'auto', 
185    centeredSlides: true, 
186    breakpoints: { 
187      768: { 
188        allowTouchMove: false, 
189
190    }, 
191    navigation: { 
192      nextEl: '.swiper-button-next', 
193      prevEl: '.swiper-button-prev', 
194    }, 
195    pagination: { 
196      el: '.swiper-pagination', 
197    }, 
198    keyboard: { 
199      enabled: true, 
200      onlyInViewport: true, 
201    }, 
202  }); 
203 
204  async function fetchLiferayDocument(url) { 
205      return fetchLiferayApi("documents/d/guest/" + url); 
206
207 
208  function numberWithCommas (x){ 
209      return x.toFixed(Number.isInteger(x) ? 0 : 2).toString().replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, "."); 
210
211 
212  /* Ajustar el precio para cruceros para descontar las tasas que vienen incluidas en el datos desde API */ 
213  function getPriceExcludingCruiseFees(hotelApiData){ 
214    /*  
215      busco en los elementos globales el elemento [hotelElements] (hotel, circuito o crucero) que  
216      tenga el mismo código que el hotelApiData  
217    */ 
218    const code = +hotelApiData.code; 
219    const hotel = hotelElements.find(h => +h.code === code); 
220    const price = Number(hotelApiData.bestPrice); 
221    const cruiseFeeDiscount = Math.abs(Number(hotel?.cruiseFeeDiscount || 0)); 
222 
223    // Si no se encuentra hotel, no es crucero o el precio no es numerico, devolvemos el precio del API sin tocar 
224    if (!hotel || !hotel.isCruise || !Number.isFinite(price) ) return hotelApiData.bestPrice; 
225     
226    // Cruceros: el API trae tasas incluidas, las descontamos 
227    return price - cruiseFeeDiscount; 
228
229	 
230  async function loadHotelsPrice() { 
231      const hotelsResult = await fetchLiferayDocument("hotels"); 
232      const hotelsJson = await hotelsResult.json(); 
233 
234      const hotelElementsDom = document.querySelectorAll("span[data-hotel]"); 
235      hotelElementsDom.forEach(hotelElement => { 
236          const hotelCode = hotelElement.dataset.hotel; 
237          const hotel = hotelsJson.find(hotel => hotel.code === +hotelCode); 
238          if (!!hotel && !!hotel.bestPrice) { 
239              let updatedPrice = getPriceExcludingCruiseFees(hotel); 
240              hotelElement.innerText = numberWithCommas(updatedPrice) + "€"; 
241              //hotelElement.innerText = numberWithCommas(hotel.bestPrice) + "€"; 
242 
243              const parent = hotelElement.closest(".data__wrapper__footer"); 
244              parent.classList.remove("d-none"); 
245
246      }) 
247
248 
249  loadHotelsPrice(); 
250	 
251})(); //IIFE 
252 
253</script> 

Conoce Marruecos Norte

DESCARGAR ITINERARIO

Salidas desde Madrid. Consultar salidas desde otros aeropuertos.
​​​​​​

Marruecos, un país de antiguas tradiciones y pasado glorioso rodeado por interminables arenas. País exótico y espectacular que esconde paraísos al alcance de todos. Su mágica atmósfera y la pasión que irradia este reino con misterios y tesoros únicos distinguido por las influencias culturales bereberes, árabes y europeas. 

Conocido como la puerta a África, es un destino muy atractivo e interesante a orillas del océano Atlántico y el mar Mediterráneo. Se trata de un país con paisajes desérticos y montañosos que atesora una gran riqueza cultural e histórica. Las montañas del Alto Atlas y las dunas del Sáhara, forman un escenario ideal para los amantes de la naturaleza y un fascinante paisaje de fondo. Además, también encontrarás oasis, playas preciosas, costas escarpadas, cascadas y curiosas cuevas. Y por supuesto, no olvides degustar su deliciosa cocina y tomar un té.

INFORMACIÓN DE INTERÉS

Fuente

DOCUMENTACIÓN

Pasaporte con una vigencia mínimo de 6 meses.

CAMBIO

La divisa oficial es el dirham. Es muy aconsejable que el cambio de divisas lo hagas a través de los bancos y que utilices la tarjeta de crédito, para evitar elevadas comisiones. También es importante que conserves el resguardo de cambio de divisas para, así, evitar posibles problemas a tu vuelta.

VESTUARIO

La ropa más adecuada son prendas ligeras a ser posible de algodón o hilo, como pantalones cortos para el verano y algo de abrigo en invierno, además de impermeable para la época del invierno y el otoño. Incluye en tu equipaje calzado y ropa cómoda para las excursiones.

ELECTRICIDAD

La corriente eléctrica es de 220 voltios. Se utilizan enchufes de dos clavijas de estilo europeo y americano.

REFERENCIA HORARIA

- 1 horas hora Central de Europa (CET).

TELÉFONO

Código de acceso desde España: + 212
Código de acceso desde Marruecos: +34

"LOS IMPRESCINDIBLES" DE MARRUECOS

Casas azules

TÁNGER
Tánger es reconocida por su fuerte identidad multicultural, forjada a mitad del siglo pasado cuando fue distinguida como una gran ciudad cosmopolita y lugar de interés de numerosos artistas y demás gente influyente.

FEZ
La ciudad de Fez queda divida en tres zonas diferenciadas: Fez el-Jdid, lugar que aglutina el Mellah (nombre con el que se conoce a La Judería); la Ciudad Nueva, donde se estilan los cafés parisinos nacidos en los tiempos de la colonización y, especialmente, la Medina Fez-el Bali, la zona más antigua de la ciudad rodeada de murallas que alcanzan hasta los 15 kilómetros de extensión.

CASABLANCA
Casablanca, la ciudad más grande de Marruecos, es conocida como el corazón cosmopolita, industrial y económico del país. Además de ser un centro industrial y económico, Casablanca también cuenta con importantes atractivos turísticos, como la impresionante mezquita de Hassan II, la medina y el mercado central.

TETUÁN
La ciudad de Tetuán, en Marruecos, es una de las más interesantes del norte del país. Tiene una población que ronda los 400.000 habitantes y su medina histórica está reconocida como Patrimonio de la Humanidad por la Unesco, prueba de su belleza y singularidad, donde destacan murallas almenadas, jardines coloridos y rincones llenos de encanto.

Mercado

MARRAKECH
Marrakech es una antigua ciudad imperial en el oeste de Marruecos y un importante centro económico con mezquitas, palacios y jardines. La medina es una ciudad medieval amurallada y densamente poblada que data del período del Imperio Bereber, con pasajes que parecen laberintos y animados zocos (mercados) que venden cerámicas, joyas y tejidos tradicionales.

MEKNES
Meknes, es una ciudad de Marruecos que toma su nombre de la tribu bereber que la fundó con el nombre de Meknassi. Esta es una de las cuatro ciudades imperiales de Marruecos. llamada la ‘Versalles marroquí’, es una ciudad imperial con una gran cantidad de monumentos históricos y sitios naturales.

RABAT
Rabat, capital de Marruecos, se encuentra junto al río Bu Regreg y al océano Atlántico. Es famosa por los monumentos que reflejan su legado islámico y colonial francés. Ciudad cultural cargada de historia. Muchas obras maestras decoran sus calles y plazas.

CHEFCHAOUEN
Chefchaouen es una ciudad con un sello muy especial, además de estar construida en la ladera de una montaña. Pero si fascina tanto a los viajeros, es porque da una impresión de irrealidad. Las fachadas de sus casas están teñidas de azul y blanco, toda la ciudad parece estar bañada de azul. Caminas como si estuvieras en un sueño.