jueves, 20 de noviembre de 2014

Como instalar Yeoman junto con Grunt + Bower además utilizar PHP

De muchos es conocido herramientas como Yeoman, Grunt y Bower y son herramientas que nos ayuda a comenzar un nuevo proyecto con plantillas predefinidas de grandes proyectos como plantillas predefinidas como HTML5 Bolierplate, Twitter Bootstrap, que nos agilizara mucho como para trabajar en nuestros desarrollos front-end de manera moderna y dinámica, con ellos construiremos un árbol web muy completo después de ejecutar unos comandos de consola crearemos inmediatamente el esqueleto de nuestra futura aplicación web y para el ejemplo además usaremos PHP.

Para quien no lo sepa con estos generadores nos van a realizar las tareas como la de crear estructuras, compilar automáticamente sass y lees, optimizar imágenes, crear diferentes entonos, realizar test y largo etc.. vamos cualquier tarea que sea repetitiva, además de refrescar automáticamente tu navegador gracias al Livereload, lo mas complicado entre comillas es hacer una buena configuración para ellos, claro con estos gestores tan frontales no vamos a poder ejecutar código PHP, sin antes configurarlo como veremos después.

Empecemos por el principio:

Yeoman

Es un generador que hace uso de Bower y Grunt, su dos grandes aliados. Yeoman tiene una gran lista de generador para que construya una gran base por nosotros.

Bower

Nos sirve para el manejo de las dependencias de nuestros proyectos, se ejecuta desde la línea de comandos y su configuración se crea en un archivo llamado bower.json luego desde el terminal ejecutaremos sus comandos y tendremos descargados los paquetes que hayamos elegido en nuestro local.

Grunt

Es una herramienta para automatizar acciones o procesos, como minimizar css y js, compilar less o sass, ejecución de pruebas, construcción y otra infinidad de tareas, se configura através de dos archivos Packaged.json (donde listaremos las dependencias) y Grunt.js (donde crearemos la configuración), existe un gran numero de plugins en su repositorio puedes encontrar de todo tipo de acciones que se pueden ajustar a diferentes necesidades.

PHP

Que voy a contar de PHP que no sepas…


Un poco de diversión comenzaremos con las instalaciones:

Antes de nada decirte que ahora mismo solo lo puedes hacer en Linux y Mac, tal vez algún dia lo tenga para el Windows pero no mola nada, mucho mejor te va a funcionar en un linux, así que seamos profesionales y utilicemos sistemas profesionales, tienes que tener instalado previamente Node.js y Ruby.

Aquí unos links para que te sirvan de ayuda:

https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-on-centos-6-with-rvm
http://www.nodeclipse.org/2013/08/30/Node.js-installation-on-CentOS-Linux.html
http://codybonney.com/installing-node-js-0-10-24-on-centos-6-4/


La siguiente te instalara Yoeman Grunt y Bower, PHP doy por hecho que ya lo tienes instalado, además de que estas utilizando un usuario con privilegios para hacer las instalaciones:


$ npm install -g yo grunt-cli bower

Ahora una vez instalado nuestros generadores, lo suyo es utilizar un usuario de linux que sea normal que vamos a utilizar para nuestro proyecto y no sea root, con la siguiente instrucción veremos un listado y elegiremos un generador para así crearemos un nuevo proyecto web, se puede usar otros comandos para hacer uso de otros generadores mas específicos de Yeoman.


$ yo

mostrara los siguente:



? 'Allo! What would you like to do?
  
  Update your generators
  Install a generator
  Find some help
--------------
  Run a generator
  Polymer
  Angular ? Update Available!
? Bootstrap Less
  Karma
  Php



Nosotros ahora vamos elegir el de Boostrap Less por que es la que me resulta mas operativa para configurar ese proyecto para hacer funcionar Grunt y PHP a la vez.

Hacer esta elección para configurar Grunt y PHP nos va a producir una salida por consola similar a esta:

? 'Allo! What would you like to do? Bootstrap Less

Make sure you are in the directory you want to scaffold into.
This generator can also be run with: yo bootstrap-less


     _-----_
    |       |    .--------------------------.
    |--(o)--|    |    Welcome to Yeoman,    |
   `---------´   |   ladies and gentlemen!  |
    ( _´U`_ )    '--------------------------'
    /___A___\
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

Out of the box I include HTML5 Boilerplate, Bootstrap with less, and a Gruntfile.js to build your app.
? What more would you like? Bootstrap Javascript files, FontAwesome
   create Gruntfile.js
   create package.json
 conflict .gitignore
? Overwrite .gitignore? overwrite
    force .gitignore
   create .gitattributes
 conflict .bowerrc
? Overwrite .bowerrc? overwrite
    force .bowerrc
   create bower.json
 conflict .jshintrc
? Overwrite .jshintrc? overwrite
    force .jshintrc
 conflict .editorconfig
? Overwrite .editorconfig? overwrite
    force .editorconfig
   create app/favicon.ico
   create app/404.html
   create app/robots.txt
   create app/.htaccess
   create app/styles/main.less
   create app/index.html
   create app/scripts/hello.coffee
   create app/scripts/main.js
   invoke   mocha


I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try running the command yourself.


   create     test/bower.json
   create     test/.bowerrc
   create     test/spec/test.js
   create     test/index.html
bower modernizr#~2.6.2          cached git://github.com/Modernizr/Modernizr.git#2.6.3
bower modernizr#~2.6.2        validate 2.6.3 against git://github.com/Modernizr/Modernizr.git#~2.6.2
bower chai#~1.8.0               cached git://github.com/chaijs/chai.git#1.8.1
bower chai#~1.8.0             validate 1.8.1 against git://github.com/chaijs/chai.git#~1.8.0
bower jquery#~1.9.1             cached git://github.com/jquery/jquery.git#1.9.1
bower jquery#~1.9.1           validate 1.9.1 against git://github.com/jquery/jquery.git#~1.9.1
bower mocha#~1.14.0             cached git://github.com/visionmedia/mocha.git#1.14.0
bower mocha#~1.14.0           validate 1.14.0 against git://github.com/visionmedia/mocha.git#~1.14.0
bower bootstrap#~3.0.0          cached git://github.com/twbs/bootstrap.git#3.0.3
bower bootstrap#~3.0.0        validate 3.0.3 against git://github.com/twbs/bootstrap.git#~3.0.0
bower font-awesome#~4.0.0       cached git://github.com/FortAwesome/Font-Awesome.git#4.0.3
bower font-awesome#~4.0.0     validate 4.0.3 against git://github.com/FortAwesome/Font-Awesome.git#~4.0.0
bower chai#~1.8.0              install chai#1.8.1
bower mocha#~1.14.0            install mocha#1.14.0

