Skip to content

2019_11 Actualización de sip 2.0b6 a sip 2.0b7

Vladimir Támara Patiño edited this page Jan 25, 2021 · 4 revisions

1. Cambios en experiencia de usuario

El cambio era requerido para modernizar la interfaz de 3 formas: (1) haciendola más adaptable a dispositivos móviles (siguiendo lineamientos de diseño visual de twitter y su librería Bootstrap 4), (2) permitiendo personalizar el color de más elementos visuales mediante temas y (3) posibilitando el uso de librerías javascript más recientes.

Entre los cambios visibles notará:

  • Ahora el tamaño del tipo de letra base es 16px (antes era 14px)
  • Se procura que los contenidos requieran desplazamiento vertical pero no tanto horizontal.
  • Cambió la distribución de algunos elementos visuales, i.e su ubicación y/o dimensiones:
    • El navegador de paǵinas (donde se quitaron las palabras anterior y siguiente y se dejaron solo flechas).
    • Tamaño de los botones (en particular de acciones), que ahora son más grandes
  • Gama de colores configurables en más elementos de la interfaz mediante temas personalizables para cada usuario.

2. Cambios para sitios en producción con unicorn y nginx

Si su aplicación se monta sobre una ruta que no sea /, digamos miorg/misitio es importante que en public/miorg/misitio cree un enlace a public/packs por ejemplo:

cd public/miorg/misitio
ln -s ../../packs .

Simultaneamente debe cambiar la configuración de nginx para que sirva estáticamente el contenido de packs, es decir dentro de la sección para su sitio miorg/misitio en producción agregar algo como:

    location ^~ /miorg/misitio/packs/ {
        gzip_static on;
        add_header Cache-Control public;
        root /var/www/htdocs/miorg/misitio/public/;
    }

Si hace falta agregue en config/application.rb:

config.relative_url_root = '/miorg/misitio'

3. Cambios para desarrolladores que usan sip en motores o aplicaciones.

Los cambios mayores son:

  1. Actualizar varias dependencias obsoletas y facilitar que las aplicaciones que usen sip empleen paquetes npm más modernos y modulares para desarrollar interfaces:
  • Bootstrap 3 a Bootstrap 4
  • Jquery 1.4 a Jquery 3.4.1
  • Fontawesome 4.7 a 5.0
  1. Usamos más webpack que sprockets para preparar y transmitir Javascript, pasando más gemas con sprockets a paquetes npm manejados por webpack: bootstrap, bootstrap-datepicker, chosen, font-awesome, jquery, jquery-ui y turbolinks. En general sugerimos emplear webpacker para Javascript y dejar sprockets para CSS e imagenes. Es un cambio complejo cuyas bases estamos resumiendo en https://github.com/pasosdeJesus/sip/wiki/Pasando-de-sprockets-a-webpacker-con-Rails-6
  2. Usar la gema sassc-rails que es más rápida para procesa SCSS que sass-rails.
  3. Ampliamos el concepto de tema y simplificamos la implementación.

Hemos implementado varias funciones auxiliares que antes proveían las gemas de Bootstrap y de Fontawesome.

Dada la amplitud del cambio si en alguna aplicación prefieres mantener por más tiempo Bootstrap 3, jquery 1.4 y el uso generalizado de sprockets para transmitir Javascript (y la consecuente imposibilidad de usar módulos en Javascript) puedes usar la rama r2.0b6 de sip (que no tendrá mantenimiento).

3.1 Preparación de recursos mediante webpack y sprockets

3.1.1 Quitar algunas gemas obsoletas y remplazarlas por paquetes npm

De Gemfile retira:

gem 'bootstrap-datepicker'
gem 'chosen-rails'
gem 'font-awesome-rails'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'pick-a-color-rails'
gem 'tiny-color-rails'
gem 'turbolinks'
gem 'twitter-bootstrap-rails'
gem 'uglifier'

Remplaza sass, sass-rails y sassc por sassc-rails.

Para ver mensajes en terminal en colores, sip requiere que en los grupos development y test tengas colorize, puede ser algo como:

group  :development, :test do 
  #gem 'byebug' # Depurar
  gem 'colorize' # Colores en terminal 
end

Y ejecuta:

bundle update; bundle install

Después desde el directorio de la aplicación (i.e / en caso de aplicaciones y test/dummy en caso de motores) descarga los paquetes npm con:

yarn add @rails/ujs  bootstrap bootstrap-datepicker chosen-js expose-loader @fortawesome/fontawesome-free jquery jquery-ui popper.js turbolinks 

Esto último debe modificar el archivo package.json, el cual debe incluir los paquetes mencionados. A continuación ejecuta:

CXX=c++ yarn install

3.1.2 Transmitir hojas de estilo mediante sprockets pero Javascript preferentemente con webpack:

El archivo config/initializers/assets.rb de sip ya incluye lo necesario para que:

  • Sprockets cargue recursos de node_modules
  • Emplear versión SASS de bootstrap y de fontawesome
  • En modo de desarrollo emplear fuentes de fontawesome y gráfico de chosen-js de node_modules y al precompilar copiarlos con huellas (sha256) en directorio público de recursos (esto último no basta con chosen y fontawesome que originalmente no emplean huellas sino recursos como chosen-sprite.png, fontawesome.)

