Estoy tratando de usar Pug para generar una lista de datos basada en datos de otro archivo .js. Mi problema es averiguar cómo hacer que Pug lea este objeto javascript
Actualmente tengo un archivo WizardSpells.js con los siguientes datos:
// wizardSpells.js const wiz1 = {}; wiz1['Affect Normal Fires'] = {'school': 'Alteration'}; wiz1['Alarm'] = {'school': 'Abjuration, Evocation'}; wiz1['Armor'] = {'school': 'Conjuration'};
Aquí está el contenido de mi archivo datalist.pug:
//datalist.pug datalist(id='wiz1-spells') each val, key in wiz1 option(value=val.school) key
El error que recibo cuando intento compilar el archivo pug en HTML es el siguiente:
TypeError: .\pug\datalists.pug:2 1| datalist(id='wiz1-spells') > 2| each val, key in wiz1 3| option(value=val.school) key Cannot read property 'length' of undefined
Mi problema claramente es que mi objeto javascript no está definido en el archivo datalist.pug.
¿Cómo hago para que Pug acceda a mi archivo javascript y al objeto javascript? Preferiría una solución que no edite el archivo WizardSpells.js y mantenga todos los cambios dentro del archivo datalists.pug.
información adicional
npm install pug-cli
pug .\pug\datalists.pug -o ./html -P
Tengo todos los archivos disponibles localmente en mi máquina, por lo que no es necesaria una red o una gran configuración. Todo lo que necesito que haga Pug es leer el archivo local y usarlo para generar resultados.
Tienes que exportar el objeto de wizardSpells.js
para poder acceder a él.
// wizardSpells.js const wiz1 = {}; wiz1['Affect Normal Fires'] = {'school': 'Alteration'}; wiz1['Alarm'] = {'school': 'Abjuration, Evocation'}; wiz1['Armor'] = {'school': 'Conjuration'}; module.exports = { wiz1 };
Alternativamente, no use el paquete pug-cli
, use el paquete pug
en su lugar y genere la salida HTML desde NodeJS directamente.
// build.js const pug = require('pug'); const wizardSpells = require('./wizardSpells.js'); const html = pug.renderFile('datalist.pug', wizardSpells); console.log(html);
Usando la respuesta anterior logré que funcionara. Mi configuración final se ve así:
// wizardSpells.js const wiz1 = {}; wiz1['Affect Normal Fires'] = {'school': 'Alteration'}; wiz1['Alarm'] = {'school': 'Abjuration, Evocation'}; wiz1['Armor'] = {'school': 'Conjuration'}; module.exports = wiz1;
El objeto javascript wiz1
se exporta directamente sin ningún objeto contenedor.
// build.js const pug = require('pug'); const fs = require('fs'); const wiz1= require('./wizardSpells.js'); const html = pug.renderFile('../src/datalist.pug', {pretty: true, wiz1: wiz1}); fs.writeFileSync('datalist.html', html);
Tuve que instalar Pug localmente en mi proyecto, npm install pug
(note que no hay bandera -g) para que la función require()
funcione.
Envío el objeto wiz1
a pug en la línea pug.renderFile()
, pero parece que pug no puede servir el "objeto raíz" para la iteración, y solo se puede acceder a las propiedades del objeto raíz. Por lo tanto, envuelvo el objeto wiz1
en otro objeto, y también agrego el indicador pretty: true
para obtener HTML bien sangrado.
Esto ahora me permite acceder al objeto wiz1
en mi archivo pug:
// datalist.pug datalist(id='wiz1-spells') each val, key in wiz1 option(value=val.school)= key
Para ejecutar todo uso el siguiente comando: node build.js
El HTML final se ve así:
<datalist id="wiz1-spells"> <option value="Alteration">Affect Normal Fires</option> <option value="Abjuration, Evocation">Alarm</option> <option value="Conjuration">Armor</option> </datalist>
Nota: como también uso el wizardSpells.js
como contenido para mi HTML final, tengo un paso de procesamiento posterior que elimina la línea module.export
, antes de la inserción, para evitar que rompa el javascript cuando se agrega al HTML y se carga mediante el navegador.