page jade ejemplos condicionales compile javascript node.js pug

javascript - ejemplos - jade npm



¿Cómo pasar una variable de un archivo de plantilla de jade a un archivo de script? (5)

Estoy teniendo problemas con una variable (config) declarada en un archivo de plantilla de jade (index.jade) que no se pasa a un archivo javascript, lo que hace que mi javascript se cuelgue. Aquí está el archivo (views / index.jade):

h1 #{title} script(src=''./socket.io/socket.io.js'') script(type=''text/javascript'') var config = {}; config.address = ''#{address}''; config.port = ''#{port}''; script(src=''./javascripts/app.js'')

Aquí hay una parte de mi app.js (lado del servidor):

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + ''/public'')); }); app.configure(''development'', function(){ app.set(''address'', ''localhost''); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure(''production'', function(){ app.use(express.errorHandler()); }); // Routes app.get(''/'', function(req, res){ res.render(''index'', { address: app.settings.address, port: app.settings.port }); }); if (!module.parent) { app.listen(app.settings.port); console.log("Server listening on port %d", app.settings.port); } // Start my Socket.io app and pass in the socket require(''./socketapp'').start(io.listen(app));

Y aquí hay una parte de mi archivo Javascript que se bloquea (public / javascripts / app.js):

(function() { var socket = new io.Socket(config.address, {port: config.port, rememberTransport: false});

Estoy ejecutando el sitio en modo de desarrollo (NODE_ENV = desarrollo) en localhost (mi propia máquina). Estoy usando node-inspector para la depuración, que me dijo que la variable de configuración no está definida en public / javascripts / app.js.

¿¿Algunas ideas?? ¡¡Gracias!!


Así es como me dirigí a esto (usando un derivado MEAN)

Mis variables:

{ NODE_ENV : development, ... ui_varables { var1: one, var2: two } }

Primero tuve que asegurarme de que se estaban pasando las variables de configuración necesarias. MEAN usa el paquete node nconf y, de forma predeterminada, está configurado para limitar qué variables pasan del entorno. Tuve que remediar eso:

config / config.js:

original:

nconf.argv() .env([''PORT'', ''NODE_ENV'', ''FORCE_DB_SYNC''] ) // Load only these environment variables .defaults({ store: { NODE_ENV: ''development'' } });

después de las modificaciones:

nconf.argv() .env(''__'') // Load ALL environment variables // double-underscore replaces : as a way to denote hierarchy .defaults({ store: { NODE_ENV: ''development'' } });

Ahora puedo configurar mis variables así:

export ui_varables__var1=first-value export ui_varables__var2=second-value

Nota: Restablecí el "indicador de jerarquía" a "__" (doble guión bajo) porque su valor predeterminado era ":", lo que hace que las variables sean más difíciles de configurar desde bash. Ver otra publicación en este hilo.

Ahora, la parte de jade: a continuación, se deben representar los valores, de modo que javascript pueda recogerlos en el lado del cliente. Una forma sencilla de escribir estos valores en el archivo de índice. Como esta es una aplicación de una página (angular), esta página siempre se carga primero. Creo que idealmente debería ser un archivo de inclusión de JavaScript (solo para mantener las cosas limpias), pero esto es bueno para una demostración.

app / controllers / index.js:

''use strict''; var config = require(''../../config/config''); exports.render = function(req, res) { res.render(''index'', { user: req.user ? JSON.stringify(req.user) : "null", //new lines follow: config_defaults : { ui_defaults: JSON.stringify(config.configwriter_ui).replace(/<///g, ''<///'') //NOTE: the replace is xss prevention } }); };

app / views / index.jade:

extends layouts/default block content section(ui-view) script(type="text/javascript"). window.user = !{user}; //new line here defaults = !{config_defaults.ui_defaults};

En mi html renderizado, esto me da un pequeño y agradable script:

<script type="text/javascript"> window.user = null; defaults = {"var1":"first-value","var2:"second-value"}; </script>

A partir de este punto, es fácil para angular utilizar el código.


En mi caso, estaba intentando pasar un objeto a una plantilla a través de una ruta rápida (similar a la configuración de OP). Luego, quería pasar ese objeto a una función a la que llamaba mediante una etiqueta de script en una plantilla de pug. Aunque la respuesta de lagginreflex me acercó, terminé con lo siguiente:

script. var data = JSON.parse(''!{JSON.stringify(routeObj)}''); funcName(data)

Esto aseguró que el objeto se pasó como se esperaba, en lugar de tener que deserializar en la función. Además, las otras respuestas parecían funcionar bien con las primitivas, pero cuando las matrices, etc. pasaban junto con el objeto, se analizaban como valores de cadena.


Es un poco tarde pero ...

script. loginName="#{login}";

Esto está funcionando bien en mi script. En Express, estoy haciendo esto:

exports.index = function(req, res){ res.render( ''index'', { layout:false, login: req.session.login } ); };

¿Supongo que el último jade es diferente?

Merc.

editar: agregado "." después de la secuencia de comandos para evitar la advertencia de Jade.


Vea esta pregunta: JADE + EXPRESS: ¿Iteración sobre el objeto en el código JS en línea (del lado del cliente)?

Estoy teniendo el mismo problema. Jade no pasa variables locales en (o hace ninguna plantilla en absoluto) a las secuencias de comandos de JavaScript, simplemente pasa todo el bloque en texto literal. Si usa las variables locales ''dirección'' y ''puerto'' en su archivo Jade encima de la etiqueta del script, deberían aparecer.

Las soluciones posibles se enumeran en la pregunta a la que he vinculado anteriormente, pero puede: - pasar todas las líneas como texto sin guardar (! = Al comienzo de cada línea), y simplemente poner "-" antes de cada línea de javascript que usa un variable local, o: - Pasa las variables a través de un elemento dom y accede a través de JQuery (feo)

¿No hay mejor manera? Parece que los creadores de Jade no quieren soporte javascript de líneas múltiples, como lo muestra este hilo en GitHub: https://github.com/visionmedia/jade/pull/405


!{} es para la interpolación de !{} protegido, que es más adecuado para objetos

script var data = !{JSON.stringify(data).replace(/<///g, ''<///'')} { foo: ''bar'' } // becomes: <script>var data = {"foo":"bar"}</script> { foo: ''bar</script><script>alert("xss")//'' } // becomes: <script>var data = {"foo":"bar<//script><script>alert(/"xss/")//"}</script>

La idea es evitar que el atacante:

  1. Salir de la variable: JSON.stringify escapa de las comillas
  2. Salir de la etiqueta del script: si el contenido de la variable (que no se puede controlar si proviene de la base de datos, por ejemplo) tiene una cadena </script> , la instrucción replace se encargará de ello

https://github.com/pugjs/pug/blob/355d3dae/examples/dynamicscript.pug

#{} es para la #{} escapadas, que solo es adecuada si está trabajando con cadenas. No funciona con objetos

script var data = #{JSON.stringify(data)} //=> <script>var data = {&quot;foo&quot;:&quot;bar&quot;}</script>