chai#1.8.1 bower_components/chai

mocha#1.14.0 bower_components/mocha
bower modernizr#~2.6.2         install modernizr#2.6.3
bower font-awesome#~4.0.0      install font-awesome#4.0.3
bower jquery#~1.9.1            install jquery#1.9.1
bower bootstrap#~3.0.0         install bootstrap#3.0.3

modernizr#2.6.3 app/bower_components/modernizr

font-awesome#4.0.3 app/bower_components/font-awesome

jquery#1.9.1 app/bower_components/jquery

bootstrap#3.0.3 app/bower_components/bootstrap
+-- jquery#1.9.1
npm WARN package.json grunt/php@0.0.0 No description
npm WARN package.json grunt/php@0.0.0 No repository field.
npm WARN package.json grunt/php@0.0.0 No README data
/
> phantomjs@1.9.12 install /var/www/html/grunt/php/node_modules/grunt-mocha/node_modules/grunt-lib-phantomjs/node_modules/phantomjs
> node install.js

Download already available at /tmp/phantomjs/phantomjs-1.9.8-linux-x86_64.tar.bz2
Extracting tar contents (via spawned process)
Removing /var/www/html/grunt/php/node_modules/grunt-mocha/node_modules/grunt-lib-phantomjs/node_modules/phantomjs/lib/phantom
Copying extracted folder /tmp/phantomjs/phantomjs-1.9.8-linux-x86_64.tar.bz2-extract-1416474106615/phantomjs-1.9.8-linux-x86_64 -> /var/www/html/grunt/php/node_modules/grunt-mocha/node_modules/grunt-lib-phantomjs/node_modules/phantomjs/lib/phantom
Removing /tmp/phantomjs/phantomjs-1.9.8-linux-x86_64.tar.bz2-extract-1416474106615
Writing location.js file
Done. Phantomjs binary available at /var/www/html/grunt/php/node_modules/grunt-mocha/node_modules/grunt-lib-phantomjs/node_modules/phantomjs/lib/phantom/bin/phantomjs

> pngquant-bin@1.0.1 postinstall /var/www/html/grunt/php/node_modules/grunt-contrib-imagemin/node_modules/imagemin/node_modules/imagemin-pngquant/node_modules/pngquant-bin
> node lib/install.js

     fetch : https://raw.github.com/imagemin/pngquant-bin/v1.0.1/vendor/linux/x64/pngquant
  progress : [====================] 100% 0.0s

? pre-build test failed, compiling from source...
? pngquant failed to build, make sure that libpng-dev is installed

{ [Error: Command failed: make: *** No hay ninguna regla para construir el objetivo `config.mk', necesario para `lib/libimagequant.a'.  Alto.
] killed: false, code: 2, signal: null }

> jpegtran-bin@1.0.2 postinstall /var/www/html/grunt/php/node_modules/grunt-contrib-imagemin/node_modules/imagemin/node_modules/imagemin-jpegtran/node_modules/jpegtran-bin
> node lib/install.js

     fetch : https://raw.github.com/imagemin/jpegtran-bin/v1.0.2/vendor/linux/x64/jpegtran
  progress : [====================] 100% 0.0s

? pre-build test passed successfully!

> gifsicle@1.0.3 postinstall /var/www/html/grunt/php/node_modules/grunt-contrib-imagemin/node_modules/imagemin/node_modules/imagemin-gifsicle/node_modules/gifsicle
> node lib/install.js

     fetch : https://raw.github.com/imagemin/gifsicle-bin/v1.0.3/vendor/linux/x64/gifsicle
  progress : [====================] 100% 0.0s

? pre-build test passed successfully!

> optipng-bin@1.0.1 postinstall /var/www/html/grunt/php/node_modules/grunt-contrib-imagemin/node_modules/imagemin/node_modules/imagemin-optipng/node_modules/optipng-bin
> node lib/install.js

     fetch : https://raw.github.com/imagemin/optipng-bin/v1.0.1/vendor/linux/x64/optipng
  progress : [====================] 100% 0.0s

? pre-build test failed, compiling from source...
? optipng built successfully!
grunt-rev@0.1.0 ../node_modules/grunt-rev

grunt-contrib-clean@0.6.0 ../node_modules/grunt-contrib-clean
+-- rimraf@2.2.8

grunt-concurrent@1.0.0 ../node_modules/grunt-concurrent
+-- pad-stdio@1.0.0 (lpad@1.0.0)
+-- async@0.9.0

time-grunt@1.0.0 ../node_modules/time-grunt
+-- date-time@1.0.0
+-- figures@1.3.5
+-- text-table@0.2.0
+-- pretty-ms@1.0.0 (parse-ms@1.0.0, get-stdin@3.0.0)
+-- hooker@0.2.3
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)

grunt-contrib-copy@0.6.0 ../node_modules/grunt-contrib-copy
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)

jshint-stylish@1.0.0 ../node_modules/jshint-stylish
+-- log-symbols@1.0.1
+-- text-table@0.2.0
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
+-- string-length@1.0.0 (strip-ansi@2.0.0)

grunt-contrib-concat@0.5.0 ../node_modules/grunt-contrib-concat
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)
+-- source-map@0.1.40 (amdefine@0.1.0)

