Creemos en la Web: Haciendo Lugar

En la sección Creemos en la Web: Lo espacial es invisible a los ojos vimos como indicar que queremos mas espacio entre el borde y otros elementos (margin/margen), en el borde (border) o entre el borde y el contenido interno (padding/relleno).

Cuando yo era joven y el pasto era mas verde, las paginas web se hacían asumiendo una o dos resoluciones de pantalla, ya que los navegadores solo funcionaban en PCs y todas las PCs tenían una resolución casi estándar (800 pixeles de ancho por 600 de alto).

En esas épocas mas simples la unidad que se usaba para indicar espacio/distancia eran los pixeles, una unidad absoluta que se refiere a cada puntito de la pantalla que puede mostrar un color.

Como todas las pantallas tenían cantidades similares de pixeles horizontales y verticales, la cosa funcionaba bastante bien para todos.

No hace falta que les cuente que hoy la web se accede de una cantidad impresionante de dispositivos y resoluciones.

Para poder escribir estilo que se adapte a la resolución de cada dispositivo usamos otras unidades, llamadas relativas, ya que son relativas a algo presente en la pagina, las mas usadas son relativas al ancho del elemento que contiene nuestro tag o al ancho de una letra en el texto.

Pixeles

Esta es la unidad mas común, un pixel es un punto en la pantalla, el cual puede mostrar un color, la cantidad horizontal y vertical de pixeles en una pantalla se llama resolución, por ejemplo, una pantalla de una laptop puede tener 1280 pixeles de ancho por 800 de alto, lo que se escribe abreviado 1280x800.

cuando especificamos el estilo de un tag y le decimos que su borde, margen o relleno es de 15px (15 pixeles), le estamos diciendo que queremos 15 puntos de espacio, pero no sabemos cuantos pixeles tiene la pantalla en total, asi que eso puede ser bastante para la pantalla de un celular básico que puede tener una resolución de 320x240 o muy poco para la pantalla de una computadora de escritorio avanzada que pueden tener 3840x2160 (mas de 10 veces mas resolución!).

Idealmente vamos a usar esta unidad muy poco, yo lo uso solo para especificar el ancho de los bordes y muchas veces no debería :)

em

Esta es la unidad mas usada y la mas recomendada, su nombre según tengo entendido viene de lejos, 1em es el alto en pixeles de la letra M mayúscula, si nombramos la letra M "eme" en ingles es "em".

el alto de que M mayúscula? de la M si estuviera en el tag en el que estamos actualmente, osea que esta unidad es relativa al tamaño de texto del tag en el que nos encontramos, el cual lo puede haber establecido cualquiera de los tags padres, o ninguno, siendo asi el estándar de 16px.

rem

Pero que pasa si no sabemos que estilos se aplicaron a tags padres y queremos estar mas seguros del tamaño que vamos a obtener? para eso existe la unidad rem, que es el alto de la letra M según el tamaño de texto definido en la base del documento (el tag <body>), de no estar definido va a ser también 16px.

Su nombre viene de "root em" (em de la raíz).

Esto nos permite saber que no importa que tamaños de fuente se hayan redefinido hasta nuestro tag, su tamaño va a ser siempre fijo relativo al tamaño base del texto del documento.

Porcentajes

Otra unidad útil, pero usada normalmente cuando estamos definiendo tamaños de la estructura de nuestro documento como ancho de columnas es el porcentaje %.

El porcentaje se refiere al ancho del tag que contiene al tag actual, si decimos que el ancho de nuestro tag es 50%, este ocupara la mitad del tag padre, si decimos que el margen horizontal es de 5%, el padding horizontal es del 2.5%, entonces nos queda 75% para el contenido:

5% margen izquierdo + 2.5% padding izquierdo + 2.5% padding derecho + 5% margen derecho = 15%

Ejemplos que no se entiende nada!

Las unidades de espacio se entienden mas usandolas y a puro prueba y error, la recomendación es usar em y rem siempre que se pueda, porcentajes cuando estamos definiendo posicionamiento de cosas en la pagina y pixeles si tenes una buena razón.

El div azul que contiene a todos los otros divs establece el tamaño de la fuente a 16 pixeles:

5em
5rem
50px
50%

El div azul que contiene a todos los otros divs establece el tamaño de la fuente, notar que los divs interiores tienen el mismo estilo que los de arriba:

5em
5rem
50px
50%

El primer div tiene un ancho de 5em, como el div padre establece el tamaño de la fuente a distintos valores en los dos ejemplos, el ancho resultante es distinto.

El segundo div tiene un ancho de 5rem, como ambos están en el mismo documento raíz, tienen el mismo ancho, aun cuando el texto interior cambia, ya que "hereda" el tamaño del div padre.

El tercero esta en pixeles, así que va a ser igual, el cuarto esta en porcentaje, y ya que ambos divs padres tienen el mismo ancho, su ancho es igual.

Probemos algo un poco distinto:

5em
5rem
50px
50%

El div padre ahora ocupa el 50% del ancho de la pagina, por lo que el ancho del ultimo div hijo debería ser la mitad de los anteriores, para "estandarizar" em y rem, seteo el tamaño de fuente de los divs hijos a 1rem.

Como no se en que pantalla estas viendo esto no te puedo decir mucho sobre que ancho van a tener, lo único que se, es que como la fuente de ambos tiene 1rem de tamaño, el ancho de los dos debería ser el mismo.

Si el tamaño de la fuente del documento resulta ser 10px, entonces el tercer div tendrá el mismo ancho.

Como siempre, no hace falta que se entienda todo ahora, solo saber las unidades mas usadas, las recomendadas y mas o menos como se comportan, el resto es prueba y error.

Creemos en la Web: Colores

Estamos creando una pagina y vemos o nos imaginamos un color que queremos usar, como se lo comunicamos a la computadora?

Las computadoras son buenas manipulando números, los colores, al menos como nosotros los usamos al comunicarnos, no tienen mucho de números.

En la búsqueda por encontrar un compromiso que funcionara tanto para humanos como para computadoras surgieron diferentes "representaciones", formas de describir unívocamente a que color nos referimos.

En esta sección vamos a explorar estas distintas representaciones.

Una herramienta online para elegir colores es Mozilla Color Picker podes usar esta o buscar alguna con la que ya hayas trabajado, intenta que permita ver las representaciones que vamos a explorar en esta sección.

Usando colores

Los siguientes son algunos de los atributos CSS que requieren colores, todos soportan todas las representaciones que vamos a explorar a continuación.

  • color
  • background-color
  • border-color
  • outline-color
  • text-decoration-color
  • text-emphasis-color
  • text-shadow

Un ejemplo que algunos de los atributos listados:

<span style="border: 1px solid; text-decoration: underline; color: red; background-color: lightgrey; border-color: blue; text-decoration-color: green; text-shadow: yellow 0.6em 0.6em; padding: 1em;">Hello Color</span>
Hello Color

Colores con nombres

La mas fácil y la que hemos usado hasta ahora es simplemente dar el nombre del color en ingles cuando necesitamos referirnos a el.

Esta representación es simple para los humanos pero tiene un par de limitaciones:

  • Hay que mantener una lista de nombres a colores
  • No todos los colores tienen nombre
  • Como me acuerdo de tantos nombres?
  • Tampoco queremos una lista de colores eterna
  • Cuando busco un color, como lo busco rápido en la tabla?
  • Cuando digo rojo, que rojo es?

A continuación la lista de colores

black
silver
gray
white
maroon
red
purple
fuchsia
green
lime
olive
yellow
navy
blue
teal
aqua
orange
aliceblue
antiquewhite
aquamarine
azure
beige
bisque
blanchedalmond
blueviolet
brown
burlywood
cadetblue
chartreuse
chocolate
coral
cornflowerblue
cornsilk
crimson
cyan (synonym of aqua)
darkblue
darkcyan
darkgoldenrod
darkgray
darkgreen
darkgrey
darkkhaki
darkmagenta
darkolivegreen
darkorange
darkorchid
darkred
darksalmon
darkseagreen
darkslateblue
darkslategray
darkslategrey
darkturquoise
darkviolet
deeppink
deepskyblue
dimgray
dimgrey
dodgerblue
firebrick
floralwhite
forestgreen
gainsboro
ghostwhite
gold
goldenrod
greenyellow
grey
honeydew
hotpink
indianred
indigo
ivory
khaki
lavender
lavenderblush
lawngreen
lemonchiffon
lightblue
lightcoral
lightcyan
lightgoldenrodyellow
lightgray
lightgreen
lightgrey
lightpink
lightsalmon
lightseagreen
lightskyblue
lightslategray
lightslategrey
lightsteelblue
lightyellow
limegreen
linen
magenta (synonym of fuchsia)
mediumaquamarine
mediumblue
mediumorchid
mediumpurple
mediumseagreen
mediumslateblue
mediumspringgreen
mediumturquoise
mediumvioletred
midnightblue
mintcream
mistyrose
moccasin
navajowhite
oldlace
olivedrab
orangered
orchid
palegoldenrod
palegreen
paleturquoise
palevioletred
papayawhip
peachpuff
peru
pink
plum
powderblue
rosybrown
royalblue
saddlebrown
salmon
sandybrown
seagreen
seashell
sienna
skyblue
slateblue
slategray
slategrey
snow
springgreen
steelblue
tan
thistle
tomato
turquoise
violet
wheat
whitesmoke
yellowgreen
rebeccapurple

RGB: Combinando Rojo, Verde y Azul

Otra forma de especificar colores es describir una mezcla de colores "básicos", en este caso rojo (Red), verde (Green) y azul (Blue).

Como lo describimos?

Necesitamos indicar la cantidad de cada color en la combinación, lo podemos hacer de dos formas:

  • Con números
    • 0: nada de color
    • 255: máximo de color
  • Como porcentaje
    • 0%: nada de color
    • 100%: máximo de color

Como lo escribimos?

La forma mas fácil de escribirlo si sabemos los valores individuales y dado que hay múltiples formas de indicarlo es:

  • Indicar de que forma vamos a describir el color, en nuestro caso rgb
  • Indicar los 3 valores

