Les persones adultes poden estudiar idiomes moderns en modalitat presencial o semipresencial i també a distància a l'Institut Obert de Catalunya (IOC).
Formació en idiomes - Treball
Formació en idiomes
The following has evaluated to null or missing:
==> enlaces  [in template "5469721879361428997#20119#325716" at line 193, column 37]
----
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: ${enlaces}  [in template "5469721879361428997#20119#325716" at line 193, column 35]
----
	1<style> 
				2.results-list-formacio { 
				3    background: #fff; 
				4    border: 1px solid #CC5D27; 
				5    border-radius: 10px 30px 10px 10px; 
				6    display: flex; 
				7    flex-wrap: wrap; 
				8    padding: 20px; 
				9    padding-right: 40px; 
				10    position: relative; 
				11    row-gap: 20px; 
				12    transition: all 0.3s; 
				13    -webkit-transition: all 0.3s; 
				14} 
				15 
				16.select-label { 
				17    font-size: 1.5em; 
				18    /* Tamaño similar al de un h3 */ 
				19    font-weight: bold; 
				20    /* Negrita */ 
				21    margin-bottom: 10px; 
				22    /* Espacio debajo del label */ 
				23    display: block; 
				24    /* Asegura que el label esté en su propia línea */ 
				25} 
				26 
				27.result-info-formacio { 
				28    column-gap: 20px; 
				29    display: flex; 
				30    flex: 100%; 
				31} 
				32 
				33.load-more-btn { 
				34    background-color: #CC5D27; 
				35    color: #fff; 
				36    padding: 10px 20px; 
				37    border-radius: 5px; 
				38    text-decoration: none; 
				39    display: inline-block; 
				40    margin-top: 20px; 
				41} 
				42</style> 
				43<#if entries?has_content> 
				44    <#assign categoryList=[] /> 
				45    <!-- Recorremos todas las entradas para obtener sus categorías --> 
				46    <#list entries as entry> 
				47        <#assign categories=entry.getCategories()![] /> 
				48        <#if categories?has_content> 
				49            <#list categories as category> 
				50                <!-- Si la categoría no está en la lista, la agregamos --> 
				51                <#if category.getName() !="Enlaces" && category.getName() !="Formació Professional per l'ocupació" && category.getName() !="Document" && category.getName() !="Sistema de Qualificació Professional" && category.getName() !="Formacio Professional Especifica" && !(categoryList?seq_contains(category.getName()))> 
				52                    <#assign categoryList=categoryList + [category.getName()] /> 
				53                </#if> 
				54            </#list> 
				55        </#if> 
				56    </#list> 
				57		<#assign idioma = themeDisplay.getLocale().language /> 
				58		<#assign entriesSize=entries?size /> 
				59		<#assign selectLabel = "Escull una opció: " /> 
				60		<#assign select = "Seleccionar" /> 
				61		<#assign nonAvailableCategories = "No hi ha categories disponibles" /> 
				62		<#assign documentos = "Documents" /> 
				63		<#assign enlaces = "Enllaços" /> 
				64		<#assign masEnlaces = "Veure més enllaços" /> 
				65		<#assign de = "de" /> 
				66		<#if idioma == "es"> 
				67			<#assign selectLabel = "Escoge una opción: " /> 
				68			<#assign nonAvailableCategories = "No hay categorías disponibles" /> 
				69			<#assign documentos = "Documentos" /> 
				70			<#assign enlaces = "Enlaces" /> 
				71			<#assign masEnlaces = "Ver más enlaces" /> 
				72		<#elseif idioma == "en"> 
				73			<#assign selectLabel = "Choose an option: " /> 
				74			<#assign nonAvailableCategories = "No categories available" /> 
				75			<#assign select = "Select" /> 
				76			<#assign enlaces = "Links" /> 
				77			<#assign masEnlaces = "See more links" /> 
				78			<#assign de = "of" /> 
				79		</#if> 
				80    <!-- Mostrar el select con las categorías obtenidas --> 
				81    <div class="wrapper medium mb-4"> 
				82        <div class="results-list-formacio d-flex justify-content-center align-items-center"> 
				83            <label for="categorySelect" class="select-label mr-2 pt-2">${selectLabel}</label> 
				84            <select id="categorySelect"> 
				85                <option value="">${select}</option> 
				86                <#if categoryList?has_content> 
				87                    <#list categoryList as categoryName> 
				88                        <option value="${categoryName}"> 
				89                            ${categoryName} 
				90                        </option> 
				91                    </#list> 
				92                    <#else> 
				93                        <option value="">${nonAvailableCategories}</option> 
				94                </#if> 
				95            </select> 
				96        </div> 
				97    </div> 
				98    <!-- Mostrar Docuemntos --> 
				99    <div class="wrapper medium mt-3 mb-1" id="documents-section" style="display: none;"> 
				100        <h3 class="mb-3" id="title-form-documents"></h3> 
				101        <ul class="results-list-formacio" id="entries-list"> 
				102            <#list entries as curEntry> 
				103                <#assign assetRenderer=curEntry.getAssetRenderer() /> 
				104                <#assign assetObject=assetRenderer.getAssetObject() /> 
				105                <#assign categories=curEntry.getCategories()![] /> 
				106                <#assign hasDocumentCategory=false /> 
				107                <!-- Comprobamos si la entrada tiene la categoría "Document" --> 
				108                <#list categories as category> 
				109                    <#if category.getName()=="Document"> 
				110                        <#assign hasDocumentCategory=true /> 
				111                    </#if> 
				112                </#list> 
				113                <!-- Renderizamos solo los documentos con la categoría "Document" --> 
				114                <#if hasDocumentCategory> 
				115                    <li class="document-entry" data-categories="document"> 
				116                        <!-- Renderizar el artículo --> 
				117                        <#if (assetObject.getArticleId())??> 
				118                            <@liferay_journal["journal-article"] 
				119                                articleId=assetObject.getArticleId() 
				120                                ddmTemplateKey="160893" 
				121                                groupId=assetObject.getGroupId() /> 
				122                        </#if> 
				123                    </li> 
				124                </#if> 
				125            </#list> 
				126        </ul> 
				127    </div> 
				128    <!-- Mostrar las entradas --> 
				129    <#assign entriesSize=entries?size /> 
				130    <div class="wrapper medium mt-3"> 
				131        <h3 class="title-form-enlace" id="title-form-enlace"></h3> 
				132        <ul id="entries-list"> 
				133            <#list entries as curEntry> 
				134                <#assign assetRenderer=curEntry.getAssetRenderer() /> 
				135                <#assign assetObject=assetRenderer.getAssetObject() /> 
				136                <#assign categories=curEntry.getCategories()![] /> 
				137                <#assign entryCategoryNames=[] /> 
				138                <#list categories as category> 
				139                    <#assign entryCategoryNames=entryCategoryNames + [category.getName()] /> 
				140                </#list> 
				141                <#assign conditionalStyle="display:block;" /> 
				142                <#if (curEntry?counter>= 5)> 
				143                    <#assign conditionalStyle="display:none;" /> 
				144                </#if> 
				145                <li class="my-4 entry" style="display:none" data-categories="${entryCategoryNames?join(',')}"> 
				146                    <#if assetObject.getArticleId()??> 
				147                        <@liferay_journal["journal-article"] 
				148                            articleId=assetObject.getArticleId() 
				149                            ddmTemplateKey="161002" 
				150                            groupId=assetObject.getGroupId() /> 
				151                    </#if> 
				152                </li> 
				153            </#list> 
				154        </ul> 
				155        <div class="centered small-padding-bottom loadMoreBtn" style="display:none;"> 
				156            <a href="javascript:void(0);" class="button lm-button-white" style="width: 100%">${masEnlaces}</a> 
				157        </div> 
				158    </div> 
				159</#if> 
				160<script> 
				161document.addEventListener('DOMContentLoaded', function() { 
				162    let maxEntriesToShow = 5; 
				163    let currentCategory = ''; 
				164    const entries = document.querySelectorAll('.entry'); 
				165		const documentEntries = document.querySelectorAll('.document-entry'); 
				166    const loadMoreButton = document.querySelector('.loadMoreBtn'); 
				167    const titleElement = document.querySelector('.title-form-enlace'); 
				168		const documentsTitleElement = document.getElementById('title-form-documents'); 
				169    const categorySelect = document.getElementById('categorySelect'); 
				170    const documentsSection = document.getElementById('documents-section'); 
				171    // Función para filtrar y mostrar las entradas según la categoría seleccionada 
				172    function filterEntriesByCategory() { 
				173        const selectedCategory = categorySelect.value.toLowerCase(); 
				174        currentCategory = selectedCategory; 
				175        let matchingEntries = []; 
				176				let documentMatchingEntries = []; 
				177        // Ocultar todas las entradas inicialmente 
				178        entries.forEach(entry => entry.style.display = 'none'); 
				179        // Filtrar las entradas que coinciden con la categoría seleccionada 
				180        entries.forEach(entry => { 
				181            const entryCategories = entry.getAttribute('data-categories').split(','); 
				182            if (entryCategories.some(category => category.toLowerCase() === selectedCategory)) { 
				183                matchingEntries.push(entry); 
				184            } 
				185        }); 
				186				documentEntries.forEach(entry => { 
				187					documentMatchingEntries.push(entry); 
				188				}); 
				189        // Mostrar solo las primeras 5 entradas de la categoría seleccionada 
				190        matchingEntries.slice(0, maxEntriesToShow).forEach(entry => entry.style.display = 'block'); 
				191				documentMatchingEntries.slice(0, maxEntriesToShow).forEach(entry => entry.style.display = 'block'); 
				192        // Actualizar el título con el conteo de entradas visibles 
				193        titleElement.innerText = '${enlaces} (' + Math.min(maxEntriesToShow, matchingEntries.length) + ' ${de} ' + matchingEntries.length + ')'; 
				194				documentsTitleElement.innerText = '${documentos} (' + Math.min(maxEntriesToShow, documentMatchingEntries.length) + ' ${de} ' + documentMatchingEntries.length + ')'; 
				195        // Mostrar u ocultar el título 
				196        titleElement.style.display = matchingEntries.length > 0 ? 'block' : 'none'; 
				197				documentsTitleElement.style.display = matchingEntries.length > 0 ? 'block' : 'none'; 
				198        // Mostrar u ocultar el botón "Ver más" 
				199        loadMoreButton.style.display = matchingEntries.length > maxEntriesToShow ? 'block' : 'none'; 
				200    } 
				201    // Evento para cargar más entradas al hacer clic en "Ver más" 
				202    loadMoreButton.addEventListener('click', function() { 
				203        const matchingEntries = Array.from(entries).filter(entry => { 
				204            const entryCategories = entry.getAttribute('data-categories').split(','); 
				205            return entryCategories.some(category => category.toLowerCase() === currentCategory); 
				206        }); 
				207        // Mostrar las siguientes 5 entradas de la categoría seleccionada 
				208        const newEntriesToShow = maxEntriesToShow + 5; 
				209        matchingEntries.slice(maxEntriesToShow, newEntriesToShow).forEach(entry => entry.style.display = 'block'); 
				210        // Actualizar el conteo 
				211        maxEntriesToShow = newEntriesToShow; 
				212        titleElement.innerText = '${enlaces} (' + Math.min(maxEntriesToShow, matchingEntries.length) + ' ${de} ' + matchingEntries.length + ')'; 
				213        // Ocultar el botón si ya se han mostrado todas las entradas 
				214        if (maxEntriesToShow >= matchingEntries.length) { 
				215            loadMoreButton.style.display = 'none'; 
				216        } 
				217    }); 
				218    // Mostrar la sección de documentos solo si hay un valor seleccionado en el select 
				219    categorySelect.addEventListener('change', function() { 
				220        if (categorySelect.value) { 
				221            documentsSection.style.display = 'block'; 
				222        } else { 
				223            documentsSection.style.display = 'none'; 
				224        } 
				225        maxEntriesToShow = 5; 
				226        filterEntriesByCategory(); 
				227    }); 
				228    // Inicializar el filtro al cargar la página 
				229    filterEntriesByCategory(); 
				230}); 
				231</script>