recursero-jekyll-theme 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +69 -18
  3. data/_config.yml +77 -0
  4. data/_data/assets.json +6 -0
  5. data/_data/en.yml +61 -15
  6. data/_data/es.yml +64 -15
  7. data/_data/forms/contacto.yml +2 -2
  8. data/_data/layouts/about.yml +34 -17
  9. data/_data/layouts/menu.yml +73 -0
  10. data/_includes/contact.html +8 -5
  11. data/_includes/floating_alert.html +6 -0
  12. data/_includes/item.html +38 -0
  13. data/_includes/menu.html +23 -0
  14. data/_includes/onboarding.html +37 -0
  15. data/_includes/pack.html +1 -0
  16. data/_includes/password.html +1 -0
  17. data/_includes/picture.html +23 -0
  18. data/_includes/preload_font.html +1 -0
  19. data/_includes/search.html +4 -3
  20. data/_includes/share.html +3 -2
  21. data/_includes/submit.html +5 -1
  22. data/_layouts/about.html +1 -1
  23. data/_layouts/default.html +34 -2
  24. data/_layouts/page.html +1 -1
  25. data/_layouts/place.html +1 -1
  26. data/_layouts/post.html +2 -2
  27. data/_sass/accessibility.scss +48 -7
  28. data/_sass/editor.scss +17 -0
  29. data/_sass/embed.scss +8 -0
  30. data/_sass/floating_alert.scss +48 -0
  31. data/_sass/fonts.scss +0 -0
  32. data/_sass/helpers.scss +327 -31
  33. data/_sass/menu.scss +36 -0
  34. data/_sass/snap.scss +60 -0
  35. data/_sass/toggler.scss +34 -11
  36. data/assets/css/styles.scss +89 -7
  37. data/assets/data/manifest.js +29 -0
  38. data/assets/fonts/forkawesome-webfont.woff2 +0 -0
  39. data/assets/js/pack.3cf11284b767fdbbefa6.js +113 -0
  40. data/assets/js/pack.3cf11284b767fdbbefa6.js.map +1 -0
  41. data/assets/js/pack.4ced2556b94e5c09e5bc.js +113 -0
  42. data/assets/js/pack.4ced2556b94e5c09e5bc.js.map +1 -0
  43. data/assets/js/pack.c42a6f683b2c0c0fa404.js +90 -0
  44. data/assets/js/pack.c42a6f683b2c0c0fa404.js.map +1 -0
  45. data/assets/js/pack.d9a353affdca4644a9b2.js +113 -0
  46. data/assets/js/pack.d9a353affdca4644a9b2.js.map +1 -0
  47. data/assets/js/sw.3cf11284b767fdbbefa6.js +2 -0
  48. data/assets/js/sw.3cf11284b767fdbbefa6.js.map +1 -0
  49. data/assets/templates/alert.html +7 -0
  50. data/assets/templates/results.html +15 -7
  51. metadata +82 -45
  52. data/_includes/navbar.html +0 -53
  53. data/_sass/share.html +0 -12
  54. data/_sass/share_box.html +0 -16
  55. data/assets/js/pack.js +0 -90
  56. data/assets/js/pack.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ ---
2
+ title:
3
+ type: 'string'
4
+ required: true
5
+ label:
6
+ en: ''
7
+ es: 'Nombre del ítem'
8
+ help:
9
+ en: ''
10
+ es: 'Tal como aparece en el menú'
11
+ post:
12
+ type: 'belongs_to'
13
+ label:
14
+ en: ''
15
+ es: 'Artículo'
16
+ help:
17
+ en: ''
18
+ es: 'Si el ítem lleva a un artículo fijo, asociarlo aquí'
19
+ item:
20
+ type: 'belongs_to'
21
+ inverse: items
22
+ filter:
23
+ layout: menu
24
+ label:
25
+ en: ''
26
+ es: 'Ítem anterior'
27
+ help:
28
+ en: ''
29
+ es: 'Si es un sub ítem, asociar el ítem superior aquí'
30
+ items:
31
+ type: 'has_many'
32
+ inverse: item
33
+ filter:
34
+ layout: menu
35
+ label:
36
+ en: ''
37
+ es: 'Sub ítemes'
38
+ help:
39
+ en: ''
40
+ es: 'Si el ítem tiene sub ítems, asociarlos aquí'
41
+ link:
42
+ type: 'string'
43
+ label:
44
+ en: ''
45
+ es: 'Vínculo'
46
+ help:
47
+ en: ''
48
+ es: 'Si el ítem lleva a una página o sección especial, asociarla aquí'
49
+ categories:
50
+ type: 'array'
51
+ label:
52
+ en: ''
53
+ es: 'Categorías'
54
+ help:
55
+ en: ''
56
+ es: 'Si el ítem lleva un sub menú de categorías, agregarlas aquí'
57
+ draft:
58
+ type: 'boolean'
59
+ label:
60
+ es: 'Borrador'
61
+ en: 'Draft'
62
+ help:
63
+ es: 'Este artículo aun no está listo para publicar'
64
+ en: "This post isn't ready to be published yet"
65
+ order:
66
+ type: 'order'
67
+ required: true
68
+ label:
69
+ es: 'Orden'
70
+ en: 'Order'
71
+ help:
72
+ es: 'La posición del artículo en la lista de artículos'
73
+ en: 'The post position in the posts list'
@@ -1,15 +1,18 @@
1
1
  {% comment %}