Veamos algunos ejemplos

R G B Formato Color
0 0 0 rgb(0, 0, 0)
255 255 255 rgb(255, 255, 255)
255 0 0 rgb(255, 0, 0)
0 255 0 rgb(0, 255, 0)
0 0 255 rgb(0, 0, 255)
255 255 0 rgb(255, 255, 0)
255 0 255 rgb(255, 0, 255)
0 255 255 rgb(0, 255, 255)
128 128 128 rgb(128, 128, 128)
128 0 0 rgb(128, 0, 0)
0 128 0 rgb(0, 128, 0)
0 0 128 rgb(0, 0, 128)
80 160 255 rgb(80, 160, 255)
80 255 160 rgb(80, 255, 160)
255 160 80 rgb(255, 160, 80)
160 255 80 rgb(160, 255, 80)
160 80 255 rgb(160, 80, 255)
255 80 160 rgb(255, 80, 160)
0% 0% 0% rgb(0%, 0%, 0%)
100% 100% 100% rgb(100%, 100%, 100%)
100% 0% 0% rgb(100%, 0%, 0%)
0% 100% 0% rgb(0%, 100%, 0%)
0% 0% 100% rgb(0%, 0%, 100%)
100% 100% 0% rgb(100%, 100%, 0%)
100% 0% 100% rgb(100%, 0%, 100%)
0% 0% 0% rgb(0%, 0%, 0%)
50% 50% 50% rgb(50%, 50%, 50%)
50% 0% 0% rgb(50%, 0%, 0%)
0% 50% 0% rgb(0%, 50%, 0%)
0% 0% 50% rgb(0%, 0%, 50%)
50% 50% 0% rgb(50%, 50%, 0%)
50% 0% 50% rgb(50%, 0%, 50%)

Alternativa: Hexadecimal

Este formato suele estar disponible en herramientas que usan o manipulan colores, es compacta pero difícil de interpretar a menos que entiendas la numeración hexadecimal fluidamente.

La mencionamos porque te la vas a encontrar en muchos lugares y hay que saber que es un formato de color valido, que lo podes usar en lugar de cualquiera de los otros y que hay muchas herramientas que la usan.

Nota muy resumida para los curiosos:

En hexadecimal en lugar de contar del 0 al 9 y al quedarnos sin dígitos ponemos un 1 adelante y empezamos de nuevo como lo hacemos en decimal, se cuenta del 0 a la F, porque tiene como base 16 y no 10 como el decimal, contando en hexadecimal seria algo como: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11 ... 1F, 20 ... 2F, 30 ... F0 ... FF, 100 etc.

Lo que cambia es que el 255 de antes se convierte en FF y ponemos los 3 valores todos juntos luego del símbolo #, que indica que estamos usando este formato, el formato debe tener o 3 o 6 caracteres, de ser necesario llenamos los valores restantes con 0.

Algunos ejemplos de la sección anterior convertidos a formato hexadecimal:

R G B Formato Color
00 00 00 #000000
FF FF FF #FFFFFF
FF 00 00 #FF0000
00 FF 00 #00FF00
00 00 FF #0000FF
FF FF 00 #FFFF00
FF 00 FF #FF00FF
00 FF FF #00FFFF
80 80 80 #808080
80 00 00 #800000
00 80 00 #008000
00 00 80 #000080

HSL: Tono, Saturación y "Liviandad/Brillo"

En esta representación tenemos 3 valores, llamados H (Hue), S (Saturation), L (Lightness).

H
Numero de 0 a 360 (angulo en un circulo de colores), indica el tono base que queremos
S
Porcentaje de saturación del color elegido, 0% va a ser un gris, 100% va a ser el color puro.
L
Porcentaje de liviandad/brillo del color elegido, 0% va a ser negro, 100% va a ser blanco, 50% (y 100% de saturación) va a ser el color puro.

Algunos colores "puros":

hsl(0, 100%, 50%)
hsl(30, 100%, 50%)
hsl(60, 100%, 50%)
hsl(90, 100%, 50%)
hsl(120, 100%, 50%)
hsl(150, 100%, 50%)
hsl(180, 100%, 50%)
hsl(210, 100%, 50%)
hsl(240, 100%, 50%)
hsl(270, 100%, 50%)
hsl(300, 100%, 50%)
hsl(330, 100%, 50%)
hsl(360, 100%, 50%)

Cambiando la saturación:

hsl(0, 0%, 50%)
hsl(0, 25%, 50%)
hsl(0, 50%, 50%)
hsl(0, 75%, 50%)
hsl(0, 100%, 50%)

Cambiando el "brillo":

hsl(0, 100%, 0%)
hsl(0, 100%, 25%)
hsl(0, 100%, 50%)
hsl(0, 100%, 75%)
hsl(0, 100%, 100%)

Alpha: Transparencia/Opacidad

Un ultimo componente del color común a todos los que vimos es la transparencia/opacidad, es decir, cuanto del contenido que se encuentra "detrás" del color que estamos mostrando es visible.

La transparencia/opacidad va de 0% (ausencia absoluta de color, como un vidrio) a 100% (color solido, nada se "transluce")

Cuando indicamos la transparencia en rgb y hsl puede ser:

  • Numero entre 0 y 1
  • Porcentaje de 0% a 100%

Ejemplos:

/* transparente */
rgba(255, 0, 153, 0)
rgba(255, 0, 153, 0%)

/* semi translucido */
rgba(255, 0, 153, 0.5)
rgba(255, 0, 153, 50%)

/* opaco */
rgba(255, 0, 153, 1)
rgba(255, 0, 153, 100%)
/* transparente */
hsla(240, 100%, 50%, 0)
hsla(240, 100%, 50%, 0%)

/* semi translucido */
hsla(240, 100%, 50%, 0.5)
hsla(240, 100%, 50%, 50%)

/* opaco */
hsla(240, 100%, 50%, 1)
hsla(240, 100%, 50%, 100%)

En el formato hexadecimal simplemente agregamos dos dígitos mas al final entre 00 (0%) y FF (100%) indicando el nivel de transparencia

/* transparente */
#FFFFFF00

/* semi translucido */
#FFFFFF80

/* opaco */
#FFFFFFFF

Y así llegamos al final, no hace falta que intentes aprender, entender o memorizar esto, solo saber que hay distintas formas de especificar colores, mas o menos cuales son, para el resto esta tu motor de búsqueda amigo.

Riak Core Tutorial Part 2: Starting

This is part of a series, see the previous one at Riak Core Tutorial Part 1: Setup

Creating our Project

Now that we have our tools and our template installed we can start by asking rebar3 to create a new project we will call tanodb using the riak_core template we just installed:

rebar3 new rebar3_riak_core name=tanodb

If it fails saying it can't find rebar3 check that it's in your $PATH environment variable and that you have Erlang activated.

The output should be something like this:

===> Writing tanodb/apps/tanodb/src/tanodb.app.src
===> Writing tanodb/apps/tanodb/src/tanodb.erl
===> Writing tanodb/apps/tanodb/src/tanodb_app.erl
===> Writing tanodb/apps/tanodb/src/tanodb_sup.erl
===> Writing tanodb/apps/tanodb/src/tanodb_console.erl
===> Writing tanodb/apps/tanodb/src/tanodb_vnode.erl
===> Writing tanodb/rebar.config
===> Writing tanodb/.editorconfig
===> Writing tanodb/.gitignore
===> Writing tanodb/README.rst
===> Writing tanodb/Makefile
===> Writing tanodb/config/admin_bin
===> Writing tanodb/priv/01-tanodb.schema
===> Writing tanodb/config/advanced.config
===> Writing tanodb/config/vars.config
===> Writing tanodb/config/vars_dev1.config
===> Writing tanodb/config/vars_dev2.config
===> Writing tanodb/config/vars_dev3.config

Note

The content of this chapter is in the 01-template branch.

https://gitlab.com/marianoguerra/tanodb/tree/01-template

Building and Running

Before explaining what the files mean so you get an idea what just happened let's run it!

cd tanodb
make
make console

make runs rebar3 commands to build a release of our project, for that it uses a tool called relx.

The initial build may take a while since it has to fetch all the dependencies and build them.

After the release is built (you can check the result by inspecting the folder _build/default/rel/tanodb/) we can run it.

When we run make console we get some noisy output that should end with something like this:

Eshell V9.3  (abort with ^G)
(tanodb@127.0.0.1)1>

This is the Erlang shell, something like a REPL connected to our system, we now can test our system by calling tanodb:ping() on it.

(tanodb@127.0.0.1)1> tanodb:ping().
{pong,1347321821914426127719021955160323408745312813056}

The response is the atom pong and a huge number that we will explain later, but to make it short, it's the id of the process that replied to us.

Exploring the Template Files

The template created a lot of files and if you are like me, you don't like things that make magic and don't explain what's going on, that's why we will get a brief overview of the files created here.

First this files are created:

apps/tanodb/src/tanodb.app.src
apps/tanodb/src/tanodb.erl
apps/tanodb/src/tanodb_app.erl
apps/tanodb/src/tanodb_sup.erl
apps/tanodb/src/tanodb_console.erl
apps/tanodb/src/tanodb_vnode.erl

Those are the meat of this project, the source code we start with, if you know a little of erlang you will recognice many of them, let's explain them briefly, if you think you need more information I recommend you this awesome book which you can read online: Learn You Some Erlang for great good!

tanodb.app.src
This file is "The Application Resource File", you can read it, it's quite self descriptive. You can read more about it in the Building OTP Applications Section of Learn You Some Erlang or in the man page for app in the Erlang documentation.
tanodb.erl
This file is the main API of our application, here we expose all the things you can ask our application to do, for now it can only handle the ping() command but we will add some more in the future.
tanodb_app.erl
This file implements the application behavior it's a set of callbacks that the Erlang runtime calls to start and stop our application.
tanodb_sup.erl
This file implements the supervisor behavior it's a set of callbacks that the Erlang runtime calls to build the supervisor hierarchy.
tanodb_console.erl
This file is specific to riak_core, it's a set of callbacks that will be called by the tanodb-admin command.
tanodb_vnode.erl
This file is specific to riak_core, it implements the riak_code_vnode behavior, which is a set of callbacks that riak_core will call to accomplish different tasks, it's the main file we will edit to add new features.

