#lisp #ucw #tutorial #esencial #CommonLisp #UnCommonWeb
Objetivo
En esta entrega del Tutorial esencial de UCW, vamos a aprender a mejorar la vista y la funcionalidad de nuestras aplicaciones UCW, incluyendo el uso de CSS y javascript.
Antecedentes
Es recomendable que si no lo haz hecho, sigas antes que nada la primera parte de este tutorial la cual puedes ver en:
URL y vista
Primero que nada crearemos un nuevo archivo para este ejemplo.
emacs ucw_bt_example_01.lisp
En seguida, agregaremos a este archivo el código para la ruta de la pagina de este ejemplo
;;;; ucw_basics_tutorial
(in-package "ucw-bt")
;;; "ucw_basics_tutorial" example 01 Using javascript and CSS
;;; The entry point of example 01
(defentry-point "example01.ucw" (:application *ucw-bt-application*)
()
(call 'ucw-bt-window
:body (make-instance 'ucw-bt-comp-02)
:title "UCW Basics Tutorial - Example 01"
:icon "/img/favicon.png"))
Como pueden ver, estamos definiendo la ruta o para la URL que nos permitirá accesar este ejemplo, llamándola example01.ucw.
El componente de ventana, sigue siendo el mismo ucw-br-window, pero lo estamos llamando con otro componente para el body ucw-bt-comp-02.
También cambiamos el Titulo de la pagina.
A continuación incluimos el código para el componente del cuerpo de nuestro ejemplo:
(defcomponent ucw-bt-comp-02 ()
())
(defmethod render ((obj02 ucw-bt-comp-02))
)
Aquí definimos el componente y su correspondiente método render, el cual entrega el contenido del componente.
Y coloquemos un poco de contenido en el método render:
(defmethod render ((obj02 ucw-bt-comp-02))
(<:h2 "Example 01 - Using CSS and javascript")
(<:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a convallis nisl, at aliquam dolor. Morbi in iaculis nunc. Nulla eu mi at velit imperdiet sollicitudin sed vel risus. Quisque eleifend lorem ipsum, et tempus nulla convallis nec. Duis molestie diam at molestie sodales. In convallis, dui in iaculis adipiscing, tortor neque elementum lectus, quis dapibus sapien metus vestibulum nibh. Curabitur fermentum molestie ipsum, a sagittis mi. Suspendisse tempus consequat odio, quis tempus augue vulputate at.")
(<:br)
(<:h3 "Traducción")
(<:p "Por otra parte, denunciamos con indignación a los hombres que son engañados y desmoralizados por los encantos del placer del momento, tan cegados por el deseo, que no pueden prever el dolor y la molestia que se va a producir, y la misma culpa es de los que faltan a su deber por debilidad de la voluntad, que es lo mismo que decir que fallan por la fatiga y el dolor. Estos casos son muy simples y fácil de distinguir. En una hora libre, sin las trabas de nuestro poder de elección y cuando nada impida que seamos capaces de hacer lo que más nos gusta, todo placer es de agradecer y cada dolor se puede evitar. Pero en ciertas circunstancias y debido a las exigencias del deber o de las obligaciones de la empresa, estos placeres tienen que ser repudiados y sus molestias aceptadas .El hombre sabio, por lo tanto, siempre tiene en estos asuntos una elección: rechaza placeres para asegurar otros placeres mayores, o de lo contrario evita los dolores para evitar dolores peores.")
(<:h3 "Translation")
(<:p "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.")
(<:a :href "http://omicrono.elespanol.com/2013/07/que-ocurre-si-intentas-traducir-lorem-ipsum-en-google-translate/"
:target "_blank"
"http://omicrono.elespanol.com/2013/07/que-ocurre-si-intentas-traducir-lorem-ipsum-en-google-translate/"))
Visualización de nuestra pagina del ejemplo 01
Suponiendo que el servidor de nuestra aplicación ya esta corriendo, solo tenemos que evaluar (C-c C-r ) o compilar el codigo (C-c M-k) del archivo.
Y luego apuntar nuestro navegador hacia:
http://localhost:8080/example01.ucw
Donde veremos la página de nuestro ejemplo 01:
Incluir el ejemplo 1 en nuestro sistema
Para que nuestro sistema reconozca nuestro ejemplo 1 debemos agregarlo a la definición de nuestro sistema.
(asdf:defsystem #:ucw_basics_tutorial
:description "Describe ucw_basics_tutorial here"
:author "Erick Lopez
:depends-on (#:ucw-core
#:ucw
#:iolib
#:parenscript)
:serial t
:components ((:file "package")
(:file "ucw_bt_server_init")
(:file "ucw_basics_tutorial")
(:file "ucw_bt_example_01")))
Podemos ver resaltado en negritas la inclusión de el archivo del ejemplo 01.
Enlazar ejemplo y página de inicio
Pongamos un par de ligas para ir de la pagina inicial al ejemplo y viceversa.
Primero agreguemos una liga para ir de nuestro ejemplo a la página de inicio:
(<:h2 "Example 01 - Using CSS and javascript")
(<:a :href "/index.ucw" "Regresar a inicio")
Y luego editemos nuestra pagina de inicio (ucw_basics_tutorial.lisp) para incluir una liga hacia nuestro ejemplo 01.
....
(<:h3 "Index")
(<:ul
(<:li
(<:a :href "/example01.ucw" "Example 01 using javascript and css")))
...
Hasta aquí, tenemos una página web simple, sin estilo y sin funcionalidades, podemos leer el texto, ir a una pagina web externa e ir a la pagina inicio y de regreso.
Luce así en este momento:
¿Luce un poco seria la página?, yo creo que sí, y seguramente muchos de los que la visiten y vean opinarían algo similar, por lo cual agregaremos primero un poco de estilo a la misma y posteriormente algunas funcionalidades utilizando javascript.
Inicialización de la aplicación para incluir CSS y Js
Si dan un vistazo a ucw_bt_server_init.lisp veran que ya habíamos definido que nuestra aplicación utiliza archivos CSS y js:
(defvar *wwwroot*
(merge-pathnames #P"wwwroot/"
(asdf:component-pathname (asdf:find-system :ucw_basics_tutorial))))
(defvar *js*
(merge-pathnames #P"wwwroot/js/"
(asdf:component-pathname (asdf:find-system :ucw_basics_tutorial))))
(defvar *css*
(merge-pathnames #P"wwwroot/css/"
(asdf:component-pathname (asdf:find-system :ucw_basics_tutorial))))
(defvar *img*
(merge-pathnames #P"wwwroot/img/"
(asdf:component-pathname (asdf:find-system :ucw_basics_tutorial))))
(defvar *ucw-bt-application*
(make-instance
'ucw-bt-application
:url-prefix "/"
:debug-on-error t
:static-roots (list (cons "wwwroot/" *wwwroot*)
(cons "css/" *css*)
(cons "js/" *js*)
(cons "img/" *img*))))
Componente de ventana con css y js
Ahora definiremos un nuevo componente de tipo ventana, el cual tendra acceso a archivos css y js:
(defcomponent ucw-bt-window-with-css-and-js (standard-window-component)
()
(:default-initargs
:title "UCW basics Tutorial - Example 01"
:icon "wwwroot/favicon.png"
:stylesheet '("/css/ucw-bt.css")
:javascript '((:src "/js/ucw-bt.js"))
:body (make-instance 'ucw-bt-comp-02))
(:documentation "UCW Basics Tutorial window with css and js"))
Y modifiquemos nuestro entry-point de manera correspondiente:
(defentry-point "example01.ucw" (:application *ucw-bt-application*)
()
(call 'ucw-bt-window-with-css-and-js
:body (make-instance 'ucw-bt-comp-02)
:title "UCW Basics Tutorial - Example 01"
:icon "/img/favicon.png"))
Evaluemos o compilemos para que estos cambios entren en funcionamiento. Y Recarguemos la pagina web de nuestro ejemplo, la cual lucirá igual aún, pero mirando el código html de la misma notaremos los cambios:
Creación de los directorios usados por la aplicación
Ahora debemos crear los directorios que indicamos en defvar *wwwroot* del archivo ucw_bt_server_init.lisp
cd src/lisp/ucw-basics-tutorial/
mkdir wwwroot
mkdir wwwroot/css
mkdir wwwroot/js
mkdir wwwroot/img
Y de una vez creamos los archivos, vacios por ahora.
touch wwwroot/css/ucw-bt.css
touch wwwroot/js/ucw-bt.js
Poniendo estilo a nuestra página de ejemplo
emacs wwwroot/css/ucw-bt.css
p {
background-color: lavender;
border: 1px solid gray;
}
h2 {
font-family: helvetica;
color: MidnightBlue;
}
h3 {
font-family: sans-serif;
color: MediumBlue;
}
/* unvisited link */
a:link {
color: red;
}
/* visited link */
a:visited {
color: green;
}
/* mouse over link */
a:hover {
color: hotpink;
}
/* selected link */
a:active {
color: blue;
}
Guardamos cambios al archivo y recargamos página, debemos ver algo como la siguiente pantalla:
Ahora ya sabes como aplicar el estilo a nuestra aplicación UCW, ¡Felicidades!
Utilizando javascript en nuestra aplicación UCW
Vamos a agregar a nuestra página de ejemplo una función de javascript con la cual cambiaremos el estilo de un elemento de la página.
Como primer paso agreguemos un botón a nuestra página:
(defmethod render ((obj02 ucw-bt-comp-02))
(<:h2 "Example 01 - Using CSS and javascript")
(<:a :href "/index.ucw" "Regresar a inicio")
(<:button
:type "button"
:class "button"
:onclick (ps (changestyle))
"Change style!")
Estamos agregando un botón que llama a la función changestyle.
Evaluamos o compilamos el código anterior.
Agregamos estilo al botón para que no se vea tan aburrido como el default:
emacs ucw-bt.css
.button {
background-color: white;
border: none;
color: #4CAF50;
padding: 15px 32px;
text-align: center;
text-decoration: overline;
display: inline-block;
font-size: 18px;
border-radius: 12px;
}
Y finalmente editemos nuestro archivo de javascript para agregar la función.
emacs wwwroot/js/ucw-bt.js
function changestyle () {
var list = document.getElementsByTagName("p"); // get all p elements
list[0].style.color = "red"; // make the first one red
}
Con todo listo, podemos ver el resultado en el navegador:
Tenemos el botón "Change Style" y todos los párrafos en letra de color negro.
Damos click en "Change Style!" y nuestra función de javascript se ejecuta cambiando el estilo de la siguiente manera:
Se ejecutó la función de javascript y cambio el color del texto del primer párrafo de negro a rojo.
¡Felicidades! Ahora ya sabes como programar aplicaciones web utilizando css y javascript en UnCommonWeb.
Cualquier pregunta escribanla en un comentario al presente y con gusto la responderé a la brevedad posible.
Happy Hacking!
Autor: Erick "ikki" López