2
- Esta imagen obtiene una cookie desde la API de Sutty para autorizar el
3
- envío del formulario.
2
+ Esta imagen obtiene una cookie desde la API de Sutty para autorizar el
3
+ envío del formulario.
4
4
  {% endcomment %}
5
- <img class="d-none" src="https://api.sutty.nl/v1/sites/{{ site.hostname }}/contact/cookie.png" />
5
+ <img class="d-none invisible" src="https://api.sutty.nl/v1/sites/{{ site.hostname }}/contact/cookie.png" />
6
6
 
7
7
  {% comment %}
8
8
  El formulario se envía a la API. La definición del formulario se
9
9
  encuentra en _data/forms/contacto.yml
10
10
  {% endcomment %}
11
- <form action="https://api.sutty.nl/v1/sites/{{ site.hostname }}/contact/contacto"
12
- method="post">
11
+ <form
12
+ data-controller="contact"
13
+ data-delay="60"
14
+ action="https://api.sutty.nl/v1/sites/{{ site.hostname }}/contact/{{ include.name }}"
15
+ method="post">
13
16
  {%- for field in include.form -%}
14
17
  {% assign template = field[1].type | append: '.html' %}
15
18
  <div class="col{{ field[1].col | default: 12 | prepend: '-' }}">
@@ -0,0 +1,6 @@
1
+ <div
2
+ data-controller="floating-alert"
3
+ class="floating-alert floating-alert-bottom floating-alert-default"
4
+ role="status" aria-live="polite" aria-atomic="true">
5
+ <div data-target="toast.content" class="floating-alert-content white background-black-t4"></div>
6
+ </div>
@@ -0,0 +1,38 @@
1
+ {%- comment -%}
2
+ El ítem tiene un dropdown si tiene sub ítems o si tiene categorías.
3
+ {%- endcomment -%}
4
+ {%- assign dropdown = include.item.items | present -%}
5
+ {%- unless dropdown -%}
6
+ {%- assign dropdown = include.item.categories | present -%}
7
+ {%- endunless -%}
8
+
9
+ <div class="nav-item w-100 w-lg-auto {{ dropdown | value_if: 'dropdown d-flex flex-wrap' }}">
10
+ {%- comment -%}
11
+ La URL del item puede ser:
12
+ * El artículo vinculado
13
+ * El vínculo escrito manualmente
14
+ * La primera categoría de la lista
15
+ * La dirección propia (en el caso de categorías)
16
+ {%- endcomment -%}
17
+ <a
18
+ href="{{ include.item.post.url | default: include.item.link | default: include.item.categories[0].url | default: include.item.url }}"
19
+ class="nav-link flex-grow-1 flex-grow-lg-0">
20
+ {{ include.item.title }}
21
+ </a>
22
+
23
+ {%- if dropdown -%}
24
+ <button class="dropdown-toggle border-0 background-white w-5 w-lg-auto pl-lg-3"></button>
25
+ <div class="dropdown-menu w-100 w-lg-auto flex-grow-1 flex-grow-lg-0">
26
+ {% for item in include.item.items %}
27
+ {%- include_cached item.html item=item -%}
28
+ {% endfor %}
29
+
30
+ {%- comment -%}
31
+ Esto necesita `replace` en sutty-archives
32
+ {%- endcomment -%}
33
+ {%- for item in include.item.categories offset: 1 -%}
34
+ {%- include_cached item.html item=item -%}
35
+ {%- endfor -%}
36
+ </div>
37
+ {%- endif -%}
38
+ </div>
@@ -0,0 +1,23 @@
1
+ {%- comment -%}
2
+ Empezamos con los ítems que no dependen de otros e implementamos
3
+ recursivamente.
4
+ {%- endcomment -%}
5
+ {%- assign items = site.posts | where: 'layout', 'menu' | where: 'item', nil -%}
6
+
7
+ <nav class="navbar navbar-expand-lg navbar-light">
8
+ <button class="navbar-toggler"
9
+ type="button"
10
+ data-toggle="collapse"
11
+ data-target="#menu"
12
+ aria-label="{{ site.i18n.menu.title }}">
13
+ <span class="navbar-toggler-icon"></span>
14
+ </button>
15
+
16
+ <div class="collapse navbar-collapse" id="menu">
17
+ <div class="navbar-nav w-100 d-flex align-items-start justify-content-center">
18
+ {% for item in items %}
19
+ {%- include_cached item.html item=item -%}
20
+ {% endfor %}
21
+ </div>
22
+ </div>
23
+ </nav>
@@ -0,0 +1,37 @@
1
+ {% comment %}
2
+ La barra de notificaciones, donde le pedimos a les usuaries que vayan
3
+ haciendo varias cosas. Quizás debería llamarse onboarding.
4
+
5
+ Primero tenemos que poder salir del navegador interno de Facebook,
6
+ Instagram, Telegram, etc.
7
+ {% endcomment %}
8
+
9
+ <aside
10
+ data-sw="{{ jekyll.production | ternary: site.data.assets['sw.js'], 'sw.js' }}"
11
+ data-controller="onboarding"
12
+ class="w-100 background-primary"
13
+ role="status"
14
+ aria-live="polite"
15
+ aria-atomic="true">
16
+ <div data-onboarding-target="internalBrowser" hidden>
17
+ <div class="h-20vh d-flex align-items-center">
18
+ {% comment %}
19
+ Con esta URL le decimos a Android y posible iOS que queremos abrir
20
+ este link en un navegador externo.
21
+
22
+ https://stackoverflow.com/a/58342222
23
+ {% endcomment %}
24
+ <a href="intent:{{ site.url }}#Intent;end" class="btn btn-block btn-primary">
25
+ {{ site.i18n.onboarding.internal_browser }}
26
+ </a>
27
+ </div>
28
+ </div>
29
+
30
+ <div data-onboarding-target="browser" hidden>
31
+ <div class="h-20vh d-flex align-items-center">
32
+ <button data-action="onboarding#install" class="btn btn-block btn-primary">
33
+ {{ site.i18n.onboarding.browser }}
34
+ </button>
35
+ </div>
36
+ </div>
37
+ </aside>
@@ -0,0 +1 @@
1
+ <script defer src="{{ jekyll.production | ternary: site.data.assets['assets/js/pack.js'], 'assets/js/pack.js' }}"></script>
@@ -0,0 +1 @@
1
+ {% include input.html field=include.field form=include.form %}
@@ -0,0 +1,23 @@
1
+ {% comment %}
2
+ Imágenes responsive. Esto logra que solo se carguen las versiones de
3
+ las imágenes con el ancho máximo de la pantalla.
4
+
5
+ TODO: Las imágenes en md y superior nunca llegan al ancho máximo así
6
+ que tienen una resolución de más.
7
+ {% endcomment %}
8
+ {%- assign image = include.image.path | default: 'public/placeholder.png' %}
9
+ {%- assign height = include.height | default: site.i18n.post.height -%}
10
+ {%- assign width = include.width | default: '100' -%}
11
+
12
+ <picture>
13
+ {% for size in site.images.sizes %}
14
+ <source srcset="{{ image | thumbnail: size }}" media="(max-width: {{ size }}px)" />
15
+ {% endfor %}
16
+
17
+ <img
18
+ class="u-photo w-{{ width }} {{ include.cover | equals: false | value_unless: 'fit-cover' }} h-{{ height }} {{ include.extra }}"
19
+ loading="lazy"
20
+ itemprop="image"
21
+ src="{{ image | thumbnail: 1140 }}"
22
+ alt="{{ include.image.description | include.default_description }}" />
23
+ </picture>
@@ -0,0 +1 @@
1
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{ include.font }}?{{ site.time | date: '%s' }}" />
@@ -1,15 +1,16 @@
1
1
  {%- comment -%}