Those were the source code files, but the template also created other files, let's review them

rebar.config
This is the file that rebar3 reads to get information about our project like dependencies and build configuration, you can read more about it on the rebar3 documentation
.editorconfig
This file describes the coding style for this project, if your text editor understands editorconfig files then it will change it's setting for this project to the ones described in this file, read more about editor config on the editorconfig website
.gitignore
A file to tell git which files to ignore from the repository.
README.rst
The README of the project
Makefile
A make file with some targets that will make it easier to achieve some complex tasks without copying and pasting too much.
config/admin_bin
A template for the tanodb-admin command.
priv/01-tanodb.schema
The cuttlefish schema file that describes what configuration our application supports, it starts with some example configuration fields that we will use as the application grows.
config/advanced.config
This file is where we configure some advanced things of our application that don't go on our tanodb.config file, here we configure riak_core and our logging library
config/vars.config
This file contains variables used by relx to build a release, you can read more about it in the rebar3 release documentation

The following files are like vars.config but with slight differences to allow running more than one node on the same machine:

config/vars_dev1.config
config/vars_dev2.config
config/vars_dev3.config

Normally when you have a cluster for your application one operating system instance runs one instance of your application and you have many operating system instances, but to test the clustering features of riak_core we will build 3 releases of our application using offsets for ports and changing the application name to avoid collisions.

Those are all the files, follow the links to know more about them.

Playing with Clustering

Before starting to add features, let's first play with clustering so we understand all those config files above work.

Build 3 releases that can run on the same machine:

make devrel

This will build 3 releases of the application using different parameters (the dev1, dev2 and dev3 files we saw earlier) and will place them under:

_build/dev1
_build/dev2
_build/dev3

This is achived by using the profiles feature from rebar3.

Now open 3 consoles and run the following commands one on each console:

make dev1-console
make dev2-console
make dev3-console

This will start the 3 nodes but they won't know about each other, for them to know about each other we need to "join" them, that is to tell one of them about the other two, this is achieved using the tanodb-admin command, here is how you should run it manually (don't run them):

_build/dev2/rel/tanodb/bin/tanodb-admin cluster join tanodb1@127.0.0.1
_build/dev3/rel/tanodb/bin/tanodb-admin cluster join tanodb1@127.0.0.1

We tell dev2 and dev3 to join tanodb1 (dev1), to make this easier and less error prone run the following command:

make devrel-join

Now let's check the status of the cluster:

make devrel-status

You can read the Makefile to get an idea of what those commands do, in this case devrel-status does the following:

_build/dev1/rel/tanodb/bin/tanodb-admin member-status

You should see something like this:

================================= Membership ===============
Status     Ring    Pending    Node
------------------------------------------------------------
joining     0.0%      --      'tanodb2@127.0.0.1'
joining     0.0%      --      'tanodb3@127.0.0.1'
valid     100.0%      --      'tanodb1@127.0.0.1'
------------------------------------------------------------
Valid:1 / Leaving:0 / Exiting:0 / Joining:2 / Down:0

It should say that 3 nodes are joining, now check the cluster plan:

make devrel-cluster-plan

The output should be something like this:

=============================== Staged Changes ==============
Action         Details(s)
-------------------------------------------------------------
join           'tanodb2@127.0.0.1'
join           'tanodb3@127.0.0.1'
-------------------------------------------------------------


NOTE: Applying these changes will result in 1 cluster transition

#############################################################
                         After cluster transition 1/1
#############################################################

================================= Membership ================
Status     Ring    Pending    Node
-------------------------------------------------------------
valid     100.0%     34.4%    'tanodb1@127.0.0.1'
valid       0.0%     32.8%    'tanodb2@127.0.0.1'
valid       0.0%     32.8%    'tanodb3@127.0.0.1'
-------------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

WARNING: Not all replicas will be on distinct nodes

Transfers resulting from cluster changes: 42
  21 transfers from 'tanodb1@127.0.0.1' to 'tanodb3@127.0.0.1'
  21 transfers from 'tanodb1@127.0.0.1' to 'tanodb2@127.0.0.1'

Now we can commit the plan:

make devrel-cluster-commit

Which should say something like:

Cluster changes committed

Now riak_core started an internal process to join the nodes to the cluster, this involve some complex processes that we will explore in the following chapters.

You should see on the consoles where the nodes are running that some logging is happening describing the process.

Check the status of the cluster again:

make devrel-status

You can see the vnodes transfering, this means the content of some virtual nodes on one tanodb node are being transferred to another tanodb node:

================================= Membership =============
Status     Ring    Pending    Node
----------------------------------------------------------
valid      75.0%     34.4%    'tanodb1@127.0.0.1'
valid       9.4%     32.8%    'tanodb2@127.0.0.1'
valid       7.8%     32.8%    'tanodb3@127.0.0.1'
----------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

At some point you should see something like this, which means that the nodes are joined and balanced:

================================= Membership ==============
Status     Ring    Pending    Node
-----------------------------------------------------------
valid      34.4%      --      'tanodb1@127.0.0.1'
valid      32.8%      --      'tanodb2@127.0.0.1'
valid      32.8%      --      'tanodb3@127.0.0.1'
-----------------------------------------------------------
Valid:3 / Leaving:0 / Exiting:0 / Joining:0 / Down:0

When you are bored you can stop them:

make devrel-stop

Building a Production Release

Even when our application doesn't have the features to merit a production release we are going to learn how to do it here since you can later do it at any step and get a full release of the app:

make prod-release

In that command rebar3 runs the release task using the prod profile, which has some configuration differences with the dev profiles we use so that it builds something we can unpack and run on another operating system without installing anything.

Let's package our release:

cd _build/prod/rel
tar -czf tanodb.tgz tanodb tanodb_config
cd -
mv _build/prod/rel/tanodb.tgz .

You can copy it to a clean OS and run:

tar -xzf tanodb.tgz
./tanodb/bin/tanodb console

And it runs!

Note

You should build the production release on the same operating system version you are intending to run it to avoid version problems, the main source of headaches are C extensions disagreeing on libc versions and similar.

So, even when you could build it on a version that is close and test it it's better to build releases on the same version to avoid problems. More so if you are packaging the Erlang runtime with the release as we are doing here.

Wrapping Up

Now you know how to create a riak_core app from a template, how to build a release and run it, how to build releases for a development cluster, run the nodes, join them and inspect the cluster status and how to build a production release and run it on a fresh server.

Riak Core Tutorial Part 1: Setup

This is the first chapter in a series that will explore how to use riak_core to build a distributed key-value store.

We first need to have Erlang installed and rebar3 installed.

The Easy Way

If you don't have Erlang installed or you don't have problem to install the latest one system wide you can try installing it with your package manager:

  • For Homebrew on OS X: brew install erlang
  • For MacPorts on OS X: port install erlang
  • For Ubuntu and Debian: apt-get install erlang
  • For Fedora: yum install erlang
  • For FreeBSD: pkg install erlang

Please check that the package version is 20.x, if not, check for instructions on how to install the Erlang Solutions package for Ubuntu, CentOS, Mac OS X, Debian or Fedora here: https://www.erlang-solutions.com/resources/download.html

Setting up rebar3

Now we have Erlang, we need a build tool, we are going to use rebar3:

# download rebar3 to our bin directory
wget https://s3.amazonaws.com/rebar3/rebar3 -O $HOME/bin/rebar3

# set execution permissions for our user
chmod u+x rebar3

Just in case you have problems running the rebar3 commands with a different version, here's the version I'm using:

rebar3 version

Output:

rebar 3.5.0 on Erlang/OTP 20 Erts 9.2

Install Riak Core Rebar3 Template

To create a Riak Core project from scratch we will use a template called rebar3_template_riak_core.

we need to clone its repo in a place where rebar3 can see it:

mkdir -p ~/.config/rebar3/templates
git clone https://github.com/marianoguerra/rebar3_template_riak_core.git ~/.config/rebar3/templates/rebar3_template_riak_core

The Hard Way: Building Erlang with kerl

Note

If you installed Erlang with the instructions above, skip until the Test that Everything Works section below.

If you have or want to have more than one version running side by side you can use kerl, from its github README:

Easy building and installing of Erlang/OTP instances.

Kerl aims to be shell agnostic and its only dependencies, excluding what's
required to actually build Erlang/OTP, are curl and git.

Note

On Mac you can install it with homebrew: brew install kerl

First we need to fetch kerl:

# create bin folder in our home directory if it's not already there
mkdir -p ~/bin

# cd to it
cd ~/bin

# download kerl script
curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl

# set execution permitions for our user
chmod u+x kerl

You will need to add ~/bin to your PATH variable so your shell can find the kerl script, you can do it like this in your shell:

# set the PATH environment variable to the value it had before plus a colon
# (path separator) and a new path which points to the bin folder we just
# created
PATH=$PATH:$HOME/bin

If you want to make this work every time you start a shell you need to put it it the rc file of your shell of choice, for bash it's ~/.bashrc, for zsh it's ~/.zshrc, you will have to add a line like this:

export PATH=$PATH:$HOME/bin

After this, start a new shell or source your rc file so that it picks up your new PATH variable, you can check that it's set correctly by running:

echo $PATH

And checking in the output if $HOME/bin is there (notice that $HOME will be expanded to the actual path).

Building an Erlang release with kerl

We have kerl installed and available in our shell, now we need to build an Erlang release of our choice, for this we will need a compiler and other tools and libraries needed to compile it:

This are instructions on ubuntu 17.10, check the names for those packages on your distribution.

# required: basic tools and libraries needed
# (compiler, curses for the shell, ssl for crypto)
sudo apt-get -y install build-essential m4 libncurses5-dev libssl-dev

# optonal: if you want odbc support (database connectivity)
sudo apt-get install unixodbc-dev

