-50% de descuento* Si compras la misma norma UNE en distintos idiomas. * Dto. sobre el pvp inferior. Ver condiciones

ISO/IEC 29341-4-13:2011

Information technology — UPnP Device Architecture — Part 4-13: Audio Video Device Control Protocol — Level 2 — Rendering Control Service

Fecha edición: 2011-09-15
En Vigor
Idiomas disponibles: Inglés
ICS: 35.200 - Equipos de interfaz y de interconexión
CTN: 45020

Anulaciones Normas

Anula a ISO/IEC 29341-4-13:2008

Normas Conjuntas

Trabajo conjunto ISO/IEC 29341-4-13:2011

Otras Relaciones

Adoptada de UIC

Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> channelResponse.items  [in template "34352066712900#33336#null" at line 6, column 20]

----
Tip: It's the step after the last dot 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 channel = channelResponse.ite...  [in template "34352066712900#33336#null" at line 6, column 1]
----
1<#-- Variables --> 
2<#assign isDebug = false> 
3<#assign channelResponse = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?filter=name eq 'Aenor Tienda'")> 
4<#assign channel = channelResponse.items[0]> 
5<#assign channelId = channel.id> 
6<#assign product = getProduct(channelId, CPDefinition_cProductId.getData()) /> 
7<#assign siteGroup = themeDisplay.getSiteGroup() /> 
8<#assign currentLocale = themeDisplay.getLocale()> 
9<#assign currentLanguage = currentLocale?substring(0,2)> 
10 
11<#-- Product data --> 
12<#assign displayDateProduct = CPDefinition_displayDate.getData() /> 
13<#assign productId = product.productId /> 
14<#assign cpDefinitionId = product.id /> 
15 
16<#assign categoriesProduct = getProductCategories(channelId, productId) /> 
17<#assign hasProductCategoriaTipoEntidadLibro = isVocabularyNameIntoCategories(categoriesProduct, 'entity type', 'libro') /> 
18<#assign hasProductCategoriaTipoEntidadNorma = isVocabularyNameIntoCategories(categoriesProduct, 'entity type', 'norma') /> 
19<#assign hasProductCategoriaTipoEntidadColeccionTematica = isVocabularyNameIntoCategories(categoriesProduct, 'entity type', 'coleccion tematica') /> 
20<#assign categoryProductInfoTematica = getCategoriesByVocabularyAsString(categoriesProduct, "temáticas", " / ", "title") /> 
21<#assign categoryProductInfoStatus = getCategoriesByVocabularyAsString(categoriesProduct, "status", " / ", "title") /> 
22 
23<#-- PickList de languages --> 
24<#assign ercOfListTypeEntryLanguages = 'IDIOMAS_NORMAS_PICKLIST' /> 
25<#assign languageEntries = getListTypeEntriesByERC(ercOfListTypeEntryLanguages) /> 
26 
27<#-- Specifications/Specifications language --> 
28<#assign specificationsLanguagesProduct = getSpecificationsProduct(channelId, productId, 'specificationKey', 'standard-languages') /> 
29<#assign filteredSpecificationsLanguagesProductTemp = filterOutItems(specificationsLanguagesProduct, 'value', ['BI', 'TR']) /> 
30<#assign filteredSpecificationsLanguagesProduct = addAllMatchingLanguagesByField(filteredSpecificationsLanguagesProductTemp, languageEntries, 'value', 'title') /> 
31 
32<#-- Thematic collection/Coleccion tematica data --> 
33<#assign thematicCollectionsProduct = getThematicCollectionProduct(cpDefinitionId) /> 
34 
35 
36<#-- Functions --> 
37<#function getProduct channelId productId> 
38    <#return restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${channelId}/products/${productId}")> 
39</#function> 
40 
41 
42<#function getProductByERC erc> 
43    <#-- TODO: estamos usando el endpoint del product admin, hay que usar la del Product de Liferay NO admin: headless-commerce-delivery-catalog --> 
44    <#-- <#return restClient.get("/headless-commerce-admin-catalog/v1.0/products/by-externalReferenceCode/${erc}")> --> 
45    <#assign response = restClient.get("/headless-commerce-admin-catalog/v1.0/products/by-externalReferenceCode/${erc}")> 
46    <#-- Si el producto no existe o tiene status NOT_FOUND, devolvemos string vacío --> 
47    <#if response?? && response.status?? && response.status == "NOT_FOUND"> 
48        <#return {}> 
49    <#elseif !response??> 
50        <#return {}> 
51    <#else> 
52        <#return response> 
53    </#if> 
54</#function> 
55 
56 
57<#function getURLsOfProduct product baseURL="" siteFriendlyURL="" languageFieldName="language" urlFieldName="url"> 
58    <#-- Inicializamos un array vacío --> 
59    <#assign urlsArray = []> 
60 
61    <#-- Validamos que product y product.urls existan --> 
62    <#if product?? && product.urls??> 
63        <#-- Iteramos sobre los idiomas --> 
64        <#list product.urls?keys as lang> 
65            <#assign urlValue = product.urls[lang] /> 
66            <#if urlValue?? && urlValue?has_content> 
67                <#-- Aseguramos que la URL empiece con "/p/" --> 
68                <#assign cleanUrl = urlValue?starts_with("/")?then(urlValue, "/p/" + urlValue) /> 
69 
70                <#-- Generamos la URL completa --> 
71                <#-- Si baseURL tiene contenido, construimos URL completa --> 
72                <#if baseURL?? && baseURL?has_content> 
73 
74                    <#-- Aseguramos que el slug empiece con /p/ --> 
75                    <#assign cleanUrl = urlValue?starts_with("/")?then(urlValue, "/p/" + urlValue) /> 
76 
77                    <#-- Tomamos las dos primeras letras del idioma para el prefijo --> 
78                    <#assign langPrefix = lang?substring(0,2)> 
79 
80                    <#-- Construimos la URL completa --> 
81                    <#if siteFriendlyURL?? && siteFriendlyURL?has_content> 
82                        <#assign fullUrl = baseURL + "/" + langPrefix + siteFriendlyURL + cleanUrl> 
83                    <#else> 
84                        <#assign fullUrl = baseURL + "/" + langPrefix + cleanUrl> 
85                    </#if> 
86 
87                <#else> 
88                    <#assign fullUrl = cleanUrl> 
89                </#if> 
90 
91                <#-- Creamos el objeto language+url --> 
92                <#assign newItem = {(languageFieldName): lang, (urlFieldName): fullUrl} /> 
93 
94                <#-- Lo agregamos al array --> 
95                <#assign urlsArray = urlsArray + [newItem] /> 
96            </#if> 
97        </#list> 
98    </#if> 
99 
100    <#return urlsArray> 
101</#function> 
102 
103 
104<#function getProductCategories channelId productId> 
105    <#return restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${channelId}/products/${productId}/categories?sort=vocabulary").items> 
106</#function> 
107 
108 
109<#function getSpecificationsProduct channelId productId field="" value=""> 
110    <#assign response = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${channelId}/products/${productId}/product-specifications?pageSize=100&sort")> 
111    <#assign items = response.items> 
112 
113    <#-- Si se pasa campo y valor, filtrar --> 
114    <#if field?has_content && value?has_content> 
115        <#assign items = items?filter(item -> 
116            (item[field]??) && (item[field]?string?lower_case == value?lower_case) 
117        )> 
118    </#if> 
119 
120    <#return items> 
121</#function> 
122 
123 
124<#function filterOutItems items field valuesToExclude> 
125    <#-- Si el array o los valores no existen, devolver items sin cambios --> 
126    <#if !items?? || !valuesToExclude??> 
127        <#return items> 
128    </#if> 
129 
130    <#-- Filtramos: solo mantener los items cuyo campo no esté en la lista --> 
131    <#assign filteredItems = items?filter(item -> 
132        !(item[field]?? && (valuesToExclude?seq_contains(item[field]?string))) 
133    )> 
134 
135    <#return filteredItems> 
136</#function> 
137 
138 
139<#function addAllMatchingLanguagesByField specificationsLanguagesProduct languageEntries specValueField newSpecField> 
140 
141    <#if specificationsLanguagesProduct?? && languageEntries?? && specValueField?? && newSpecField??> 
142 
143        <#-- Creamos una copia para no modificar el original directamente --> 
144        <#assign updatedSpecs = []> 
145 
146        <#list specificationsLanguagesProduct as spec> 
147            <#-- Buscar coincidencia --> 
148            <#assign keyValue = spec[specValueField]> 
149            <#assign match = languageEntries?filter(entry -> entry.key == keyValue)?first> 
150 
151            <#-- Crear una copia del objeto actual --> 
152            <#assign newSpec = spec> 
153 
154            <#-- Si hay match con nombre válido, añadir el nuevo campo --> 
155            <#if match?? && match.name?? && match.name?has_content> 
156                <#assign newSpec = newSpec + { (newSpecField): match.name }> 
157            </#if> 
158 
159            <#-- Añadir al array final --> 
160            <#assign updatedSpecs = updatedSpecs + [newSpec]> 
161        </#list> 
162 
163        <#return updatedSpecs> 
164    <#else> 
165        <#return specificationsLanguagesProduct> 
166    </#if> 
167</#function> 
168 
169 
170<#function getListTypeEntriesByERC erc fields="key,name,externalReferenceCode,name_i18n" sort="key" pageSize="1000"> 
171    <#attempt> 
172        <#return restClient.get( 
173            "/headless-admin-list-type/v1.0/list-type-definitions/by-external-reference-code/${erc}/list-type-entries?fields=${fields}&sort=${sort}&pageSize=${pageSize}" 
174        ).items> 
175    <#recover> 
176        <#return []> 
177    </#attempt> 
178</#function> 
179 
180 
181<#function getThematicCollectionProduct cpDefinitionId> 
182    <#assign response = restClient.get("/c/thematiccollections/?filter=r_thematicCollection_CPDefinitionId eq '${cpDefinitionId}'")!{} /> 
183    <#assign items = response.items![] /> 
184    <#return (items?size > 0)?then(items[0], {}) /> 
185</#function> 
186 
187 
188<#function sortByField items fieldPath sortFieldName="sortKey" order="asc"> 
189 
190    <#-- Array temporal con el campo auxiliar --> 
191    <#assign prepared = []> 
192 
193    <#list items as e> 
194        <#-- Evaluar el valor del campo dinámico --> 
195        <#assign sortValue = "" /> 
196        <#if fieldPath == "section?first.key"> 
197            <#assign sortValue = (e.section?first.key)!""?lower_case> 
198        <#elseif fieldPath == "section?first.name"> 
199            <#assign sortValue = (e.section?first.name)!""?lower_case> 
200        <#elseif fieldPath == "type?first.key"> 
201            <#assign sortValue = (e.type?first.key)!""?lower_case> 
202        <#else> 
203            <#-- Si el campoPath no está mapeado, usar vacío --> 
204            <#assign sortValue = "" /> 
205        </#if> 
206 
207        <#-- Agregar objeto enriquecido con campo auxiliar --> 
208        <#assign prepared = prepared + [ e + { (sortFieldName): sortValue } ]> 
209    </#list> 
210 
211    <#-- Ordenar --> 
212    <#assign sorted = prepared?sort_by(sortFieldName)> 
213 
214    <#-- Si order = desc, invertir --> 
215    <#if order?lower_case == "desc"> 
216        <#assign sorted = sorted?reverse> 
217    </#if> 
218 
219    <#return sorted> 
220</#function> 
221 
222 
223<#function addKeysFieldNested items arrayField nestedField newFieldName mode="first" subArrayField=""> 
224 
225    <#assign enrichedItems = []> 
226 
227    <#list items as e> 
228        <#assign resultValue = ""> 
229 
230        <#-- Detectamos el array del objeto principal --> 
231        <#assign targetArray = e[arrayField]![]> 
232 
233        <#if targetArray?has_content> 
234            <#if mode == "all"> 
235                <#assign keysList = []> 
236                <#list targetArray as t> 
237                    <#if subArrayField?has_content> 
238                        <#assign subArray = t[subArrayField]![]> 
239                        <#if subArray?has_content> 
240                            <#list subArray as sub> 
241                                <#assign keysList = keysList + [ sub[nestedField]!"" ]> 
242                            </#list> 
243                        </#if> 
244                    <#else> 
245                        <#assign keysList = keysList + [ t[nestedField]!"" ]> 
246                    </#if> 
247                </#list> 
248                <#assign resultValue = keysList?join(", ")> 
249            <#elseif mode == "first"> 
250                <#assign firstItem = targetArray?first> 
251                <#if subArrayField?has_content> 
252                    <#assign subArray = firstItem[subArrayField]![]> 
253                    <#if subArray?has_content> 
254                        <#assign resultValue = subArray?first[nestedField]!"" > 
255                    <#else> 
256                        <#assign resultValue = "" > 
257                    </#if> 
258                <#else> 
259                    <#assign resultValue = firstItem[nestedField]!"" > 
260                </#if> 
261            </#if> 
262        <#else> 
263            <#assign resultValue = ""> 
264        </#if> 
265 
266        <#-- Añadimos el nuevo campo al objeto --> 
267        <#assign enrichedItems = enrichedItems + [ 
268            e + { (newFieldName): resultValue } 
269        ]> 
270    </#list> 
271 
272    <#return enrichedItems> 
273</#function> 
274 
275 
276<#function isVocabularyNameIntoCategories categories vocabulary name> 
277    <#assign found = false /> 
278 
279    <#if categories?has_content && vocabulary?has_content && name?has_content> 
280 
281        <#assign vocabNorm = normalize(vocabulary) /> 
282        <#assign nameNorm  = normalize(name) /> 
283 
284        <#list categories as category> 
285            <#if !found> 
286                <#assign catVocabNorm = normalize(category.vocabulary) /> 
287                <#assign catNameNorm  = normalize(category.name) /> 
288 
289                <#if catVocabNorm == vocabNorm && catNameNorm == nameNorm> 
290                    <#assign found = true /> 
291                </#if> 
292            </#if> 
293        </#list> 
294 
295    </#if> 
296 
297    <#return found> 
298</#function> 
299 
300 
301<#function normalize text onlyAccents = false> 
302    <#-- proteger null --> 
303    <#if !text?has_content> 
304        <#return ""> 
305    </#if> 
306 
307    <#assign t = text /> 
308 
309    <#-- quitar acentos --> 
310    <#assign t = t 
311        ?replace("á","a")?replace("é","e")?replace("í","i") 
312        ?replace("ó","o")?replace("ú","u")?replace("ü","u") 
313        ?replace("ñ","n") 
314        ?replace("Á","A")?replace("É","E")?replace("Í","I") 
315        ?replace("Ó","O")?replace("Ú","U")?replace("Ü","U") 
316        ?replace("Ñ","N") 
317    /> 
318 
319    <#-- si NO es solo acentos, normalización completa --> 
320    <#if !onlyAccents> 
321        <#assign t = t?lower_case /> 
322        <#assign t = t?trim /> 
323        <#assign t = t?replace("\\s+", " ", "r") /> 
324    </#if> 
325 
326    <#return t> 
327</#function> 
328 
329 
330<#-- Función que retorna los valores de categorías como string, normalizando vocabulario --> 
331<#function getCategoriesByVocabularyAsString categories vocabulary separator=" / " field="name"> 
332    <#assign matchedValues = []> 
333    <#if categories?has_content && vocabulary?has_content> 
334        <#list categories as category> 
335            <#-- Normalizamos tanto el vocabulary de la categoría como el buscado --> 
336            <#if normalize(category.vocabulary, true)?lower_case == normalize(vocabulary, true)?lower_case> 
337                <#if field == "title"> 
338                    <#assign matchedValues += [category.title]> 
339                <#else> 
340                    <#assign matchedValues += [category.name]> 
341                </#if> 
342            </#if> 
343        </#list> 
344    </#if> 
345    <#return matchedValues?join(separator)> 
346</#function> 
347 
348 
349<#macro printObject obj> 
350    <#-- Permite hacer un output de un array de objetos o un objeto que se pasa como parámetro --> 
351    <#if obj?is_hash> 
352
353        <#list obj?keys as k> 
354            "${k}": 
355            <#assign value = obj[k]> 
356            <#if value?is_hash || value?is_sequence> 
357                <@printObject obj=value/> 
358            <#elseif value?is_boolean> 
359                ${value?c} 
360            <#elseif value?is_number> 
361                ${value} 
362            <#elseif value?has_content> 
363                "${value?string}" 
364            <#else> 
365                null 
366            </#if> 
367            <#if k_has_next>, </#if> 
368        </#list> 
369
370    <#elseif obj?is_sequence> 
371
372        <#list obj as item> 
373            <@printObject obj=item/> 
374            <#if item_has_next>, </#if> 
375        </#list> 
376
377    <#elseif obj?is_boolean> 
378        ${obj?c} 
379    <#elseif obj?is_number> 
380        ${obj} 
381    <#elseif obj?has_content> 
382        "${obj?string}" 
383    <#else> 
384        null 
385    </#if> 
386</#macro> 
387 
388 
389 
390 
391<#-- HTML --> 
392<#if hasProductCategoriaTipoEntidadColeccionTematica> 
393    <div id="ecom-coleccion_tematica-detail" class="ecom-coleccion_tematica"> 
394 
395        <div class="tabs-section"> 
396            <div class="tab-content"> 
397 
398                <#-- Fecha edicion del producto > description del Producto --> 
399                <div class="ecom-coleccion_tematica-detail-body"> 
400                    ${product.description} 
401                </div> 
402 
403                <#-- Para imprimir el contenido de los Objects --> 
404                <#-- Thematic collection/Coleccion tematica data 
405                <#if isDebug> 
406                    <div class=""> 
407                        <p><strong>thematicCollectionsProduct:</strong></p> 
408                        <div class="print-object-json-content mb-3" style="max-height:200px; overflow:auto; border:1px solid #ccc; padding:5px; cursor:pointer;" 
409                             onclick="const r=document.createRange(); r.selectNodeContents(this); const s=window.getSelection(); s.removeAllRanges(); s.addRange(r);"> 
410                            <@printObject thematicCollectionsProduct /> 
411                        </div> 
412                    </div> 
413                 </#if> 
414                 --> 
415 
416            </div> 
417        </div> 
418    </div> 
419</#if> 

El libro en palabras del autor

Ultricies magna feugiat malesuada sociosqu varius vivamus cubilia parturient, himenaeos vitae vehicula nam placerat netus urna platea, nostra rutrum felis mattis penatibus velit quisque.

Button
Preguntas frecuentes ¿Tienes alguna duda sobre nuestros productos?

Respuesta 2

Desde la web

Libros y normas