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 Noruega

Noruega combina una deslumbrante naturaleza de fiordos y auroras boreales con una calidad de vida que la sitúa entre las más altas del planeta. Sus ciudades equilibran modernidad, diseño vanguardista y una vibrante oferta cultural con el respeto absoluto por su entorno natural.

Es el destino perfecto para quienes buscan explorar paisajes majestuosos, sumergirse en una rica historia vikinga y disfrutar de un ambiente acogedor, seguro y cosmopolita.

INFORMACIÓN DE INTERÉS

Bergen

DOCUMENTACIÓN

Los ciudadanos españoles precisan llevar el documento de identidad válido o pasaporte en vigor.

CAMBIO

La moneda oficial es la Corona Noruega o Kroner.

VESTUARIO

Se aconseja ropa y calzado cómodo, apropiados para la estación del año en la que se visite.

ELECTRICIDAD

230 voltios.

REFERENCIA HORARIA

Se aplica la hora Central de Europa (CET), misma que en España.

TELÉFONO

Código de acceso desde España: + 47
Código de acceso desde Noruega: +34

"LOS IMPRESCINDIBLES" DE NORUEGA

Fiordo de Sogn

OSLO
Oslo, capital de Noruega, es una pequeña ciudad que ha sabido crecer sin perder sus señas de identidad, llegando a convertirse en una de las capitales más bellas de Europa. Aunque se trata de una ciudad muy moderna, aún conserva la magia de los pequeños pueblos y desde el centro de la ciudad es posible llegar hasta un bosque en cuestión de minutos.

LILLEHAMMER
La zona de Lillehammer se encuentra aproximadamente dos horas por carretera al norte de Oslo. La localidad es famosa por haber acogido los Juegos olímpicos de invierno en 1994. La zona, con montañas, ríos y el lago más grande de Noruega, es un auténtico paraíso para realizar actividades al aire libre.

REGIÓN DE GELIO
Geilo es un pequeño pueblo de montaña de unos 2500 habitantes, a mitad de camino entre Oslo y Bergen. Se encuentra en un valle con cordilleras montañosas a cada lado, y viajando en tren desde su estación resulta una experiencia inolvidable por su increíble paisaje. Es conocido por su estación de esquí en invierno, y tiene otras actividades como senderismo, ciclismo y pesca en verano. ¡Te gustará!.

Pueblo

 

BORGUND
Borgund es conocido principalmente por su famosa iglesia de madera, la Borgund Stave Church, que es una de las mejor conservadas de Noruega. Esta iglesia, construida en el siglo XII, es un excelente ejemplo de la arquitectura de iglesias de estacas, con su distintivo diseño en forma de barco y elaborados detalles decorativos. El entorno natural que rodea a Borgund es igualmente impresionante, con montañas y paisajes típicos de Noruega que ofrecen oportunidades para el senderismo y la exploración. Además, el área tiene un ambiente tranquilo y pintoresco, ideal para quienes buscan escapar del bullicio de la vida urbana.

STAVANGER/ZONA DE SOLA
Es la cuarta ciudad más grande de Noruega y es conocida como la capital del petróleo por su importancia en la exploración de petróleo, capital de la cultura y la gastronomía, famosa por su arte callejero … es una acogedora ciudad con mucho que ofrecer. Calles adoquinadas, una catedral de casi 900 años de antigüedad, «Fargegaten» (la calle colorida), y un casco antiguo con el asentamiento de casas de madera mejor conservado de Europa, que incluye más de 170 casas, muchas de las cuales datan del s. XVIII. En 2008 Stavanger fue designada Capital Europea de la Cultura, lo que refleja la gran variedad de eventos culturales y actividades en la región.

Restaurante sobre el río

 

FIORDOS DE LOS SUEÑOS
La región de los fiordos en Noruega es uno de los destinos turísticos más demandados. Esta región es un icono de la belleza natural del norte de Europa. alberga ciudades con una historia y cultura dignas de conocer con una excelente gastronomía y ambiente nocturno.

ZONA ASERAL
Aseral se encuentra en la región de Agder y es conocido por su hermosa naturaleza, incluyendo montañas y lagos. Es un lugar ideal para disfrutar de actividades al aire libre como senderismo y pesca.

BERGEN
La conocida «puerta de los fiordos», con un centro histórico envidiable además de contar con el barrio de Bryggen, patrimonio mundial de la UNESCO, y por su animada vida cultural. Bergen siempre ha tenido carácter propio y por eso ha sido capaz de mantener toda su esencia y toda su historia pese a seguir siendo la segunda localidad con más habitantes de Noruega. Bucear por sus calles, es una auténtica delicia.