# optonal: if you want pdf docs you need apache fop and xslt tools and java (fop is a java project)
sudo apt-get install -y fop xsltproc default-jdk

# optional: if you want to build jinterface you need a JDK
sudo apt-get install -y default-jdk

# optional: if you want wx (desktop GUI modules)
sudo apt-get install -y libwxgtk3.0-dev

Now that we have everything we need we can finally build our Erlang release.

First we fetch an updated list of releases:

kerl update releases

The output in my case:

The available releases are:

R10B-0 R10B-10 R10B-1a R10B-2 R10B-3 R10B-4 R10B-5 R10B-6 R10B-7 R10B-8
R10B-9 R11B-0 R11B-1 R11B-2 R11B-3 R11B-4 R11B-5 R12B-0 R12B-1 R12B-2 R12B-3
R12B-4 R12B-5 R13A R13B01 R13B02-1 R13B02 R13B03 R13B04 R13B R14A R14B01
R14B02 R14B03 R14B04 R14B_erts-5.8.1.1 R14B R15B01 R15B02
R15B02_with_MSVCR100_installer_fix R15B03-1 R15B03 R15B
R16A_RELEASE_CANDIDATE R16B01 R16B02 R16B03-1 R16B03 R16B 17.0-rc1 17.0-rc2
17.0 17.1 17.3 17.4 17.5 18.0 18.1 18.2.1 18.2 18.3 19.0 19.1 19.2 19.3
20.0 20.1 20.2 20.3

Let's build the 20.3 version:

# this will take a while
kerl build 20.3 20.3

And install it:

kerl install 20.3 ~/bin/erl-20.3

Now everytime we want to use this version of Erlang we need to run:

. $HOME/bin/erl-20.3/activate

Test that Everything Works

We have installed several tools:

kerl
Let's you install multiple Erlang releases that can live side by side
Erlang 20.3
The version of erlang we are going to be using
Rebar 3
Our build tool
rebar3_template_riak_core
Rebar 3 Template that will make it easy to setup fresh riak_core projects for experimentation

Now we need to check that everything is setup correctly, we will do that by creating a template and building it.

Remember to have $HOME/bin in your $PATH and Erlang 20.3 activated, cd to a folder of your choice to hold this project and run:

rebar3 new rebar3_riak_core name=akv

Output should be similar to this one:

===> Writing akv/apps/akv/src/akv.app.src
===> Writing akv/apps/akv/src/akv.erl
===> Writing akv/apps/akv/src/akv_app.erl
===> Writing akv/apps/akv/src/akv_sup.erl
===> Writing akv/apps/akv/src/akv_console.erl
===> Writing akv/apps/akv/src/akv_vnode.erl
===> Writing akv/rebar.config
===> Writing akv/.editorconfig
===> Writing akv/.gitignore
===> Writing akv/README.rst
===> Writing akv/Makefile
===> Writing akv/config/admin_bin
===> Writing akv/priv/01-akv.schema
===> Writing akv/config/advanced.config
===> Writing akv/config/vars.config
===> Writing akv/config/vars_dev1.config
===> Writing akv/config/vars_dev2.config
===> Writing akv/config/vars_dev3.config

Now let's try to build it:

cd akv
make

Output is to long to list, after it ends, near the end you should see this line:

===> release successfully created!

Now let's try to run it:

make console

Last lines should be:

Eshell V9.3  (abort with ^G)
(akv@127.0.0.1)1>

You can exit with q(). and pressing enter or hitting Ctrl-C twice.

We're ready to start!

Creemos en la Web: Reusando HTML (de otros)

En la sección anterior vimos como reusar estilo creado por otras personas.

Como vimos, muchas paginas comparten distintos componentes y yendo un nivel mas arriba, muchas paginas tienen incluso una estructura similar, por ejemplo blogs, paginas principales de un diario, de un producto, o de un sitio de ventas online.

Si bien no hay una forma simple de reusar HTML sin acudir a funcionalidades mas avanzadas que requieran programar, existe lo que usualmente se llaman templates (plantillas), que son paginas completas o secciones grandes de paginas para copiar y modificar el contenido de manera de no empezar de cero.

En esta sección vamos a explorar algunos de esos templates, en este caso, los disponibles en la pagina del proyecto bootstrap: https://getbootstrap.com/docs/4.1/examples/

Cover

Probemos uno de los ejemplos llamado Cover, copia y pega el siguiente HTML en un proyecto thimble nuevo:

<!doctype html>
<html lang="en">
  <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <title>Titulo de Pagina</title>

        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

        <link href="style.css" rel="stylesheet">
  </head>

  <body class="text-center">

        <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
          <header class="masthead mb-auto">
                <div class="inner">
                  <h3 class="masthead-brand">Nombre</h3>
                  <nav class="nav nav-masthead justify-content-center">
                        <a class="nav-link active" href="#">Principal</a>
                        <a class="nav-link" href="#">Link 1</a>
                        <a class="nav-link" href="#">Link 2</a>
                  </nav>
                </div>
          </header>

          <main role="main" class="inner cover">
                <h1 class="cover-heading">Título</h1>
                <p class="lead">Descripción.</p>
                <p class="lead">
                  <a href="#" class="btn btn-lg btn-secondary">Acción Principal</a>
                </p>
          </main>

          <footer class="mastfoot mt-auto">
                <div class="inner">
                  <p>Template "Cover" para <a href="https://getbootstrap.com/">Bootstrap</a>, por <a href="https://twitter.com/mdo">@mdo</a>.</p>
                </div>
          </footer>
        </div>

  </body>
</html>

Y el siguiente CSS en el archivo style.css del proyecto:

/*
* Globals
*/

/* Links */
a,
a:focus,
a:hover {
  color: #fff;
}

/* Custom default button */
.btn-secondary,
.btn-secondary:hover,
.btn-secondary:focus {
  color: #333;
  text-shadow: none; /* Prevent inheritance from `body` */
  background-color: #fff;
  border: .05rem solid #fff;
}


/*
* Base structure
*/

html,
body {
  height: 100%;
  background-color: #333;
}

body {
  display: -ms-flexbox;
  display: flex;
  color: #fff;
  text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
  box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
}

.cover-container {
  max-width: 42em;
}


/*
* Header
*/
.masthead {
  margin-bottom: 2rem;
}

.masthead-brand {
  margin-bottom: 0;
}

.nav-masthead .nav-link {
  padding: .25rem 0;
  font-weight: 700;
  color: rgba(255, 255, 255, .5);
  background-color: transparent;
  border-bottom: .25rem solid transparent;
}

.nav-masthead .nav-link:hover,
.nav-masthead .nav-link:focus {
  border-bottom-color: rgba(255, 255, 255, .25);
}

.nav-masthead .nav-link + .nav-link {
  margin-left: 1rem;
}

.nav-masthead .active {
  color: #fff;
  border-bottom-color: #fff;
}

@media (min-width: 48em) {
  .masthead-brand {
        float: left;
  }
  .nav-masthead {
        float: right;
  }
}


/*
* Cover
*/
.cover {
  padding: 0 1.5rem;
}
.cover .btn-lg {
  padding: .75rem 1.25rem;
  font-weight: 700;
}


/*
* Footer
*/
.mastfoot {
  color: rgba(255, 255, 255, .5);
}

Debería verse algo así:

/galleries/cew/7/01-cover.png

Una vez publicado:

/galleries/cew/7/02-cover-preview.png

Actividades propuestas:

  1. Intenta cambiar el contenido para presentar un proyecto o producto que te interese.
  2. Intenta cambiarlo para que sea fondo claro con contenido oscuro.
    • Agregando estilo al final de style.css
    • Cambiando el estilo existente en style.css

Pagina Principal

Esta pagina es bastante mas larga así que vamos a probar una forma nueva.

Podes ver el resultado visitando https://marianoguerra.github.io/creemos-en-la-web/paginas/landing/

En la pagina principal hace click derecho en cada imagen y selecciona la opción "Descargar imagen como..." o similar.

Descarga todas las imágenes.

Hace click en la pagina y presiona las teclas Ctrl y "u" a la vez, esto debería abrirte una ventana nueva con el HTML la pagina. Otra forma de hacerlo en algunos navegadores es haciendo click derecho con el mouse sobre la pagina y seleccionando la opción "Ver Código" o similar.

Copia el HTML en un proyecto nuevo de thimble.

Visita la dirección: https://marianoguerra.github.io/creemos-en-la-web/paginas/landing/style.css

Copia el CSS en el archivo style.css del proyecto.

Agrega las imágenes que descargaste a un nuevo directorio llamado img, un video que muestra como:

Actividades propuestas:

  1. Intenta cambiar el contenido para presentar un proyecto o producto que te interese.
  2. Intenta cambiarlo las imágenes
    • Manteniendo los nombres de las imágenes existentes (subiendo nuevas imágenes con nombres existentes)
    • Cambiando el nombre de las imágenes en el HTML (subiendo nuevas imágenes con nombres nuevos)

Creemos en la Web: Reusando estilo (de otros)

Introduccion

En las secciones anteriores aprendimos como reusar el estilo guardándolo en un archivo separado y cargándolo en múltiples paginas.

A medida que vamos creando mas y mas paginas empiezan a surgir cosas comunes que se usan en casi cualquier proyecto.

Si miras con atención las paginas que visitas vas a ver que hay ciertos componentes que se repiten.

De esto te podrás imaginar que con tanto reusar estilos y llevarlos de un proyecto a otro a alguien se le habrá ocurrido la idea de hacer un archivo de estilos lo suficientemente genérico para que pueda ser el estilo inicial de mucha gente que quiere crear una pagina web nueva pero no quiere estar definiendo de cero todo cada vez que empieza.

Imaginas bien!

Hay varios, pero el mas conocido se llama bootstrap, y nos permite empezar nuestras paginas sin tener que preocuparnos por detalles que al fin del día no son tan importantes.

Mas interesante, es que como este proyecto estandariza los nombres de clases para cada estilo, hay gente que crea nuevos estilos que se cargan "sobre" bootstrap y que le cambian el aspecto sin que nosotros tengamos que hacer nada mas que agregar una linea a nuestro HTML!