Así que no es necesario que repitas esto en las fuentes de la aplicación.

De los diversos archivos de app/assets/stylesheets retira hojas de estilo provenientes de versiones anteriores (los de las nuevas ya se incluyen en sip):

*= require chosen
*= require font-awesome
*= require twitter-bootstrap-static/bootstrap
*= require bootstrap-datepicker

Retira de archivos de app/assets/javascripts inclusiones de paquetes que antes eran gemas:

//= require bootstrap
//= require chosen-jquery 
//= require jquery
//= require turbolinks
//= require jquery-ui/widgets/autocomplete
//= require bootstrap-datepicker

Indica a sprockets que emplee los CSS listos de los paquetes recientes, aprovechando que sip ya los configura, editando app/assets/stylesheets/application.css para asegurar que incluye:

*= require sip/application.css

o que incluya otra hoja que a su vez incluya esa.

Desde el directorio de la aplicación en app/javascript/packs/application.js indica los Javascript a cargar con:

console.log('Hola Mundo desde Webpacker')

require('@rails/ujs').start()   // Javascript no intrusivo segun rails
require('turbolinks').start()   // Acelera carga de paginas

import {$, jQuery} from 'jquery';
import 'popper.js'              // Dialogos emergentes usados por bootstrap
import 'bootstrap'              // Maquetacion y elementos de diseño
import 'chosen-js/chosen.jquery';       // Cuadros de seleccion potenciados
import 'bootstrap-datepicker'
import 'bootstrap-datepicker/dist/locales/bootstrap-datepicker.es.min.js'
import 'jquery-ui'
import 'jquery-ui/ui/widgets/autocomplete'

Asegura la carga de jQuery de forma global (mientras se tenga esas dependencia en javascripts) modificando config/webpack/environment.js para dejar algo como:

const { environment } = require('@rails/webpacker')

const webpack = require('webpack')

environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
   $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
    'window.jQuery': 'jquery',
    Popper: ['popper.js', 'default']
  })
)

environment.loaders.append('expose', {
    test: require.resolve('jquery'),
    use: [
          { loader: 'expose-loader', options: '$' },
          { loader: 'expose-loader', options: 'jQuery' }
        ]
})
      
module.exports = environment

Si empleas una maquetación general (layout) diferente a la de sip asegurate de modificar en app/views/layouts/application.html.erb el orden entre los javascript preparados por sprockets y los preparado por webpack:

<head>
...
<%= stylesheet_link_tag "application", :media => "all",
  'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag "application" %>
...
</head>

3.1.3 Prueba el cambio

Desde el directorio de la aplicación debería operar:

bin/rails assets:precompile --trace

Que debería crear diversos recursos en public.../assets

3.2 Cambios por paso de Bootstrap 3 a Bootstrap 4

  • Verifica que la barra de menús opera, pues las funciones auxiliares ahora se implementan en sip. Para casos comunes se comportan igual que originales pero por cuanto cambió la forma de especificar opciones de menús, las opciones de menús desplegables requieren un tercer parámetro desplegable: true
  • Las imágenes adaptables ya no tienen clase img-responsive sino img-fluid
  • Los botones ya no pueden tener clase .btn-xs, el más pequeños es .btn-sm (en general ya no se usa -xs).
  • La grilla ya no emplea col-medio-offset-num sino offset-medio-num.
  • En bootstrap 4 ya no hay paneles (panel), ahora deben usarse tarjetas (card). Por ejemplo lo que era en bootstrap 3
<div class="panel panel-default">
  <div class="panel-heading">Título</div>
  <div class="panel-body">
    Contenido
  </div>
</div>

en bootstrap 4 debe ser:

 <div class="card border-primary">
   <div class="card-body">
     <h4 class="card-title">Título</h4>
     Contenido
  </div>
</div>
  • Cambio la forma de especificar un panel con pestañas: ahora cada elemento li debe tener clase nav-item y cada elemento a debe tener clase nav-link. El li de la pestaña que debe comenzar activa debe tener enlace con clase active y atributo aria-selected="true". El tab-pane inicialmente activo debe tener clases active show. Cada panel de contenido con clase tab-pane es más "chévere" con la clase fade.
  • El navegador de páginas requiere que cada enlace tenga la clase page-link, por ejemplo:
<%= will_paginate @informes, { param_name: :pagina, 
  class: 'page-link' }  %>  

3.2.3 Fontawesome de 4.7 a 5

  • Puedes cambiar las funciones auxiliares a español:
    • icono-fa (fa-icon).
  • Ahora usamos el paquete npm @fortawesome/fontawesome-free
  • Las fuentes se copian automáticamente en public.../@fortawesome/fontawesome-free/webfonts/, porque modificamos en sip el archivo global config/initializers/assets.rb:
  • Usamos la versión SASS que facilita establecer ruta de las fuentes mediante la variable $fa-font-path
  • Fontawesome 5 ahora tiene una versión libre (que es la que usamos) y una pro o por pago. Varios íconos que había en la versión 4.7 pasaron a la versión Pro. Sin embargo la versión libre suele tener iconos alternativos, por ejemplo fa-cloud-download ahora está disponible en la version Pro, pero buscando entre los disponibles en la versión libre encontramos fa-cloud-download-alt.