2
2
  Encabezado con buscador
3
3
  {%- endcomment -%}
4
+ {%- assign param = include.param | default: 'search' -%}
4
5
  <section id="{{ site.i18n.search.id }}">
5
6
  <div class="jumbotron">
6
- <form method="get" class="search" action="{{ site.i18n.search.url }}" data-controller="search">
7
+ <form method="get" class="search" action="{{ site.i18n.search.url }}" data-controller="search" data-action="search#search">
7
8
  <div class="form-group">
8
- <label for="search" class="sr-only">{{ site.i18n.search.placeholder }}</label>
9
+ <label for="{{ param }}_q" class="sr-only">{{ site.i18n.search.placeholder }}</label>
9
10
  <input
10
11
  type="search"
11
12
  required
12
- id="q"
13
+ id="{{ param }}_q"
13
14
  name="q"
14
15
  placeholder="{{ site.i18n.search.placeholder }}"
15
16
  class="form-control form-control-lg m-0"
data/_includes/share.html CHANGED
@@ -5,6 +5,7 @@
5
5
  {% endunless %}
6
6
  {% assign title = include.title | default: '' | cgi_escape %}
7
7
  {% assign description = include.description | default: '' | cgi_escape %}
8
+ {% assign tags = include.tags | join: ',' | default: '' | cgi_escape %}
8
9
 