Podes ver algunos ejemplos en https://bootswatch.com/

Incluyendo Bootstrap

Vamos a ver como usar esto, empecemos con un proyecto nuevo en thimble con una pagina básica:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
  </head>

  <body>
        <h1>Esto es un título</h1>

        <p>Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

        <p>Esto es otro párrafo</p>

        <p>
          Una lista no ordenada:
        </p>

        <ul>
          <li>Manzana</li>
          <li>Durazno</li>
          <li>Banana</li>
        </ul>

        <p>Una lista ordenada:</p>

        <ol>
          <li>Uno</li>
          <li>Dos</li>
          <li>Tres</li>
        </ol>

        <p>Un link a <a href="https://google.com">Google</a></p>

  </body>
</html>

Nuestra pagina de siempre, no muy linda de ver:

/galleries/cew/6/01-base.png

Ahora agregamos la hoja de estilo de bootstrap en el <head> de la pagina, debajo del tag <title>:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

Y podemos ver que ya cambio un poco:

/galleries/cew/6/02-base-bootstrap.png

Un tour por algunos componentes de bootstrap

Pero si fuera solo por eso entonces no seria tan útil, esto es solo el contenido base, bootstrap nos provee con muchos componentes estandard para usar, empecemos por las alertas:

Alertas

Agreguemos el siguiente HTML al <body> de nuestro proyecto:

<h2>Alertas</h2>

<div class="alert alert-primary" role="alert">
  Alerta principal (primary)
</div>
<div class="alert alert-secondary" role="alert">
  Alerta secundario (secondary)
</div>
<div class="alert alert-success" role="alert">
  Alerta exito (success)
</div>
<div class="alert alert-danger" role="alert">
  Alerta peligro (danger)
</div>
<div class="alert alert-warning" role="alert">
  Alerta advertencia (warning)
</div>
<div class="alert alert-info" role="alert">
  Alerta informacion (info)
</div>
<div class="alert alert-light" role="alert">
  Alerta claro (light)
</div>
<div class="alert alert-dark" role="alert">
  Alerta oscuro (dark)
</div>

<h2>Alertas con mas contenido</h2>

<div class="alert alert-info" role="alert">
  <h4 class="alert-heading">Titulo</h4>
  <p>Contenido principal.</p>
  <hr>
  <p class="mb-0">Contenido despues del separador.</p>
</div>

Debería verse algo así:

/galleries/cew/6/03-bs-alerts.png

Badges

Badges se traduce a medalla o distintivo, es mas fácil entender que son viéndolos que por la palabra, así que agreguemos el siguiente HTML a nuestra pagina:

<h2>Badges</h2>

<h3>Estandar</h3>

<div class="m-3">
  <span class="badge badge-primary">Principal</span>
  <span class="badge badge-secondary">Secundario</span>
  <span class="badge badge-success">Exito</span>
  <span class="badge badge-danger">Peligro</span>
  <span class="badge badge-warning">Advertencia</span>
  <span class="badge badge-info">Informacion</span>
  <span class="badge badge-light">Claro</span>
  <span class="badge badge-dark">Oscuro</span>
</div>

<h3>Pill Badges (Pastillas)</h3>

<div class="m-3">
  <span class="badge badge-pill badge-primary">Principal</span>
  <span class="badge badge-pill badge-secondary">Secundario</span>
  <span class="badge badge-pill badge-success">Exito</span>
  <span class="badge badge-pill badge-danger">Peligro</span>
  <span class="badge badge-pill badge-warning">Advertencia</span>
  <span class="badge badge-pill badge-info">Informacion</span>
  <span class="badge badge-pill badge-light">Claro</span>
  <span class="badge badge-pill badge-dark">Oscuro</span>
</div>

<h3>Links</h3>

<div class="m-3">
  <a href="#" class="badge badge-primary">Principal</a>
  <a href="#" class="badge badge-secondary">Secundario</a>
  <a href="#" class="badge badge-success">Exito</a>
  <a href="#" class="badge badge-danger">Peligro</a>
  <a href="#" class="badge badge-warning">Advertencia</a>
  <a href="#" class="badge badge-info">Informacion</a>
  <a href="#" class="badge badge-light">Claro</a>
  <a href="#" class="badge badge-dark">Oscuro</a>
</div>

Como veras rodeo los ejemplos con un div para darle mas margen, pero no uso style="margin: ..." como hasta acá, sino que uso una clase que bootstrap provee que estandariza los margenes en 6 niveles (m-0, m-1, ..., m-5). De esta manera si usamos estas clases en nuestras paginas los margenes serán consistentes y luego podremos ajustarlos en un solo lugar (la definición de .m-0, ..., .m-5 en nuestra hoja de estilos)

El resultado es algo así:

/galleries/cew/6/04-badges.png

Barra de Navegacion

Otro componente muy útil y versátil son las barras de navegación, suelen usarse en la parte superior de la pagina y en cualquier sección que tiene mas de un elemento para mostrar, como los tabs del navegador web.

<h2>Barra de Navegacion</h2>

<h3>Usando tags de lista</h3>

<ul class="nav">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#">Inactivo</a>
  </li>
</ul>

<h3>Usando el tag nav</h3>

<nav class="nav">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Justificado al centro</h3>

<nav class="nav justify-content-center">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Justificado a la derecha</h3>

<nav class="nav justify-content-end">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Tabs</h3>

<nav class="nav nav-tabs">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Pills</h3>

<nav class="nav nav-pills">
  <a class="nav-link active" href="#">Activo</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" href="#">Inactivo</a>
</nav>

<h3>Tabs Expandidas (Lista)</h3>

<ul class="nav nav-tabs nav-fill">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#">Inactivo</a>
  </li>
</ul>

<h3>Pills Expandidas (Nav)</h3>

<nav class="nav nav-pills nav-fill">
  <a class="nav-item nav-link active" href="#">Activo</a>
  <a class="nav-item nav-link" href="#">Link</a>
  <a class="nav-item nav-link" href="#">Link</a>
  <a class="nav-item nav-link disabled" href="#">Inactivo</a>
</nav>

El resultado es algo así:

/galleries/cew/6/05-nav.png

Luego de explorar los componentes copiando y pegando los ejemplos intenta modificarlos, agregar mas items, eliminar algunos, reordenarlos etc.

Si te sentís aventurero, intenta mirar un ejemplo y luego tiperarlo por completo solo mirando el ejemplo cuando te olvides de algo o algo no funcione.

Este ejercicio es una buena forma de memorizar los conceptos básicos y de ver cuales partes pensabas que entendías pero todavía algún detalle se escapa.

Creemos en la Web: Lo espacial es invisible a los ojos

En la sección previa (Creemos en la Web: CSS y cosas por el estilo) terminamos con una pagina que se veía así:

/galleries/cew/4/05-link.png

Que tendríamos que hacer si quisiéramos que la palabra lista tuviera la clase llamativo?

Hasta ahora para aplicar una clase a una palabra o conjunto de palabras aprovechábamos un tag que ya estaba ahí (b, i o li), pero dos de ellos aplican un formato que no queremos, y el otro solo funciona con listas.

Como podemos hacer para definir una selección para aplicarle atributos pero que en si no signifique nada?

Para eso hay un tag llamado span que en ingles significa algo así como tramo, palmo, lapso o mas detallado: la extensión completa de algo de punta a punta; la cantidad de espacio que cubre algo.

Osea, demarca el comienzo y fin de algo, su extensión y nada mas. Este tag no significa nada en si mismo, solo lo usamos para demarcar una región a la cual queremos referirnos para algo.

Si, muy difuso, vamos a algo mas tangible, en nuestro caso queremos usar span para demarcar la palabra lista y aplicarle la clase llamativo:

<p>
    Una <span class="llamativo">lista</span> no ordenada:
</p>

Y

<p>Una <span class="llamativo">lista</span> ordenada:</p>

Logrado nuestro objetivo pasamos al siguiente desafió, queremos resaltar el segundo párrafo poniéndole un borde, para eso vamos a usar un conjunto de atributos CSS nuevos:

<p style="border-width: 1px; border-style: solid; border-color: red;">Esto es otro párrafo</p>

Es un poco largo para solo decir "quiero un border rojo, de 1 pixel de ancho y solido", por suerte hay una versión abreviada:

<p style="border: 1px solid red;">Esto es otro párrafo</p>

No se vos, pero a mi me parece que el texto esta muy pegado al borde rojo, preferiría que tuviera un poco mas de espacio.

Para eso usamos una de dos formas de darle mas "espacio" a un tag, una es el espacio "interno" (entre el borde y el contenido) y otro es el espacio "externo" (entre el borde y sus vecinos).

El espacio interno en ingles se llama padding (se traduce "relleno"), el espacio externo en ingles se llama margin (se traduce "margen").

Estos dos atributos los vas a usar mucho en el día a día y como se usan mucho hay formas abreviadas y mas especificas de usarlos, empecemos con la abreviada que es la que nos sirve a nosotros.

<p style="padding: 8px; border: 1px solid red;">Esto es otro párrafo</p>

Eso esta un poco mejor!

Ya que estamos haciéndonos espacio, demosle un poco mas de espacio exterior:

<p style="margin: 8px; padding: 8px; border: 1px solid red;">Esto es otro párrafo</p>

Un poco mejor, pero si bien le da espacio con respecto al párrafo anterior y el siguiente, también tiene un margen izquierdo que lo "desalinea" con respecto al resto de los tags.

Para poder especificar margenes y rellenos con mas nivel de detalle vamos a necesitar usar las versiones menos abreviadas, ambas aplican tanto a margin como a padding así que las vemos juntas:

Primero la que ya vimos:

margin: 8px;
padding: 8px;

Esto aplica a los 4 lados del tag, el siguiente nos permite especificar dos valores:

margin: 8px 0px;
padding: 8px 0px;

El primer valor es para arriba y abajo, el segundo valor para la izquierda y la derecha.