3.2.4. Cambios en Javascript por paso de jQuery 1.4 a jQuery 3.4

  • Ya no hay método size(), usa .length.
  • getJSON ya no emplea .error, usa .fail

4. Cambios en temas

Ahora en la tabla tema no se almacena el color en hexadecimal (como ocurría en sip 2.0b6) sino en un valor valido CSS (lo que antes era 'ffffff' ahora es '#ffffff').

Ampliamos el concepto de tema de colores, ahora cubre:

  • Color de fondo (y primero para tablas alternantes, fondo en campos de entrada)
  • Color de letra principal
  • Segundo color en tablas alternantes
  • Color de alerta de exito (como logró ingresar)
  • Color de alerta de error (como cuando no pasa validación).
  • Colores de la barra de navegación y de los menús desplegables
  • Colores de los botones primarios (como el botón Nuevo)
  • Colores de los botones de peligro (como el botón Eliminar)
  • Colores de los botones para otras acciones (como el botón Editar)

Los últimos 4 grupos de colores constan de: (1) color de la parte superior del fondo para degrade, (2) color de la parte inferior para degrade y (3) color para la letra e iconos.

Para lograr combinaciones agradables de colores recomendamos sacar colores del logo o imagen institucional mediante una herramienta como: https://color.adobe.com/es/create

No empleamos en sip los temas de colores de Bootstrap 4 porque nos pareció un soporte incompleto para colores (aunque es más amplio en otros aspectos que aún no tuvimos en cuenta en sip como espaciado de elementos, tamaño de fuentes y efectos).

5. Otros cambios que podrías considerar

  • Cambiar uso de otras gemas Javascript con sprockets por paquetes npm con webpacker
  • Explorar más posibilidades con temas de Bootstrap 4 y mezclarlas con el concepto de temas de sip: https://getbootstrap.com/docs/4.3/getting-started/theming/
  • Seguir las líneas generales a nivel de interfaz en otras aplicaciones rails recientes:
    • Modificar el Javascript de tu aplicación para usar módulos y webpack para implementarlo en navegadores
    • No emplear jQuery
  • Usar webpack de motores

En el resto de esta sección exploramos algunas de estas posibilidades.

5.1 Reducir o eliminar la dependencia en jQuery

En el archivo app/assets/javascripts/application.js remplaza:

$(document).on("turbolinks:load", function() {

por

document.addEventListener("turbolinks:load", function() {

5.2 Emplear webpacker de motores en paralelo a los de la aplicación

El soporte para motores de webpacker está apenas comenzando al momento de este escrito (ver https://github.com/rails/webpacker/issues/348) aún cuando ya hay documentación inicial: https://github.com/rails/webpacker/blob/master/docs/engines.md. Allí se describen un método de servir los recursos webpack del motor mediante Rack.

De ese escrito diferimos en la sugerencia de emitir recursos compilados simplemente en ../public porque aunque podría crear un "repositorio" de packs precompilados en /var/www/bundler/ruby/2.6/gems/public, en principio se mezclarían los de distintas versiones de gemas. Por eso nos parece mejor:

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_root_path: public
  public_output_path: mimitor-packs
  cache_path: tmp/cache/webpacker
  check_yarn_integrity: false
  webpack_compile_output: false    

Nos parce mejor dejar esos recursos en public dentro de la gema y en la aplicación en config/application.rb usarlos:

   config.middleware.use(
      Rack::Static,
      urls: ["/mimotor-packs"], root: File.join(
        Gem::Specification.find_by_name("mimotor").gem_dir, 'public')
    )

Así en la aplicación puede ejecutarse

bin/rails mimotor:webpacker:compile  

para compilar recursos a mimotor/public/mimotor-packs

Otra posibilidad es modificar en la aplicación config/webpacker para incluir la ruta del motor entre las buscadas por ejemplo:

resolved_paths: ['../active_record_migration_ui/public/']  

Sin embargo este método no es tan conveniente porque requiere poner la ruta de la gema --que puede cambiar ante cambio de versiones-- y no es directo emplear por ejemplo Gem::Specification porque el YAML de webpacker.yaml no aceptar ERB.

Ambos métodos dan rutas diferentes para los recursos del motor (i.e /mimotor-packs/) y para la aplicación (/packs). En modo de desarrollo esos espacios de nombres son servidos por rack, pero no es tan claro en modo producción donde nginx tipicamente sirve /packs como hacerlo servir /mimotor/packs de una forma general ante cambio de versiones y ubicación de las fuentes de mimotor, ni tampoco como operaría si se cambia el punto de montaje de la aplicación (parece que cada vez es menos frecuente el escenario de punto de montaje diferente a / por la popularidad de docker que en general deja lo que corre en /).

Clone this wiki locally