9
10
  <a
10
11
  {% if include.share.url == '%url' %}
@@ -12,10 +13,10 @@
12
13
  {% else %}
13
14
  target="_blank"
14
15
  {% endif %}
15
- rel="nofollow"
16
+ rel="noopener nofollow"
16
17
  title="{{ include.share.title }}"
17
18
  class="d-flex flex-column align-items-center p-3"
18
- href="{{ include.share.url | replace: '%url', url | replace: '%title', title | replace: '%description', description }}">
19
+ href="{{ include.share.url | replace: '%url', url | replace: '%title', title | replace: '%description', description | replace: '%tags', tags }}">
19
20
  <i class="fa fa-fw fa-2x fa-{{ include.share.icon }}"></i>
20
21
  <span>{{ include.share.title }}</span>
21
22
  </a>
@@ -1 +1,5 @@
1
- <input type="submit" class="btn btn-success" value="{{ include.field[1].label[site.locale] }}" />
1
+ <input
2
+ data-target="contact.submit"
3
+ type="submit"
4
+ class="btn btn-success"
5
+ value="{{ include.field[1].label[site.locale] }}" />
data/_layouts/about.html CHANGED
@@ -22,7 +22,7 @@ layout: default
22
22
 
23
23
  <p>
24
24
  <time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
25
- {%- assign date_format = site.i18n.date | default: "%b %-d, %Y" -%}
25
+ {%- assign date_format = site.i18n.date.format | default: "%b %-d, %Y" -%}
26
26
  {{ page.date | date: date_format }}
27
27
  </time>
28
28
  {%- for author in page.author -%}
@@ -9,14 +9,46 @@
9
9
  <meta name="color-scheme" content="light"/>
10
10
  <meta name="referrer" content="strict-origin-when-cross-origin"/>
11
11
 
12
+ {% comment %}
13
+ No tenemos forma de hashear SASS aún, por lo que renovamos la caché
14
+ aplicando la hora de compilación del sitio. Es importante que los
15
+ CSS se renueven cuando se regenera el sitio, porque pueden contener
16
+ variables dinámicas (como personalización de colores y tipografía) o
17
+ minificarse distinto dependiendo del contenido.
18
+ {% endcomment %}
12
19
  <link href="assets/css/styles.css" rel="stylesheet">