El no abreviado nos permite especificar los cuatro valores:

margin: 8px 0px 0px 0px;
padding: 8px 0px 0px 0px;

Y el orden es como las agujas del reloj:

margin: <arriba> <derecha> <abajo> <izquierda>;
padding: <arriba> <derecha> <abajo> <izquierda>;

Pero que pasa si solo queremos especificar uno de ellos? tenemos que poner en 0 a todos los otros siempre? Por suerte no, hay otra forma de ser aun mas especifico, diciendole cual margen o relleno queremos definir:

margin-top: 8px;    /* top: arriba */
margin-right: 0px;  /* right: derecha */
margin-bottom: 0px; /* bottom: abajo */
margin-left: 0px;   /* left: izquierda */

Como veras a la derecha de las definiciones puse las traducciones entre /* y */, si escribís eso en tu CSS va a funcionar. Esto es porque son comentarios, una forma de agregar notas en el código CSS que el navegador ignora ya que es para los humanos.

Si querés escribir comentarios en HTML es un poco distinto:

<!-- Esto es un comentario, puede ir en cualquier lado y el navegador
     lo va a ignorar, puede extenderse mas de una linea.

     suele ser útil cuando queremos esconder un tag pero no borrarlo.
-->

Volviendo al tag span, este tag sirve solo para rodear segmentos de texto, que pasa si queremos agregar un borde con relleno a los primeros 3 párrafos?

Agregar borde a cada párrafo no sirve, porque lo que queremos es "rodear" los 3 párrafos con un borde y el tag span solo sirve para rodear texto.

Obviamente este problema se resuelve con un nuevo tag, se llama div y cumple la misma función que span pero se diferencia en que dentro de el puede haber otros tags.

Probemoslo rodeando los 3 primeros párrafos con un borde verde y relleno de 8 pixeles:

<div style="border: 1px solid green; padding: 8px">
  <p>Esto es un párrafo, la siguiente palabra es en
     <b class="llamativo">negrita</b>, la siguiente en
     <i class="llamativo">itálica</i>
  </p>

  <p style="margin: 8px; padding: 8px; border: 1px solid red;">
    Esto es otro párrafo
  </p>

  <p>
    Una <span class="llamativo">lista</span> no ordenada:
  </p>
</div>

El resultado queda algo así (tené en cuenta que esta sección ya tiene CSS así que en Thimble se va a ver un poco distinto):

Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica

Esto es otro párrafo

Una lista no ordenada:

Con lo que aprendimos en esta sección podemos arreglar una cosa que no quedaba del todo bien.

Quizás notaste que al aplicar la clase llamativo a los ítems de la lista, el marcador de la izquierda también se volvió llamativo, si queremos que solo el contenido del ítem sea llamativo y no el ítem completo, podemos hacer uso de nuestro nuevo amigo el tag span para aplicar la clase solo al contenido.

Pasamos de:

<ul>
  <li class="llamativo">Manzana</li>
  <li>Durazno</li>
  <li class="llamativo">Banana</li>
</ul>
  • Manzana
  • Durazno
  • Banana

A:

<ul>
  <li><span class="llamativo">Manzana<span></li>
  <li>Durazno</li>
  <li><span class="llamativo">Banana<span></li>
</ul>
  • Manzana
  • Durazno
  • Banana

Y Problema resuelto.

Creemos en la Web: CSS y cosas por el estilo

En la sección previa (Creemos en la Web: HTML atributos y meta datos) vimos como usar HTML para definir la estructura y el contenido de nuestras paginas web, pero seamos sinceros, el aspecto deja bastante que desear.

Para poder hacer nuestras paginas mas agradables vamos a aprender el segundo lenguaje: CSS, el cual sirve para describir el aspecto y disposición del contenido que definamos con HTML.

Apagando las luces

Vamos a empezar cambiando un poco de color, que pasa si queremos hacer una pagina "invertida"? donde el fondo es oscuro y el texto claro.

Creemos un proyecto nuevo con el siguiente contenido:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
  </head>

  <body>
        <h1>Esto es un título</h1>

        <p>Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

        <p>Esto es otro párrafo</p>

        <p>
          Una lista no ordenada:
        </p>

        <ul>
          <li>Manzana</li>
          <li>Durazno</li>
          <li>Banana</li>
        </ul>


        <p>Una lista ordenada:</p>

        <ol>
          <li>Uno</li>
          <li>Dos</li>
          <li>Tres</li>
        </ol>

        <p>Un link a <a href="https://google.com">Google</a></p>

        <p>Una imagen:</p>

        <img title="un cubo" width="200" height="200"  src="cube.jpg">
  </body>
</html>

Para empezar tenemos que hacer que el fondo sea oscuro, es decir el cuerpo (body) de la pagina debe tener el color de fondo negro.

Como le decimos a un tag cosas que no son su contenido?

Con atributos, en este caso el atributo es bastante poderoso, y su valor es un lenguaje en si mismo!

Cambiamos el tag de apertura del cuerpo de

<body>

A:

<body style="background-color: black;">

El contenido del atributo style es uno o mas pares de valores, cada par separado por ;, cada par a su lado izquierdo tiene la "llave" y del lado derecho el "valor".

Este concepto de pares llave valor se va a repetir mucho en el mundo informático así que si prestas atención lo vas a ver en muchos lados, para empezar, ya los conocés de los atributos de los tags :)

Los pares llave/valor en CSS sirven para especificar distintas propiedades del tag en el que están definidos.

En este caso le estamos diciendo que el color de fondo (background significa fondo en ingles) tiene el valor negro (black).

El resultado, si bien es lo que queremos, nos agrega un nuevo desafío:

/galleries/cew/4/01-bg-color.png

El texto no se lee!

Ahora tenemos que hacer que el texto sea un color claro, empezamos con el titulo:

<h1 style="color: white;">Esto es un título</h1>

Para definir el color del contenido de un tag (no el fondo), usamos la llave color (que por suerte no tenemos que traducir :)

Continuamos con el primer párrafo:

<p style="color: white;">Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

Y el resultado se ve algo así:

/galleries/cew/4/02-color.png

Si sos como yo, ya estarás pensando: "Esto va a llevar un buen tiempo y mucha repetición!".

Si, eso pensé yo.

Pero quizás notaste que la palabra negrita y la palabra itálica ahora también tienen color blanco.

Esto no es un accidente, cuando un valor se define en CSS para un tag, los tags descendientes "heredan" ese valor si tiene sentido, el color de fondo y el color del texto por suerte son unos de ellos.

Ahora bien, donde podríamos poner el color de texto para hacer el menor esfuerzo posible?

En el mismo lugar que definimos el color de fondo.

<body style="background-color: black; color: white;">

El resultado es lo que esperábamos:

/galleries/cew/4/03-color.png

Gustos específicos

Ahora digamos que se nos ocurre que queremos que la palabra negrita, itálica y los elementos impares de las listas tienen que tener fondo blanco y texto rojo.

Intentemos lo:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
  </head>

  <body style="background-color: black; color: white;">
        <h1>Esto es un título</h1>

        <p>Esto es un párrafo, la siguiente palabra es en <b style="background-color: white; color: red;">negrita</b>, la siguiente en <i style="background-color: white; color: red;">itálica</i></p>

        <p>Esto es otro párrafo</p>

        <p>
          Una lista no ordenada:
        </p>

        <ul>
          <li style="background-color: white; color: red;">Manzana</li>
          <li>Durazno</li>
          <li style="background-color: white; color: red;">Banana</li>
        </ul>


        <p>Una lista ordenada:</p>

        <ol>
          <li style="background-color: white; color: red;">Uno</li>
          <li>Dos</li>
          <li style="background-color: white; color: red;">Tres</li>
        </ol>

        <p>Un link a <a href="https://google.com">Google</a></p>

        <p>Una imagen:</p>

        <img title="un cubo" width="200" height="200"  src="cube.jpg">
  </body>
</html>

Eso fue bastante repetitivo...

Gustos específicos, cambiantes

En este momento se nos ocurre que quizás seria mejor si el texto fuera azul en lugar de rojo.

La idea de tener que cambiar el color en cada lugar nos hace pensar que quizás el rojo esta bien después de todo...

Pero como siempre en el mundo de la web, si algo es repetitivo y tedioso, seguro hay una forma de automatizar lo repetitivo.

En este caso lo que nos serviría es indicar todos los tags que comparten un conjunto de características y especificar en un mismo lugar las características comunes.

Es como si los tags pertenecieran a una misma clase.

Y resulta que todos los tags pueden tener un atributo para eso, el atributo class nos permite definir una lista de palabras separadas por espacios que describen a que clases pertenece ese tag.

Llamemos a nuestra clase de tags con fondo claro y texto colorido llamativo.

Edita el ejemplo, todos los elementos con style="background-color: white; color: red;" ahora tienen que contener el atributo class con el valor llamativo, ejemplo del primero:

<b class="llamativo">negrita</b>

Luego de hacer todos los cambios podemos observar que ... no paso nada.

Porque las clases son cosas que usamos nosotros para agrupar tags, ahora tenemos que de alguna forma decirle al navegador que queremos que todos los tags con clase llamativo tengan fondo blanco y texto azul.

Para eso vamos a aprender un tag nuevo, el tag style, este tag normalmente va en la cabecera (porque no define contenido del documento) y nos permite centralizar en un lugar las definiciones de estilo.

Este va a ser el principio del documento:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
        <style>
        .llamativo{
                background-color: white;
                color: blue;
        }
        </style>
  </head>

La parte que nos interesa y es nueva es el contenido del tag

.llamativo{
        background-color: white;
        color: blue;
}

El nombre de nuestra clase esta ahí, pero empieza con un punto?

Si, para decirle al navegador que llamativo es una clase de tags en nuestro documento.

Luego de decir para que cosa queremos definir el estilo, llamado selector en la jerga CSS (ya que selecciona el conjunto de tags a los cuales el estilo aplica) le decimos que estilo aplicar, en nuestro caso y de la misma forma que en el atributo style, pares de llave/valor separados por ;. Por suerte acá podemos separarlos con saltos de linea y espacios para hacerlo mas legible.