grunt-contrib-coffee@0.11.1 ../node_modules/grunt-contrib-coffee
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
+-- coffee-script@1.7.1 (mkdirp@0.3.5)
+-- lodash@2.4.1

grunt-contrib-watch@0.6.1 ../node_modules/grunt-contrib-watch
+-- async@0.2.10
+-- tiny-lr-fork@0.0.5 (debug@0.7.4, faye-websocket@0.4.4, noptify@0.0.3, qs@0.5.6)
+-- gaze@0.5.1 (globule@0.1.0)
+-- lodash@2.4.1

grunt-usemin@2.4.0 ../node_modules/grunt-usemin
+-- debug@1.0.4 (ms@0.6.2)
+-- lodash@2.4.1

load-grunt-tasks@0.6.0 ../node_modules/load-grunt-tasks
+-- multimatch@0.3.0 (array-differ@0.1.0, array-union@0.1.0, minimatch@0.3.0)
+-- findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.1)

matchdep@0.3.0 ../node_modules/matchdep
+-- stack-trace@0.0.7
+-- resolve@0.5.1
+-- globule@0.1.0 (minimatch@0.2.14, glob@3.1.21, lodash@1.0.1)
+-- findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.1)

grunt-contrib-htmlmin@0.3.0 ../node_modules/grunt-contrib-htmlmin
+-- pretty-bytes@0.1.2
+-- chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)
+-- html-minifier@0.6.9 (change-case@2.1.5, relateurl@0.2.5, clean-css@2.2.18, cli@0.6.5, uglify-js@2.4.15)

grunt-contrib-connect@0.8.0 ../node_modules/grunt-contrib-connect
+-- connect-livereload@0.4.1
+-- open@0.0.5
+-- async@0.9.0
+-- portscanner@0.2.3 (async@0.1.15)
+-- connect@2.19.6 (parseurl@1.0.1, response-time@2.0.0, escape-html@1.0.1, pause@0.0.1, cookie-signature@1.0.3, cookie@0.1.2, vhost@1.0.0, fresh@0.2.2, qs@0.6.6, basic-auth-connect@1.0.0, on-headers@0.0.0, bytes@1.0.0, morgan@1.1.1, serve-favicon@2.0.1, errorhandler@1.0.2, cookie-parser@1.1.0, connect-timeout@1.1.0, body-parser@1.3.1, method-override@2.0.2, debug@1.0.2, express-session@1.2.1, csurf@1.2.1, type-is@1.2.1, compression@1.0.7, serve-static@1.2.3, multiparty@3.2.8, serve-index@1.1.1)

grunt@0.4.5 ../node_modules/grunt
+-- dateformat@1.0.2-1.2.3
+-- which@1.0.5
+-- eventemitter2@0.4.14
+-- getobject@0.1.0
+-- rimraf@2.2.8
+-- colors@0.6.2
+-- async@0.1.22
+-- grunt-legacy-util@0.2.0
+-- hooker@0.2.3
+-- nopt@1.0.10 (abbrev@1.0.5)
+-- exit@0.1.2
+-- minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
+-- glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
+-- lodash@0.9.2
+-- coffee-script@1.3.3
+-- underscore.string@2.2.1
+-- iconv-lite@0.2.11
+-- findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.1)
+-- grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.1)
+-- js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)

grunt-svgmin@1.0.0 ../node_modules/grunt-svgmin
+-- log-symbols@1.0.1
+-- pretty-bytes@1.0.1 (get-stdin@1.0.0)
+-- each-async@1.1.0 (onetime@1.0.0, setimmediate@1.0.2)
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
+-- svgo@0.4.5 (colors@0.6.2, whet.extend@0.9.9, coa@0.4.1, sax@0.6.1, js-yaml@2.1.3)

grunt-contrib-uglify@0.6.0 ../node_modules/grunt-contrib-uglify
+-- uri-path@0.0.2
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)
+-- uglify-js@2.4.15 (uglify-to-browserify@1.0.2, async@0.2.10, optimist@0.3.7, source-map@0.1.34)
+-- lodash@2.4.1
+-- maxmin@1.0.0 (figures@1.3.5, pretty-bytes@1.0.1, gzip-size@1.0.0)

grunt-contrib-cssmin@0.10.0 ../node_modules/grunt-contrib-cssmin
+-- chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)
+-- clean-css@2.2.18 (commander@2.2.0)
+-- maxmin@0.2.2 (figures@1.3.5, pretty-bytes@0.1.2, chalk@0.5.1, gzip-size@0.2.0)

grunt-contrib-jshint@0.10.0 ../node_modules/grunt-contrib-jshint
+-- hooker@0.2.3
+-- jshint@2.5.10 (strip-json-comments@1.0.2, underscore@1.6.0, exit@0.1.2, minimatch@1.0.0, console-browserify@1.1.0, shelljs@0.3.0, cli@0.6.5, htmlparser2@3.8.2)

grunt-mocha@0.4.11 ../node_modules/grunt-mocha
+-- lodash@2.3.0
+-- mocha@1.18.2 (diff@1.0.7, growl@1.7.0, commander@2.0.0, mkdirp@0.3.5, debug@2.1.0, glob@3.2.3, jade@0.26.3)
+-- grunt-lib-phantomjs@0.4.0 (eventemitter2@0.4.14, semver@1.0.14, temporary@0.0.8, phantomjs@1.9.12)

grunt-contrib-less@0.11.4 ../node_modules/grunt-contrib-less
+-- async@0.2.10
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)
+-- maxmin@0.1.0 (pretty-bytes@0.1.2, chalk@0.4.0, gzip-size@0.1.1)
+-- lodash@2.4.1
+-- less@1.7.5 (graceful-fs@3.0.4, mime@1.2.11, clean-css@2.2.18, source-map@0.1.40, mkdirp@0.5.0, request@2.40.0)