13
- <script defer type="text/javascript" src="assets/js/pack.js"></script>
20
+
21
+ {% comment %}
22
+ Webpack. La configuración se pasa por variables de entorno, en
23
+ desarrollo hay que evitar el archivo .env (copiarlo de .env.example
24
+ si no existe.
25
+ {% endcomment %}
26
+ <link rel="preload" as="script" type="text/javascript" href="env.js" />
27
+ <script type="text/javascript" src="env.js"></script>
28
+ {% include_cached pack.html %}
29
+
30
+ {% comment %}
31
+ Agregar otras tipografías. Esto hace que las tipografías se carguen
32
+ lo más rápido posible y minimizar el tiempo en que se ven las del
33
+ navegador. En Firefox todavía no está soportado.
34
+
35
+ Fork Awesome lleva la hora de generación para poder renovarlo si
36
+ agregamos íconos nuevos, de lo contrario puede quedar cacheado para
37
+ siempre y les visitantes van a ver íconos rotos.
38
+ {% endcomment %}
39
+ {% include_cached preload_font.html font='assets/fonts/forkawesome-webfont.woff2' %}
40
+
41
+ <link rel="icon" type="image/svg+xml" href="public/favicon.svg">
42
+ <link rel="alternate icon" href="public/favicon.ico">
43
+ <link rel="mask-icon" href="public/favicon.svg" color="white">
44
+ <link rel="manifest" href="manifest.json">
14
45
 
15
46
  {% seo %}
16
47
  {% feed_meta %}
17
48
  </head>
18
49
  <body class="d-flex flex-column justify-content-between d-print-block min-vh-100">
19
- {% include navbar.html %}
50
+ {%- include_cached onboarding.html -%}
51
+ {%- include_cached menu.html active_cache_key=page.layout %}
20
52
  {% include_cached search.html %}
21
53
 
22
54
  <main class="flex-grow-1 container-fluid d-flex flex-column justify-content-start">
data/_layouts/page.html CHANGED
@@ -28,7 +28,7 @@ layout: default
28
28
 
29
29
  <p>
30
30
  <time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
31
- {%- assign date_format = site.i18n.date | default: "%b %-d, %Y" -%}
31
+ {%- assign date_format = site.i18n.date.format | default: "%b %-d, %Y" -%}
32
32
  {{ page.date | date: date_format }}
33
33
  </time>
34
34
  {%- for author in page.author -%}
data/_layouts/place.html CHANGED
@@ -28,7 +28,7 @@ layout: default
28
28
 
29
29
  <p>
30
30
  <time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
31
- {%- assign date_format = site.i18n.date | default: "%b %-d, %Y" -%}
31
+ {%- assign date_format = site.i18n.date.format | default: "%b %-d, %Y" -%}
32
32
  {{ page.date | date: date_format }}
33
33
  </time>
34
34
  {%- for author in page.author -%}
data/_layouts/post.html CHANGED
@@ -28,8 +28,8 @@ layout: default
28
28
 
29
29
  <p>
30
30
  <time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
31
- {%- assign date_format = site.i18n.date | default: "%b %-d, %Y" -%}
32
- {{ page.date | date: date_format }}
31
+ {%- assign date_format = site.i18n.date.format | default: "%b %-d, %Y" -%}
32
+ {{ page.date | date_local: date_format }}
33
33
  </time>
34
34
  {%- for author in page.author -%}
35
35
 
@@ -1,13 +1,54 @@
1
- * {
2
- scroll-behavior: smooth;
3
- }
1
+ ////
2
+ /// Accesibilidad
3
+ /// @group Accesibilidad
4
+ ////
5
+
6
+ /// La navegación es suave. Esto hace que al navegar a elementos dentro
7
+ /// de la misma página no haga un salto, sino que haya una transición.
8
+ ///
9
+ /// Es especialmente útil en sliders.
10
+ ///
11
+ /// Sin embargo puede producir mareos a algunas personas.
12
+ * { scroll-behavior: smooth; }
4
13
 
5
- /*
6
- * Deshabilita animaciones si la usuaria las tiene deshabilitadas
7
- */
14
+ /// Aquí se aplica la opción `prefers-reduced-motion: reduce`, pero
15
+ /// SassDoc no la estaría mostrando.
8
16
  @media (prefers-reduced-motion: reduce) {
17
+ /// Si les usuaries prefirieron reducir las animaciones de los sitios,
18
+ /// deshabilitamos la navegación suavizada y las animaciones.
9
19
  * {
10
- scroll-behavior: auto;
20
+ scroll-behavior: auto !important;
11
21
  animation: none !important;
12
22
  }
13
23
  }
24
+
25
+ /// Utilizamos Axe para poder marcarnos cuáles elementos no cumplen con
26
+ /// parámetros de accesibilidad durante el desarrollo. Esta clase
27
+ /// muestra un borde rojo alrededor de los elementos inaccesibles y al
28
+ /// obtener el foco, muestra los mensajes de error generados por Axe.js.
29
+ ///
30
+ /// @link _packs/entry.js
31
+ .inaccesible {
32
+ outline: $red 1px solid;
33
+
34
+ @extend .position-relative;
35
+
36
+ &:focus::after {
37
+ @extend .position-fixed;
38
+ @extend .background-red;
39
+ @extend .white;
40
+ @extend .p-3;
41
+
42
+ left: 0;
43
+ bottom: 0;
44
+ width: 100vw;
45
+ font-size: 1rem;
46
+
47
+ word-wrap: normal;
48
+ line-break: auto;
49
+ white-space: pre-line;
50
+
51
+ /// El contenido se trae desde el ariaLabel del elemento.
52
+ content: attr(aria-label);
53
+ }
54
+ }