Que pasa si no ponemos el punto? el navegador piensa que nos referimos al nombre de un tag, veamos un ejemplo.

.llamativo{
        background-color: white;
        color: blue;
}

body{
        background-color: black;
        color: white;
}

Y así podemos centralizar todo el estilo de la pagina en la cabecera y separar claramente el contenido de su presentación, algo que es una buena costumbre en el desarrollo web.

/galleries/cew/4/04-style.png

Gustos cambiantes, en muchos lugares

Con lo que aprendimos hasta ahora ya podrías tener tu pagina personal, tu blog o una pagina con cuentos o historias.

Imaginemos que con el tiempo tu pagina web crece y tiene 10 documentos distintos, todos con el mismo estilo en la cabecera.

Y un día decidís cambiar el estilo de tu pagina, querés algo mas claro.

Ahí es cuando dándote cuenta que vas a tener que hacer cambios en 10 documentos, el estilo oscuro actual no es tan mala idea después de todo...

A menos que haya otra forma de evitar la repetición.

Por suerte la hay, y quizás ya la notaste al ver en tus proyectos de Thimble un archivo con un nombre familiar que todavía no mencionamos.

El misterioso style.css.

Si lo abrís vas a ver un contenido familiar con algunas cosas nuevas, el mio tiene esto:

/* Fonts from Google Fonts - more at https://fonts.google.com */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');

body {
  background-color: white;
  font-family: "Open Sans", sans-serif;
  padding: 5px 25px;
  font-size: 18px;
  margin: 0;
  color: #444;
}

h1 {
  font-family: "Merriweather", serif;
  font-size: 32px;
}

Con lo que aprendimos e ignorando las primeras dos lineas podemos ver que es un archivo que contiene CSS y que define el estilo para el tag body y para los títulos.

Pero ese estilo no se esta aplicando, porque no lo incluimos en nuestro documento.

Para incluirlo vamos a aprender un tag nuevo, que hace muchas cosas distintas pero su tarea habitual es incluir archivos de estilo en documentos HTML.

Si agregamos el siguiente tag:

<link href="style.css" rel="stylesheet">

Después del tag style en la cabecera podemos ver como de pronto el estilo contenido en ese archivo se aplica al documento!

Antes de ver que sucedió y donde esta nuestro fondo negro veamos los dos atributos del tag link:

href
Atributo que indica la ubicación del archivo de estilo a cargar, ya lo conocíamos del tag a
rel
Como vimos mas arriba, link es un tag polifacético, y para saber cual es la rel acion del archivo referenciado con el actual, se lo tenemos que indicar. En este caso le decimos que la relación es de una hoja de estilo (S tyle s heet), de ahí las dos s en CSS

Ahora tendrás una de dos preguntas, o las dos:

Y nuestro fondo oscuro?

Y la C en CSS que significa?

Resulta que las dos preguntas tienen mas o menos la misma respuesta, la C en CSS es de Cascada, osea que CSS en español significa hojas de estilo en cascada.

Y donde esta la cascada? en la forma en la que el navegador interpreta los estilos que definimos para nuestro documento.

En nuestro documento primero le decimos que el fondo del tag body es negro y después cargamos un archivo CSS que le dice que el fondo es claro.

El navegador interpreta los estilos dándole la razón al ultimo que lo declaro y al mas especifico.

En este caso, el ultimo en declarar el color de fondo del documento es el archivo (esta mas abajo en el documento HTML).

Y lo de mas especifico? bueno, el color del texto esta definido en varios lugares, en el tag style para el tag body, y en el archivo style.css para el tag body. en ese caso sabemos que el ultimo gana.

Pero sin embargo los tags con clase llamativo son azules, como decide el navegador que el azul le gana al negro? Porque el atributo class es mas especifico que el tag body.

De esta manera podemos hacer definiciones generales "a grandes rasgos" al principio de nuestras hojas de estilo e irlas refinando mas abajo, redefiniendolas para casos mas particulares e incluso en otras hojas de estilo especificas para ciertos documentos.

Esto es bastante información y con el tiempo lo vamos a ir aprendiendo a medida que lo usamos.

Pero antes de terminar, movamos nuestro estilo al archivo style.css y dejemos el documento HTML libre de CSS mas que la referencia a style.css, el cual queda así:

body {
  background-color: white;
  color: #444;

  font-family: helvetica;
  font-size: 18px;

  padding: 5px 25px;
  margin: 0;
}

h1 {
  font-size: 32px;
}

.llamativo{
  background-color: white;
  color: blue;
}

En el CSS hay algunas llaves nuevas, font-family define la fuente del texto, font-size su tamaño, las otras dos (padding y margin) las vamos a ver en próximas secciones.

El principio de nuestro documento queda así:

<!doctype html>
<html>
  <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
        <link href="style.css" rel="stylesheet">
  </head>

Ya observaras uno de los beneficios de separar contenido de presentación: cambiamos completamente el aspecto de la pagina sin tocar si contenido.

El proyecto quedo así:

/galleries/cew/4/05-link.png

Creemos en la Web: HTML atributos y meta datos

En la sección anterior vimos como crear una pagina web que replicaba un documento de Google Docs con formato básico, en esta sección vamos a aprender sobre dos conceptos con nombres tenebrosos pero que como todo lo tenebroso cuando se los entiende resulta ser bastante inofensivo.

Necesitamos saber sobre atributos y meta datos para poder resolver dos problemas en nuestra pagina web:

  1. Como le digo al navegador cual es el titulo de mi pagina web sin que lo muestre en el contenido del documento?
  2. Como le indico información extra sobre un tag sin que se vea en el documento? por ejemplo, como separo el texto de un enlace y la dirección a la que apunta?

Para el primero vamos a usar meta datos, que son datos sobre el documento pero que no son parte del contenido del mismo.

Para lo segundo vamos a usar atributos, que son datos sobre los tags pero no son parte del contenido.

Meta datos

Para separar los meta datos del documento del contenido hacemos lo usual, rodeamos los metadatos en un tag y el contenido en otro.

En la terminología HTML un documento esta separado en dos partes, la cabeza o cabecera (head en ingles), la cual contiene los datos sobre el documento y el cuerpo (body), el cual tiene el contenido del mismo.

Como estos dos son parte de un documento HTML, ambos están contenidos en el tag raíz de todo documento HTML, el tag html.

Veamos el documento correctamente estructurado mas simple que podamos tener:

<html>
    <head></head>
    <body></body>
</html>

Si queremos definir el titulo del documento, el cual se va a mostrar en la barra de títulos del navegador cuando la pagina tiene el foco y también en la pestaña de la pagina en el navegador, usamos el tag title.

<html>
    <head>
        <title>Mi Pagina</title>
    </head>

    <body>
    </body>
</html>

Otro tag que es recomendable poner en el documento si no queremos tener problemas con como el navegador muestra las tildes y la ñ es un tag que le indica como interpretar tildes y otros caracteres especiales, utf-8 es un estándar que define como interpretar caracteres especiales y es el mas usado actualmente, simplemente copialo en todos tus documentos para evitar dolores de cabeza.

<html>
    <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
    </head>

    <body>
    </body>
</html>

Para terminar, dado que HTML es un estándar que ha evolucionado en el tiempo, el navegador soporta múltiples versiones y si no se le indica la versión intenta adivinar.

Normalmente adivina bien, pero para facilitarle el trabajo y evitar confusiones podemos ser buenas personas e indicarselo explícitamente.

<!doctype html>
<html>
    <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
    </head>

    <body>
    </body>
</html>

La primera linea le indica que el documento es de tipo HTML 5, la ultima versión del estándar.

No te preocupes en memorizar estos tags, yo simplemente copio de algún documento anterior las partes comunes, nunca empiezo de cero :)

La evolución de HTML y su énfasis en mantener compatibilidad hace que todavía puedas visitar la primera pagina web publicada en 1991: http://info.cern.ch/hypertext/WWW/TheProject.html

Atributos

Ahora al segundo problema, como indicamos información sobre un tag que no es el contenido principal, por ejemplo, si queremos crear un enlace a https://google.com pero queremos que el texto del enlace diga "Google", como hacemos esto?

Quizás lo notaste en algunos de los ejemplos hasta ahora.

Para hacer eso usamos lo que se llaman atributos, que son información extra que agregamos a un tag, la mayoría son opcionales, de manera que los vamos agregando y aprendiendo a medida que los vamos necesitando.

Veamos como resolver el problema del enlace.

<a href="https://google.com">Google</a>

Que se ve así:

Google

Los atributos van luego del identificador del tag de apertura, separados por espacios, primero va el nombre del atributo, luego un = y luego el valor, normalmente entre comillas.

Por si no te diste cuenta, acabamos de aprender un nuevo tag, el tag a (de a nchor que significa ancla en ingles) con su atributo href (de h ypertext ref erence en ingles).

Ya que aprendimos un tag nuevo, aprendamos otro similar y muy útil, el tag para mostrar imágenes [1]:

<img src="http://marianoguerra.org/galleries/cew/3/cube.jpg">

Así se ve:

Agreguemos mas atributos, uno para el tooltip (title), y dos para definir el alto (height) y el ancho (width).

<img title="un cubo" width="200" height="200" src="http://marianoguerra.org/galleries/cew/3/cube.jpg">

El resultado:

Ahora pongamos todo junto en una pagina:

<!doctype html>
<html>
    <head>
        <meta chartset="utf-8">
        <title>Mi Pagina</title>
    </head>

    <body>
        <p>Un link a <a href="https://google.com">Google</a></p>

        <p>Una imagen:</p>

        <img title="un cubo" width="200" height="200" src="http://marianoguerra.org/galleries/cew/3/cube.jpg">
    </body>
</html>

Que se ve algo así:

/galleries/cew/3/01-page.png

Notar que subí la imagen al proyecto, haciendo click en el icono de archivo y seleccionando Subir un archivo..., la dirección de la imagen es simplemente el nombre del archivo ya que esta en el mismo lugar que la pagina que la muestra.