grunt-contrib-imagemin@0.8.1 ../node_modules/grunt-contrib-imagemin
+-- pretty-bytes@1.0.1 (get-stdin@1.0.0)
+-- async@0.9.0
+-- chalk@0.5.1 (escape-string-regexp@1.0.2, ansi-styles@1.1.0, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
+-- imagemin@1.0.5 (get-stdin@3.0.0, stat-mode@0.2.0, ware@0.3.0, nopt@3.0.1, tempfile@1.1.0, fs-extra@0.11.1, imagemin-svgo@1.0.2, imagemin-pngquant@1.0.2, imagemin-jpegtran@1.0.0, imagemin-gifsicle@1.0.0, imagemin-optipng@1.0.0)


     _-----_
    |       |    .---------------------------------------.
    |--(o)--|    |        Bye from us! Chat soon.        |
   `---------´   |                                       |
    ( _´U`_ )    |            The Yeoman Team            |
    /___A___\    | https://github.com/yeoman/yeoman#team |
     |  ~  |     '---------------------------------------'
   __'.___.'__
 ´   `  |° ´ Y ` 


Podremos ver que nos ha creado la siguiente estructura, donde podemos observar que nos ha creado los archivos de configuración de Grunt y de Bower, más la carpeta con la aplicación y otra con plugins de Grunt, también son llamados contribs



Ahora llega el momento de la configuración para esto vamos a hacer uso del archivo Gruntfile.js, pero antes de hacer la configuración de PHP en Grunt, voy a contar las partes que interesante tiene este fichero y deberíamos saber identificar.

Función contenedora:


 module.exports = function(grunt) {
    // el resto de codigo 
};

Objeto de configuración del proyecto:


grunt.initConfig({
    // dentro ira la configuración de tareas

    less: {
      dist: {
        files: {
          '<%= yeoman.app %>/styles/main.css': ['<%= yeoman.app %>/styles/main.less']
        },
        options: {
          sourceMap: true,
          sourceMapFilename: '<%= yeoman.app %>/styles/main.css.map',
          sourceMapBasepath: '<%= yeoman.app %>/',
          sourceMapRootpath: '/'
        }
      }
    },
  
  Mastareas... 
 
};

El registro de Tareas, lleva 2 parámetros el primero es el nombre que después será el que utilizaremos para ejecutar dicha tarea, el segundo es un array y incluiremos las tareas que serán ejecutadas.


grunt.registerTask('test', [
    'coffee',
    'less',
  ]);

Ahora si ejecutásemos el código de abajo, la tarea “test” llamaría al objeto de la configuración para realizar los procesos configurados en el, que son los de coffee y less. También tener en cuenta que se pueden crear tareas que llamen a otras tareas, como ejemplo podríamos crear un objeto que se llamase “multiple-test” y este a su vez llamase a “test” y a otras tareas que le indicásemos.


grunt test

Hasta ahora ya hemos dados los primeros pasos y hemos hecho uso de Yeoman, Grunt y Bower si te has dado cuenta cada uno ha cumplido su función según lo que contaba al principio y ya que tenemos instalado todo vamos a probar, puede que antes necesites como yo que cambiar en Gruntfile.js. en las opciones de conect, el puerto y el hostname.


grunt server

Con este comando que necesitaras ejecutar con un user con privilegios, nos creara todos las tareas y nos arrancara el servidor web en mi caso ya que cambie el hostname y el puerto podré ver el resultado en 192.168.1.52:9008 será como esta:



Si nuestro proyecto front-end no necesita paginas dinámicas PHP con esto nos bastaria para comenzar un desarrollo, utilizando HTML5, Bootstrap y Font Awesome, pero podemos ir incluyendo contribs según vayamos necesitando, podéis encontrar plugins de Grunt en el link que dejo, son muy sencillas de instalar, también dejo un enlace que explica cómo se hace por si surge alguna duda, aunque para Grunt-PHP vamos a hacer la instalación de una contrib.

http://gruntjs.com/plugins 
http://blog.grayghostvisuals.com/grunt/image-optimization/

Como usar PHP junto a Grunt


Para poder integrar PHP en el servidor de Grunt vamos a tener que conectar con un marco middleware, primeramente el instalaremos plugin connect-php


npm install connect-php

Una vez instalado, vamos a requerir utilizar connect-php y se lo asignaremos a una variable, podemos insertar esto al principio del Gruntfile.js


var miphp = require('connect-php');

Sin más rodeos, ahora vamos a incluir nuestro middleware, para hacerlo esto deberemos hacerlo dentro de Grant.initConfig a su vez en el connect creando la función dentro de la propiedad middleware:


grunt.initConfig({
  ...
  connect: {
    options: {
      ......
      middleware: function(connect, options) {
  var mymiddleware = [];
  var dir = options.directory ||
    options.base[options.base.length - 1];
  if (!Array.isArray(options.base)) {
    options.base = [options.base];
  }

  mymiddleware.push(miphp(dir));

  options.base.forEach(function(base) {
    mymiddleware.push(connect.static(base));
  });

  mymiddleware.push(connect.directory(dir));
  return mymiddleware;
}
    },
    ...
  }
});

Si hemos realizado todo bien ahora puedes cambiar el archivo de dentro app/index.html por index.php y volver a ejecutar grunt server y entrar en la url 192.168.1.52:9008/index.php entonces podéis ver que funciona perfectamente  

domingo, 3 de noviembre de 2013

Como redireccionar a un usuario hacia una pagina usando con jQuery

Para saber como redireccionar a un usuario hacia una pagina usando jQuery es muy sencillo

$(window).attr("location","http://jquerytotal.blogspot.com.es");

Aunque jQuery no es necesario y usando

window.location.replace(url) 

En Javascript será mejor simular una redirección HTTP. Y en javascript es mejor que usar

window.location.href = url 

porque replace () el usuario no se queda bloqueado en un sin fin. Si desea simular que alguien hace clic en un enlace, utiliza mejor location.href. Si desea simular una redirección HTTP, utiliza location.replace.

martes, 13 de agosto de 2013

Como usar MYSQL desde la consola de Linux

Accede por medio de la consola o terminal de linux y administra a MySQL esto en algunas ocasiones nos puede venir muy bien aparte de ser mas rapido cuando usemos en ciertas operaciones

Para entrar en MySQL usaremos el siguiente comando

#  mysql -h localhost -u usuario -p password

ahora sabremos que estamos dentro ya que veremos lo siguiente:

mysql >

Aqui dejo algunos comandos útiles para MySQL y manejo el de bases de datos.

show databases; - Listar todas las bases de datos.
drop [database]; - borrar la base de datos.
create [database]; - crear la base de datos.
connect [database]; - Conectarse a esa base de datos.
show tables; - Listar todas las tablas de una base de datos.
show table status; - Muestra informacion sobre las tablas de la base de datos.
describe [table]; - Muestra la estructura de una tabla de la base de datos.

Verificacion y reparacion de errores en las bases de datos Mysql :

check table [table]; - Verificar la tabla.
repair table [table]; - Reparar la tabla rota.

Manejo de bases de datos Mysql :

drop table [table]; - Elimina la tabla, incluyendo registros y estructura.
drop table if exists [table]; - Elimina la tabla de la base de datos, pero antes verifica que exista.
truncate table [table]; - Elimina los registros, pero mantiene la esrtuctura de la tabla.
rename table [table] to [nuevo nombre de tabla]; - Renombra una tabla de la base de datos.

Bases de datos Mysql en consola del sistema operativo linux:

# mysqladmin -u -p create - crear base de datos.
# mysqladmin -u -p drop - borrar la base de datos.
# mysqladmin -u root -p proc - listar procesos en ejecucion en el servidor de bases de datos Mysql.
# mysqladmin -u root -p -i 5 status - verificar status cada 5 segundos.
# mysqldump --opt -u -h -p > /path/to/file - Exportar base de datos a un archivo.
# mysqldump --opt -u -h --all-databases -p > /path/to/file - Exportar TODAS las bases de datos a un archivo.
# mysql -h -u -p < /path/to/file - Importar un archivo a la base de datos a mysql
# mysqlcheck -o -u root -p --all-databases - Optimizar las bases de datos mysql.
en GNU/Linu

Exportar base de datos por consola:

mysqldump -h IP -u USER -p – -default-character-set=utf8 NOMBASEDATOS > ARCHIVO.sql

Donde:
IP: IP servidor MYSQL
USER: usuario que tiene permisos para acceder a a base de datos.
NOMBASEDATOS: Nombre de la base de datos que se quiere EXPORTAR.
ARCHIVO: nombre del fichero .sql que va a contener todo el backup.

Importar base de datos por consola:
Desde la misma consola, existen 2 maneras:

1. Todo en una sola línea.
mysql -h IP -u USER -p - -default-character-set=utf8 NOMBASEDATOS < ARCHIVO.sql

2. Entrando al mysql.
#Nos conectamos al servidor
mysql -h IP -u USER -p

# Creamos la base de datos.
create database NOMBREDB

#Le decimos al MYSQL que base de datos vamos a usar.
use NOMBREDB

#Le damos la ubicación de nuestro archivo .sql.
source /ruta/archivo/sql/archivo.sql

miércoles, 6 de marzo de 2013

PHP Internal Server Error o Fatal error: Maximum execution time

Si estas ejecutando un código en php que resulta ser un bucle muy largo y tarda mucho tiempo en completarse tal vez te salgan errores como Fatal error: Maximum execution o el maravilloso 500 Internal Server Error

El problema es que el tiempo de ejecución que tienes por defecto es una kaka el límite suele estar predeterminado a 30 para cambiar ese tiempo máximo de ejecución cambiar estas variables en el php.ini


max_execution_time = 300 ;
max_input_time = 250 ;


Cambiando estas variables se establece el número de segundos que se permite la ejecución de un script. Si esto se alcanza, el script devuelve un error fatal.

Modifica las variables por consola en


sudo nano /etc/php5/apache2/php.ini
sudo nano /etc/php5/cli/php.ini


y luego


sudo /etc/init.d/apache2 restart


Si te quedas corto juega con las cifras tal vez no es muy recomendable darle un valor excesivamente grande pero en algunos casos puede ser totalmente correcto

jueves, 31 de enero de 2013

MongoDB Error: couldn't connect to server - mongo.js:91 exception: connect failed

Como resolver este problema en MongoDB es sencillo - Error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js:91


Primer paso borrar el archivo bloqueado

sudo rm /var/lib/mongodb/mongod.lock


Segundo paso reparar mongodb

mongod --repair



Iniciar MongoDB

sudo start mongodb


Checkear el estado de MongoDb

sudo status mongodb



Y empezar
Start mongo console.



MongoDB como Instalar configurar el driver MongoDB en Ubuntu

Para instalar en linux muy facil primero
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0C


Añadir al sources.list
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen


Updateamos e instalamos 
sudo apt-get -y update
sudo apt-get -y install mongodb-10gen


Instalando el Driver MongoDB y PHP, puede ser que necesites instalar perl

sudo apt-get install php-pear
sudo pecl install mongo


ahora añadir en el php.ini y reiniciar los servicios tendremos mongodb instalado en nuestra maquina
extension=mongo.so


Controlando los servicios de arrancar parar restaurar

sudo service mongodb start
sudo service mongodb stop
sudo service mongodb restart
sudo service mongodb status



Archivo de configuración de MongoDB
sudo nano /etc/mongodb.conf


Comando para ejecutar MongoDB al arrancar o reiniciar el servidor
chkconfig --levels 235 mongodb on
chkconfig mongod on

viernes, 7 de octubre de 2011

Redirigir de un dominio a otro usando .htaccess

Este es el codigo para redirigir de un dominio a otro usando .htaccess


# El sitio se ha mudado permanentemente a otro dominio
# sitioviejo.com a sitionuevo.com
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.sitioviejo.com$ [NC]
RewriteRule ^(.*)$ http://www.sitionuevo.com/$1 [R=301,L]

jueves, 9 de junio de 2011

Jquery mostrar ver videos en todos los navegadores (firefox o IE) y en moviles esto si es crossbrowsing

Existe varios plugins jQuery con los que podemos ver videos en cualquier navegador ya sea firefox o IE en casi todas las versiones y el resto de navegadores, el funcionamiento de este plugin consiste en detectar el navegador que es, para asi generar el codigo del video para después reproducirlo en formato mp4 o swf, lo cierto es que es una solución genial y supervalida, tambien se van visionar los vídeos en telefonos moviles.

Aqui el ejemplo de muestra


Dentro del head

<script src="jquery.js"></script>
<script src="mediaelement.js"></script>
<script src="mediaelementplayer.js"></script>
<link href="mediaelementplayer.css" rel="Stylesheet" />


En el body


<span id="player1-mode"></span>


<video width="640" height="360" id="player2" poster="../media/echo-hereweare.jpg" controls="controls" preload="none">
<!-- MP4 source must come first for iOS -->
<source type="video/mp4" src="../media/echo-hereweare.mp4" />
<!-- WebM for Firefox 4 and Opera -->
<source type="video/webm" src="../media/echo-hereweare.webm" />
<!-- OGG for Firefox 3 -->
<source type="video/ogg" src="../media/echo-hereweare.ogv" />

<!-- Fallback flash player for no-HTML5 browsers with JavaScript turned off -->
<object width="640" height="360" type="application/x-shockwave-flash" data="../build/flashmediaelement.swf">
<param name="movie" value="../build/flashmediaelement.swf" />
<param name="flashvars" value="controls=true&file=../media/echo-hereweare.mp4" />
<!-- Image fall back for non-HTML5 browser with JavaScript turned off and no Flash player installed -->
<img src="../media/echo-hereweare.jpg" width="640" height="360" alt="Here we are"
title="No video playback capabilities" />
</object>
</video>

<span id="player2-mode"></span>

<script>

$('audio,video').mediaelementplayer({
success: function(player, node) {
$('#' + node.id + '-mode').html('mode: ' + player.pluginType);
}
});

</script>

<input type="button" id="stopall" value="Stop all">

<script>
$('#stopall').click(function() {
$('video, audio').each(function() {
$(this)[0].player.pause();
});
});
</script>


Para descargar los archivos aqui



jueves, 19 de mayo de 2011

Como detectar y redireccionar un iPod iPhone Ipad mediante codigo Javascript

Vamos a ver como usando una lineas de codigo javascript podemos detectar si es un dispositivo iPod iPad o iPhone y lo redireccionaremos a la version movil de nuestro site, para ello vamos a crear una pequeña función para detectarlos.



function esApple(){
return (
(navigator.platform.indexOf("iPhone") != -1) ||
(navigator.platform.indexOf("iPod") != -1) ||
(navigator.platform.indexOf("iPad") != -1)
);
}
if(esApple()){
window.location = "dominio.mobi";
}



Así con este código podremos redireccionar a los visitantes de nuestra web a la versión correcta para sus iPod iPhone e Ipad sin que tengan que andar dando vueltas.

lunes, 9 de mayo de 2011

Como crear un border css redondeado que se vea bien en todos los navegadores

Si quiereis saber como crear un border css redondeado que se vea bien en todos los navegadores ademas sin utilizar imagenes solo con css y la ayuda de un ficherito, pero bueno ya debes de saber que con firefox usando el prefijo -moz va bien y con el resto de navegadores menos internet explorer con -webkit tambien funciona perfecto.

Bueno dejo la el link para tener bordes css redondeados y que se vea en todos los exploradores

http://code.google.com/p/curved-corner/

martes, 19 de abril de 2011

Manipular cookies en javascript

Aqui dejo unas buenos metodos para manipular cookies en javascript que son un poco tediosas y esto es algo que funciona a la perfeccion:

Clase cookie en javascript para manipularlas
var Cookie = {
set: function(name,value,seconds){
if(seconds){
d = new Date();
d.setTime(d.getTime() + (seconds * 1000));
expiry = '; expires=' + d.toGMTString();
}else
expiry = '';
document.cookie = name + "=" + value + expiry + "; path=/";
},
get: function(name){
nameEQ = name + "=";
ca = document.cookie.split(';');
for(i = 0; i < ca.length; i++){ c = ca[i]; while(c.charAt(0) == ' ') c = c.substring(1,c.length); if(c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null }, unset: function(name){ Cookie.set(name,'',-1); } }




Posibles usos de la clase

Cookie.set('nombre','valor', 86400);
Cookie.unset('nombre');



Otra solucion para manipular cookies pero esta vez mediante una funcion javascript

function getCookie( name ) {
var start = document.cookie.indexOf( name + "=" );
var len = start + name.length + 1;
if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
return null;
}
if ( start == -1 ) return null;
var end = document.cookie.indexOf( ';', len );
if ( end == -1 ) end = document.cookie.length;
return unescape( document.cookie.substring( len, end ) );
}

function setCookie( name, value, expires, path, domain, secure ) {
var today = new Date();
today.setTime( today.getTime() );
if ( expires ) {
expires = expires * 1000 * 60 * 60 * 24;
}
var expires_date = new Date( today.getTime() + (expires) );
document.cookie = name+'='+escape( value ) +
( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
( ( path ) ? ';path=' + path : '' ) +
( ( domain ) ? ';domain=' + domain : '' ) +
( ( secure ) ? ';secure' : '' );
}

function deleteCookie( name, path, domain ) {
if ( getCookie( name ) ) document.cookie = name + '=' +
( ( path ) ? ';path=' + path : '') +
( ( domain ) ? ';domain=' + domain : '' ) +
';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}



Y ahora como se usa esta funcion para manipular cookies


// Párametros para setCookie
// nombre, valor, expira, camino, dominio, seguro
setCookie( 'test', 'mi valor', '', '/', '', '' );
if ( getCookie( 'test' ) ) alert( getCookie('test'));

// Párametros para deleteCookie
// nombre, camino, dominio
// Asegúrese de usar los mismos parámetros en setCookie y deleteCookie.
deleteCookie('test', '/', '');
( getCookie( 'test' ) ) ? alert( getCookie('test')) :
alert( 'No existe');


martes, 14 de diciembre de 2010

Imagen interactiva con jQuery


Aqui dejo un link de un tutorial que muestra como hace una imagen interactiva al estilo de IKEA aunque este sitio utiliza flash pero aqui lo muestran con jQuery.



http://buildinternet.com/2009/08/lights-out-dimmingcovering-background-content-with-jquery

viernes, 10 de diciembre de 2010

Deshabilitar el botón derecho con JQuery

Este es código bastante sencillo para que el usuario no pueda utilizar el botón derecho, para incorporarlo en nuestras paginas tan solo has de tener la ultima version de jQuery y listo.



$(document).ready(function(){
$(document).bind("contextmenu",function(e){
return false;
});
});

viernes, 6 de agosto de 2010

Jquery encriptar desencriptar javascript JQuery

Existe una clase que nos ayuda a encriptar o desencriptar cadenas de texto para nuestros diferentes usos, el js en cuestion es JQuery RC4 y seria tan sencillo de utilizar como lo siguiente:

para encriptar

var href = $("#linki").attr("href");
$('#linki').attr('href', 'http://www.weblaquesea.com/descarga_juegos/descargajuegos.php?juegos='+ $.rc4EncryptStr(href,"descarga"));



Para desencriptar

$('#link').attr('href', "http://" + $.rc4DecryptStr(href,"descarga"));});


Aqui estamos pasando una variable codificada y despues la descodificamos, si te das cuenta hay que utilizar una palabra clave tanto en el metodo de encriptar como en el de desencriptar

lunes, 19 de julio de 2010

Eventos en Javacript

En cada elemento o etiqueta XHTML se define su propia lista de posibles eventos ya sean uno o varios.
En la siguiente tabla se resumen los eventos más importantes definidos por JavaScript:

onblur
Deseleccionar el elemento
<button>, <input>, <label>, <select>, <textarea>, <body>


onchange
Deseleccionar un elemento que se ha modificado
<input>, <select>, <textarea>


onclick
Pinchar y soltar el ratón
Todos los elementos


ondblclick
Pinchar dos veces seguidas con el ratón
Todos los elementos


onfocus
Seleccionar un elemento
<button>, <input>, <label>, <select>, <textarea>, <body>


onkeydown
Pulsar una tecla (sin soltar)
Elementos de formulario y <body>


onkeypress
Pulsar una tecla
Elementos de formulario y <body>


onkeyup
Soltar una tecla pulsada
Elementos de formulario y <body>


onload
La página se ha cargado completamente
<body>


onmousedown
Pulsar (sin soltar) un botón del ratón
Todos los elementos


onmousemove
Mover el ratón
Todos los elementos


onmouseout
El ratón "sale" del elemento (pasa por encima de otro elemento)
Todos los elementos


onmouseover
El ratón "entra" en el elemento (pasa por encima del elemento)
Todos los elementos


onmouseup
Soltar el botón que estaba pulsado en el ratón
Todos los elementos


onreset
Inicializar el formulario (borrar todos sus datos)
<form>


onresize
Se ha modificado el tamaño de la ventana del navegador
<body>


onselect
Seleccionar un texto
<input>, <textarea>


onsubmit
Enviar el formulario
<form>


onunload
Se abandona la página (por ejemplo al cerrar el navegador)
<body>

viernes, 2 de julio de 2010

JQuery selectores basicos - selectores formulario - selectores de filtro - selectores de atributos

[atrr(=)(!=)(^=)($=)(*=)value]


(=)Igual

var myVar = 'es';  
$('a[hreflang='+myVar+']');
$('input[type=checkbox][checked=true]');


(!=)Diferente

$("label[name!='identificador']");


(^=)Empieza

$('a[href^=http]');

$("input[name^='Esto']").val("Aquin");


($=) Acaba>

$('a[href$=html]');

$("a[href$=.jpg], a[href$=.jpeg], a[href$=.png]");



(*=)contiene

$('a').not("[href*=value]")



Selectores Filtro basico


:animated

selecciona los elementos que están en proceso de animación en este momento

$(".navArticals:not(:has(:animated))")



:eq()

Obtiene o modifica el valor de un elemento de la referecia que se le pase
$('a.enlacePdf:eq(2)')




:even

Selecciona los elementos pares en el conjunto resultado (en base 0).

$("tr:even").css("background-color", "#bbbbff");



:odd

Selecciona los elementos impares en el conjunto resultado (en base 0).
$("tr:even").css("background-color", "#ffbbbb");


:first

Selecciona el primer elemento asociado

$("tr:first").css("background-color", "#bbbbff");



:last

Selecciona el ultimo elemento asociado
$("tr:last").css("background-color", "#bbbbff");


:header

Elementos de encabezado como h1, h2, h3

$(":header").css({background:'#CCC', color:'blue'});


:gt()

Selecciona los elementos desde el del índice hasta el ultimo

$("tr:gt(6)").css("background-color", "#bbbbff");



:lt()

Selecciona los elementos desde el primero hasta el del índice dado
$("tr:lt(6)").css("background-color", "#bbbbff");



:not()

Selecciona todos los elementos en conjunto que no coincidan con el valor de la referencia pasada

$('tr').not("[href*=value]")
$("tr:not(':last')")



:hidden - Selecciona elementos que son hidden o estan ocultos por css

:visible - Selecciona elementos que son visible o estan visibles por css

:parent - Selecciona elementos que tiene nodos hijos

:empty - Selecciona elementos sin nodos hijos

:contains() - Selecciona elementos que tiene el valor o texto especificado

:has()- Selecciona elementos que contienen elemento que le pasemos



:first-child - Selecciona el primer elemento hijo de su padre.

:last-child - Selecciona el ultimo elemento hijo de su padre.

:only-child - Selecciona el elemento que esta solo(unico) hijo de su padre

:nth-child

Existe con diferentes valores


:nth-child(even) - Selecciona el elemento hijo de su padre indicado pero con la condición de que sea par

:nth-child(odd) - Selecciona el elemento hijo de su padre indicado pero con la condición de que sea impar

:nth-child(3n+1) - Selecciona el primer elemento hijo de su padre y siguiente sera el tercero

:nth-child(2) - Selecciona el segundo elemento hijo de su padre

$("div p:*****child").text("Cambio texto");


Filtros de formulario



:button

Selecciona todos los elementos de tipo button.

:checkbox

Selecciona todos los elementos de tipo checkbox.

:checked

Selecciona todos los elementos que estan checked.

:disabled

Selecciona todos los elementos que estan disabled.

:enabled

Selecciona todos los elementos que estan enabled

:file

Selecciona todos los elementos de tipo file.

:image

Selecciona todos los elementos de tipo image.

:input

Selecciona todos los elementos input

:password

Selecciona todos los elementos de tipo password.

:radio

Selecciona todos los elementos de tipo radio.

:reset

Selecciona todos los elementos de tipo reset.

:selected

Selecciona todos los elementos de tipo selected.

:submit

Selecciona todos los elementos de tipo submit

:text

Selecciona todos los elementos de tipo text.

miércoles, 23 de junio de 2010

jQuery aprendiendo a manipular elementos y manejar conceptos basico - segunda parte

html: Podemos recuperar o reemplazar el contenido HTML de un elemento.


var variahtml =$("#idJQuery").html();
$("p").html("<a href="http://www.google.es">Google</a>");


text: Es muy parecido a html() pero este hace caso omiso al las etiquetas HTML.


$("p").text("<a href="http://www.google.es">Google</a>");


wrap: Inserta una estructura HTML en el interior de un elemento (envolver).

$("span").wrap("<div><div><p><em><b></b></em></p></div></div>");


unwrap: Remueve una estructura HTML del elemento

$("span").unwrap();
o
$("span").unwrap("<b/>");


wrapAll: Envuelve a todos los elementos juntos.


$("li").wrapAll("<div class="estilo1"></div>");



wrapInner:Envuelve una estructura HTML alrededor del contenido de cada elemento en el conjunto de los elementos coincidentes.


$("li").wrapInner("<div class="estilo1"></div>");


replaceWith: reemplaza los tags HTML de los elementos por el contenido que pasemos.


$("p").replaceWith("<div>"+ $("p").text()+"</div>");


replaceAll: Localiza todos los elementos en primera instancia. Esta función realiza la misma acción que replaceWith pero actua por cada elemento independientemente.


$("p").replaceAll("<div>"+ $("p").text()+"</div>");


clone: Simplemente duplica los elementos.


$("#idJQuery").clone().prependTo("p");


empty: Vacia el contenido de los elementos.

$("#idJQuery").empty();


remove: Elimina los elementos.


$("#idJQuery").remove();

jQuery aprendiendo a manipular elementos y manejar conceptos basico

Vamos a ver como manipular elementos en JQuery asi que ahora a ver sus funciones

append: Lo utilizamos para añadir un codigo HTML al elemento que nos interese


$("li").append("Manipular el elemento ");
$("#idJQuery").append("con estos añadidos");


appendTo: Se usa para seleccionar un elemento y enviar sus caracteristicas a otro elemento que queremos hacer un añadido


$("li").appendTo("#parraf");


prepend:Basicamente realiza la misma accion que append, con la diferencia que este realiza la accion al principio del elemento.


$("li").prepend("Este texto que ira por delante ");


prependTo: Ahora va elemento seleccionado delante del elementoque hemos puesto en segundo lugar.


$("li").prependTo("p");


after: Inserta contenido especificado por el elemento despues de cada elemento


$("parraf").after("li");
$("p").after(" despues");


insertAfter: inserta el elemento despues del elemento al que se le hace referencia.


$('<h3>contenido</h3>').insertAfter('.clase');


before: Coloca el elemento antes del existente.


$('.clase').before('<p>Texto</p>');


insertBefore: Posiciona elementos antes del indicado.

$('<h3>contenido</h3>').insertBefore('.clase');

Como indexar un blogger y darlo de alta google

Para indexar un blogger y darlo de alta para que aparezca en el maravilloso buscador Google deberemos utilizar la Herramienta para webmasters que nos permitira subir el sitemap y este haga su funcion de mostrar todas nuestras paginas al buscador.

¿Pero como añadir un sitemap si blogger no lo usa?

Es simple podemos usar nuestro Feed como sitemap, el feed se encuentra en la dirección http://jquery total.blogspot.com/atom.xml

Bien llegados hasta aqui deberemos irnos a las herramientas para webmaster añadir nuestro sitio y en la informacion del sitio clickamos en sitemap hay insertaremos nuestra url y listo.

JQuery aprendiendo $.extend

Esta función coge los valores de dos variables con parámetros y los combina, siempre cogiendo como bueno el ultimo parámetro con valor y si no cogerá el valor del parámetro de la primera variable. $.extend puede ser mas conocido a la hora de crear plugins


var comentario = {
autor : 'megatron',
email : 'email@vivalared.com',
sitio_web : 'http://www.vivalared.com',
contenido : 'Me gusto mucho la pelicula en 3D',
post : 1099,
notificar_actualizaciones : 1,
fecha : '2010-05-21'
}

var actualizar_comentario = {
email : 'nuevomail@vivalared.com',
notificar_actualizaciones : 0,
autor : 'megatron',
fecha : '2010-05-28'
}

var nuevo_comentario = $.extend(comentario, actualizar_comentario);
console.info(nuevo_comentario.email);


Definir nuestros argumentos predeterminados como un objeto, y luego extenderlo con las propiedades


function mi_funcion(args){
opciones = jQuery.extend({
clase_activa : 'active',
animacion : 'slide',
duracion : 150,
idioma : 'es',
mensaje : 'bazinga!'
}, args);
}

//Y luego, al llamar a la función...

mi_funcion({ duracion: 200, idioma : 'en', mensaje : 'lorem ipsum' });

console.info(opciones.mensaje);