/galleries/cew/3/02-upload.png
[1] “DOF Example” by Owen Byrne is licensed under CC BY 2.0

Creemos en la Web: HTML

Qué es HTML?

Crear paginas web involucra normalmente 3 "lenguajes" (formas que tenemos los humanos de decirle a una computadora que queremos que haga).

El único necesario es el que vamos a cubrir en esta sección: HTML

HTML permite describir el contenido de una pagina web que un programa especial llamado normalmente navegador web interpreta y muestra en la pantalla.

El contenido de un archivo HTML es texto con un formato especial, pero que podemos inspeccionar y editar con cualquier editor de texto.

Normalmente cuando la gente quiere crear un documento de texto que tenga cierto formato usa un programa como Microsoft Word, Google Docs o Libre Office Writer, en estos programas le indicamos con acciones al editor que partes del texto tienen que formato, algo como lo siguiente:

/galleries/cew/2/01-editor-visual.gif

Para indicarle al editor que una linea es un titulo, la seleccionamos, demarcando los limites y luego le indicamos que queremos que se muestre como un titulo.

Los párrafos simplemente los separamos con saltos de linea, si queremos texto en negrita o itálica, al igual que con el titulo, seleccionamos e indicamos que formato queremos para la selección.

HTML es un lenguaje que inicialmente fue pensado para escribir en editores de texto y luego evoluciono para ser generado por programas, que toman datos de una base de datos y generan como salida texto en formato HTML.

Si bien existen algunos editores visuales para HTML, normalmente este se edita a mano con editores de texto, y eso es lo que vamos a hacer.

La pagina mas simple del mundo

Escribí lo siguiente en la barra de dirección de tu navegador:

data:text/html, hola mundo

Felicitaciones! acabas de crear tu primera pagina web!

Normalmente lo que escribimos en la barra de direcciones del navegador es la ubicación de la pagina web, la primera parte (http: o https:) le indica al navegador que lo que sigue es la ubicación de la pagina que queremos ver y que la puede solicitar usando el "protocolo" [1] HTTP (Protocolo de Transferencia de Hiper Texto), lo que sigue es la dirección de la pagina, similar a la ubicación de un archivo en tu computadora, pero empezando con la pagina web que contiene la pagina.

En este caso le decimos que le vamos a indicar la pagina directamente, y que esta en formato HTML, luego escribimos el contenido de la misma.

Si bien no es una forma ideal de crear paginas web, a veces es útil para tareas especificas, por ejemplo:

Selector de colores:

data:text/html, <input type="color">

Calendario:

data:text/html, <input type="date">

Bloc de notas:

data:text/html, <body contenteditable style="max-width:60rem;margin:0 auto;padding:4rem;">bloc de notas

No te preocupes por la parte style="max-width:60rem;margin:0 auto;padding:4rem;" eso es el segundo lenguaje que vamos a ver en la próxima sección.

Nuestra primera pagina web

Nuestra primera pagina web va a intentar replicar el ejemplo de Google Docs que vimos mas arriba, con esta pagina vamos a cubrir los principales elementos de HTML.

Empezamos creando un nuevo proyecto en Thimble, si tenes dudas de como hacerlo revisa la sección anterior que contiene una introducción a Thimble.

El nuevo proyecto comienza con un contenido por defecto:

<!DOCTYPE html>
<html>
  <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Made with Thimble</title>
        <link rel="stylesheet" href="style.css">
  </head>
  <body>
        <h1>Welcome to Thimble</h1>
        <p>
          Make something <strong>amazing</strong> with the web!
        </p>
  </body>
</html>

Lo vamos a borrar y escribir el siguiente texto:

Esto es un título

Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica

Esto es otro párrafo

Una lista no ordenada:

Manzana
Durazno
Banana

Una lista ordenada:

Uno
Dos
Tres

El resultado debería ser similar al siguiente:

/galleries/cew/2/02-plain-text.png

Si la vista previa no se actualiza automáticamente podes hacer click en el botón de refrescar vista previa.

Como podemos ver la vista previa muestra todo el texto junto y sin formato, algo así:

Esto es un título Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica Esto es otro párrafo Una lista no ordenada: Manzana Durazno Banana Una lista ordenada: Uno Dos Tres

Sin formato es esperable ya que no le indicamos ninguno, pero porque todo junto?

Porque HTML "junta" todos los espacios y saltos de lineas a un solo espacio, si queremos especificar algo distinto lo tenemos que hacer explícitamente.

Esto nos va a permitir estructurar el documento con claridad y estructura sabiendo que el navegador no va a reflejar nuestros espacios y saltos de linea en el documento final.

Ya tenemos el contenido de nuestra primera pagina web, es un avance! pero no es muy diferente a un documento de texto, como agregamos el formato?

En el ejemplo de Google Docs mas arriba para indicar el formato de las distintas partes lo que hacíamos era indicar el principio y el fin de la sección a la que le queriamos aplicar formato con el mouse y luego seleccionamos una operación en el menú para indicarle que tipo de formato queremos.

En HTML es casi igual, salvo que no tenemos mouse ni menú :)

Como HTML es un formato de texto, tenemos que trabajar con lo que tenemos, pero la forma es muy parecida, primero indicamos el principio y final de una sección a la que le queremos aplicar una operación y luego le indicamos cual es esa operación.

En HTML el indicador para el inicio de una sección es <> y el indicador de fin es </>

Pero eso no funciona porque todavía tenemos que indicar que operación aplicar al texto entre <> y </>, para eso escribimos la operación entre el < y el >.

Empecemos con el titulo, si notas en la animación de Google Docs, la operación se llama Heading 1, es medio largo para escribir todo eso cada vez que queremos un titulo de nivel 1, así que lo acortamos a h1.

Cambiemos

Esto es un título

Por

<h1>Esto es un título</h1>

El resultado debería verse algo así:

/galleries/cew/2/03-h1.png

Tenemos el titulo!

Y ese es el primer tag (etiqueta en inglés) que aprendimos:

h1
Formatea el texto delimitado como un titulo de nivel 1

Si digo titulo de nivel 1 podemos imaginarnos que hay mas niveles, es como el indice de un libro, las secciones tienen sub secciones y cada sección tiene un titulo de un nivel mas alto.

En HTML tenemos 6 niveles: h1, h2, h3, h4, h5, h6.

Continuemos.

La siguiente linea dice:

Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica

Como le indicamos que es un párrafo? como con el titulo, lo rodeamos de una etiqueta de apertura y una de cierre y le indicamos que es un párrafo, pero de nuevo, escribir párrafo en español o ingles por cada párrafo es bastante largo así que lo vamos a abreviar a p

<p>Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica</p>

El resultado debería verse similar al siguiente:

/galleries/cew/2/04-p.png

Notaras que ahora el primer párrafo tiene espacio con respecto al titulo y al resto del texto, ahora hacemos lo mismo con los siguientes párrafos:

<h1>Esto es un título</h1>

<p>Esto es un párrafo, la siguiente palabra es en negrita, la siguiente en itálica</p>

<p>Esto es otro párrafo</p>

<p>
  Una lista no ordenada:

Manzana
Durazno
Banana
</p>

<p>
Una lista ordenada:

Uno
Dos
Tres
</p>

Como veras los saltos de linea y los espacios no afectan el formato final.

/galleries/cew/2/05-p.png

Tenemos el titulo y los párrafos, ya casi que podemos escribir un cuento en HTML :)

Pero un poco mas de formato no vendría mal, sigamos con negrita e itálica.

No hay nada de magia, es igual a las anteriores, rodeamos la sección que queremos formatear y le indicamos que formato queremos aplicarle.

A ver si te podes imaginar que identificador lleva negrita (b old en ingles) e itálica (i talic en ingles)?

<p>Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

El resultado debería verse algo así:

/galleries/cew/2/06-bi.png

Como podes ver en el párrafo, podemos tener tags/etiquetas dentro de otros tags/etiquetas, en este caso tenemos tags negrita e itálica dentro del tag de párrafo.

Ya casi estamos!

Solo faltan las listas, en este caso tenemos que indicar dos cosas distintas con tags:

  1. Que queremos una lista

    • Ordenada: Numerada
    • No Ordenada: Sin Numeración
  2. Cuales son los elementos de la lista

Empecemos con la lista no ordenada, en ingles u nordered l ist, ya te podes imaginar como se identifica el tag:

<ul>
Manzana
Durazno
Banana
</ul>

Pero esto no es suficiente, todavía le tenemos que decir cuales son los elementos de la lista (l ist i tem en ingles):

<ul>
        <li>Manzana</li>
        <li>Durazno</li>
        <li>Banana</li>
</ul>

De nuevo tenemos tags dentro de otro tag, en este caso el tag li (list item) dentro del tag ul (unordered list)

Para la lista ordenada es igual, pero en lugar de indicar que queremos una lista no ordenada, le indicamos que queremos una ordenada (o rdered l list en ingles)

<ol>
        <li>Uno</li>
        <li>Dos</li>
        <li>Tres</li>
</ol>

El código completo:

<h1>Esto es un título</h1>

<p>Esto es un párrafo, la siguiente palabra es en <b>negrita</b>, la siguiente en <i>itálica</i></p>

<p>Esto es otro párrafo</p>

<p>
  Una lista no ordenada:
</p>

<ul>
  <li>Manzana</li>
  <li>Durazno</li>
  <li>Banana</li>
</ul>


<p>Una lista ordenada:</p>

<ol>
  <li>Uno</li>
  <li>Dos</li>
  <li>Tres</li>
</ol>

Que debería verse similar a esto:

/galleries/cew/2/07-lists.png

Y con esto replicamos el documento de Google Docs y sabemos un poco mas cual es el contenido de los archivos .doc, .odt y similares, solo que esos están en formato binario (unos y ceros) ya que las computadoras los prefieren en lugar del formato texto, que preferimos los humanos :)

[1] Un protocolo es un acuerdo entre dos o mas partes que establece la forma en la que se van a comunicar, en este caso establece como un navegador solicita un documento HTML y como el otro se lo envía.