Commit 07b605e6 authored by Elias2049's avatar Elias2049
Browse files

Merge branch 'master' of https://gitlab.ocamlpro.com/OCamlPro/www into CssElias

parents e382d7f8 d45ccbf8
......@@ -18,7 +18,7 @@ build:
stage: build
image: registry.ocamlpro.com/ocamlpro/ocaml-docker-images:4.12
before_script:
- sudo apk add openssl-libs-static
- sudo apk add bash openssl-libs-static
- if [ -d _opam ]; then opam install . --deps-only --locked --depext-only -td;
else opam switch create . ocaml-system --deps-only --locked -td; fi
script:
......
......@@ -8,6 +8,8 @@ type article =
; url : string
}
exception ContentDoesntExistSoPleaseRaiseA404
let alt_ergo_footer =
{|
> ### **About Alt-Ergo**
......@@ -188,13 +190,13 @@ let article_of_string post url =
let authors =
let auth = get_meta_value author in
match String.split_on_char ',' auth with
| [ "" ] -> [ "Unspecified authors!" ]
| [ "" ] -> [ "Unspecified authors." ]
| auth -> auth
in
let tags =
let tags = get_meta_value tags in
match String.split_on_char ',' tags with
| [ "" ] -> [ "Unspecified tags!" ]
| [ "" ] -> [ "Unspecified tags." ]
| tags -> tags
in
let category =
......@@ -296,7 +298,7 @@ let links_to_home_pages =
</a>
</p>
</div>
<div class="col-4">
<div class="col-4">
<p class="toplinks">
<a href="/blog/category">
Categories
......@@ -315,19 +317,19 @@ let pp_article_excerpt fmt article =
<h3><a href="/blog/%s">%s</a></h3>
</div>
<div class="row">
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_person.svg"/>
Authors: %a
</div>
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_calendar.svg"/>
Date: %4d-%02d-%02d
</div>
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_category.svg"/>
Category: <a href="/blog/category/%s">%s</a>
</div>
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_tags.svg"/>
Tags: %a
</div>
......@@ -356,22 +358,22 @@ let specific_article_header title authors (year, month, day) category tags =
Format.asprintf
{|<h1 id="page-title">%s</h1>
<div class="row">
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_person.svg"/>
Authors: %a
</div>
<div class="col-lg-2">
<div class="col-6 col-lg-2">
<img class="icon" src="/blog/assets/img/icon_calendar.svg"/>
Date: %4d-%02d-%02d
</div>
<div class="col-lg-1" align="center">
<div class="col-6 col-lg-1" align="center">
<a href="/blog/feed"><img class="icon" src="/blog/assets/img/icon_atom_feed.svg"/></a>
</div>
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_category.svg"/>
Category: <a href="/blog/category/%s">%s</a>
</div>
<div class="col-lg-3">
<div class="col-6 col-lg-3">
<img class="icon" src="/blog/assets/img/icon_tags.svg"/>
Tags: %a
</div>
......@@ -394,9 +396,12 @@ let given_category category =
(fun article -> String.equal (normalize_url article.category) category)
articles_by_date
in
let category = (List.hd articles_of_category).category in
Format.asprintf {|<h1 id="page-title">Articles on %s</h1>%s%a@.|} category
links_to_home_pages pp_blog_posts articles_of_category
match articles_of_category with
| [] -> raise ContentDoesntExistSoPleaseRaiseA404
| _l ->
let category = (List.hd articles_of_category).category in
Format.asprintf {|<h1 id="page-title">Articles on %s</h1>%s%a@.|} category
links_to_home_pages pp_blog_posts articles_of_category
(** [given_author ocp_author] Displays the list of articles written by a given
[ocp_author] *)
......@@ -410,13 +415,16 @@ let given_author ocp_author =
article.authors )
articles_by_date
in
let authors = (List.hd articles_of_author).authors in
let author =
List.find (fun auth -> String.equal (normalize_url auth) ocp_author) authors
in
( Format.asprintf {|<h1 id="page-title">Articles by %s</h1>%s%a@.|} author
links_to_home_pages pp_blog_posts articles_of_author
, author )
match articles_of_author with
| [] -> raise ContentDoesntExistSoPleaseRaiseA404
| _l ->
let authors = (List.hd articles_of_author).authors in
let author =
List.find (fun auth -> String.equal (normalize_url auth) ocp_author) authors
in
( Format.asprintf {|<h1 id="page-title">Articles by %s</h1>%s%a@.|} author
links_to_home_pages pp_blog_posts articles_of_author
, author )
(** [given_tag tag] Displays the list of articles tagged with given [tag] *)
let given_tag tag =
......@@ -429,13 +437,16 @@ let given_tag tag =
article.tags )
articles_by_date
in
let tag =
List.find
(fun t -> String.equal (normalize_tag t) tag)
(List.hd articles_with_tag).tags
in
Format.asprintf {|<h1 id="page-title">Articles tagged with %s</h1>%s%a@.|} tag
links_to_home_pages pp_blog_posts articles_with_tag
match articles_with_tag with
| [] -> raise ContentDoesntExistSoPleaseRaiseA404
| _l ->
let tag =
List.find
(fun t -> String.equal (normalize_tag t) tag)
(List.hd articles_with_tag).tags
in
Format.asprintf {|<h1 id="page-title">Articles tagged with %s</h1>%s%a@.|} tag
links_to_home_pages pp_blog_posts articles_with_tag
(** [category_home] This is the home page for all available categories on the
Blog, along with number of articles of given category *)
......
@font-face {
font-family: "Fontin";
src: url("../font/Fontin-Regular.ttf") format('truetype');
}
@font-face {
font-family: "Fontin-Bold";
src: url("../font/Fontin-Bold.ttf") format('truetype');
}
@font-face {
font-family: "Fontin-Italic";
src: url("../font/Fontin-Italic.ttf") format('truetype');
}
body {
padding-top: 3rem;
padding-bottom: 3rem;
color: #5a5a5a;
background-color: #EEEEEE;
line-height: 1.6;
font-size: 28px;
}
p img {
max-width: 45em;
display: block;
margin: auto;
}
.toplinks
{
font-size: 1em;
font-family: 'Fontin';
margin-left: 10px;
}
.toplinks2 {
float: left;
}
.toplinks3 {
float: left;
margin-left: 140px;
}
h1, h2 {
font-family: "Fontin-Bold"; /*Seems a little bit too 'boudiné' : not beautiful on smartphones and tabs*/
}
.quote blockquote {
background-color: #91bff0 /*#ECDDCE*/; /*Changes in Quote style, may need to change color too*/
padding-right: 10px;
padding-top: 5px;
padding-bottom: 1px;
border-radius: 12px;
}
.featurette-divider {
margin: 5rem 0;
}
.cardheader,.card-body {
background-color: #EEEEEE;
}
.card-text {
text-align: left;
}
.card-image {
/*max-width: 10em;*/
width: auto;
max-height: 200px;
display: block;
margin: auto;
}
/* Bootstrap icons */
.feed, .icon {
width:1em;
}
#page-title {
text-align: center;
}
/* Bootstrap tweaks */
blockquote.blockquote {
border-left: 6px solid #3131e0;
border-radius: 6px;
padding-left: 16px;
background-color: #c0c0f0;
}
/*
* The CSS below has been taken from the following page:
*
* https://www.bootdey.com/snippets/view/timeline-steps
*
* This comment will be updated as changes of said code happen
*
* */
body{margin-top:20px;}
.timeline-steps {
display: flex;
justify-content: center;
flex-wrap: wrap
}
.timeline-steps .timeline-step {
align-items: center;
display: flex;
flex-direction: column;
position: relative;
margin: 1rem
}
@media (min-width:768px) {
.timeline-steps .timeline-step:not(:last-child):after {
content: "";
display: block;
border-top: .25rem dotted #3b82f6;
width: 3.46rem;
position: absolute;
left: 7.5rem;
top: .3125rem
}
.timeline-steps .timeline-step:not(:first-child):before {
content: "";
display: block;
border-top: .25rem dotted #3b82f6;
width: 3.8125rem;
position: absolute;
right: 7.5rem;
top: .3125rem
}
}
.timeline-steps .timeline-content {
width: 10rem;
text-align: center
}
.timeline-steps .timeline-content .inner-circle {
border-radius: 1.5rem;
height: 1rem;
width: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
background-color: #3b82f6
}
.timeline-steps .timeline-content .inner-circle:before {
content: "";
background-color: #3b82f6;
display: inline-block;
height: 3rem;
width: 3rem;
min-width: 3rem;
border-radius: 6.25rem;
opacity: .5
}
/*
* The CSS above has been taken from the following page:
*
* https://www.bootdey.com/snippets/view/timeline-steps
*
* */
/* Current modifications : minor style changes (UI mainly no Js and/or dynamic changes for the moment) */
.img_products {
width: 200px;
height: 200px;
}
.p_index_center {
text-align: center;
}
a {
cursor: pointer;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.col-lg-2 {
display: block;
margin: auto;
}
img.feed {
display: inline; /*Keep feed icon in footer aligned (as it's an image)*/
}
.bg-dark {
background-color: #1688AB !important;
}
.list-group-flush {
border-radius: 10px;
}
.card-title {
text-align: center;
font-family: "Fontin";
}
.h3, h3 {
font-family: 'Fontin';
}
.btn-primary {
background-color: #1688AB;
border-color: #1688AB;
}
.navbar-dark .navbar-nav .nav-link {
color: rgb(255,255,255);
}
.blogimg {
width: 35px;
}
/**************Animation File Start Here (animate.css)****************/
/**************Copy and Save this in another file (animate.css)****************/
/* Animation Delay */
.d01{ animation-delay:0.1s; -moz-animation-delay:0.1s; -webkit-animation-delay:0.1s; }
.d02{ animation-delay:0.2s; -moz-animation-delay:0.2s; -webkit-animation-delay:0.2s; }
.d03{ animation-delay:0.3s; -moz-animation-delay:0.3s; -webkit-animation-delay:0.3s; }
.d04{ animation-delay:0.4s; -moz-animation-delay:0.4s; -webkit-animation-delay:0.4s; }
.d05{ animation-delay:0.5s; -moz-animation-delay:0.5s; -webkit-animation-delay:0.5s; }
.d06{ animation-delay:0.6s; -moz-animation-delay:0.6s; -webkit-animation-delay:0.6s; }
.d07{ animation-delay:0.7s; -moz-animation-delay:0.7s; -webkit-animation-delay:0.7s; }
.d08{ animation-delay:0.8s; -moz-animation-delay:0.8s; -webkit-animation-delay:0.8s; }
.d09{ animation-delay:0.9s; -moz-animation-delay:0.9s; -webkit-animation-delay:0.9s; }
.d10{ animation-delay:1s; -moz-animation-delay:1s; -webkit-animation-delay:1s; }
.d11{ animation-delay:1.1s; -moz-animation-delay:1.1s; -webkit-animation-delay:1.1s; }
.d12{ animation-delay:1.2s; -moz-animation-delay:1.2s; -webkit-animation-delay:1.2s; }
.d13{ animation-delay:1.3s; -moz-animation-delay:1.3s; -webkit-animation-delay:1.3s; }
.d14{ animation-delay:1.4s; -moz-animation-delay:1.4s; -webkit-animation-delay:1.4s; }
.d15{ animation-delay:1.5s; -moz-animation-delay:1.5s; -webkit-animation-delay:1.5s; }
.d16{ animation-delay:1.6s; -moz-animation-delay:1.6s; -webkit-animation-delay:1.6s; }
.d17{ animation-delay:1.7s; -moz-animation-delay:1.7s; -webkit-animation-delay:1.7s; }
.d18{ animation-delay:1.8s; -moz-animation-delay:1.8s; -webkit-animation-delay:1.8s; }
.d19{ animation-delay:1.9s; -moz-animation-delay:1.9s; -webkit-animation-delay:1.9s; }
.d21{ animation-delay:2.1s; -moz-animation-delay:2.1s; -webkit-animation-delay:2.1s; }
.d26{ animation-delay:2.6s; -moz-animation-delay:2.6s; -webkit-animation-delay:2.6s; }
.t14{
animation-duration: 1.4s !important;
}
.t24{
animation-duration: 2.4s !important;
}
/*Animation ends*/
.anim,.anima {
opacity: 0;
}
.anim.animated,.anima.animated {
opacity: 1;
}
/***CSS Animations****/
/*!
* animate.css -http://daneden.me/animate
* Version - 3.5.2
* Licensed under the MIT license - http://opensource.org/licenses/MIT
*
* Copyright (c) 2017 Daniel Eden
*/
.animated {
animation-duration: 1s;
animation-fill-mode: both;
}
.animated.infinite {
animation-iteration-count: infinite;
}
.animated.hinge {
animation-duration: 2s;
}
.animated.flipOutX,
.animated.flipOutY,
.animated.bounceIn,
.animated.bounceOut {
animation-duration: .75s;
}
@keyframes bounce {
from, 20%, 53%, 80%, to {
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
transform: translate3d(0,0,0);
}
40%, 43% {
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
transform: translate3d(0, -30px, 0);
}
70% {
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0,-4px,0);
}
}
.animated.bounce {
animation-name: bounce;
transform-origin: center bottom;
}
@keyframes flash {
from, 50%, to {
opacity: 1;
}
25%, 75% {
opacity: 0;
}
}
.animated.flash {
animation-name: flash;
}
/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
@keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.05, 1.05, 1.05);
}
to {
transform: scale3d(1, 1, 1);
}
}
.animated.pulse {
animation-name: pulse;
}
@keyframes rubberBand {
from {
transform: scale3d(1, 1, 1);
}
30% {
transform: scale3d(1.25, 0.75, 1);
}
40% {
transform: scale3d(0.75, 1.25, 1);
}
50% {
transform: scale3d(1.15, 0.85, 1);
}
65% {
transform: scale3d(.95, 1.05, 1);
}
75% {
transform: scale3d(1.05, .95, 1);
}
to {
transform: scale3d(1, 1, 1);
}
}
.animated.rubberBand {
animation-name: rubberBand;
}
@keyframes shake {
from, to {
transform: translate3d(0, 0, 0);
}
10%, 30%, 50%, 70%, 90% {
transform: translate3d(-10px, 0, 0);
}
20%, 40%, 60%, 80% {
transform: translate3d(10px, 0, 0);
}
}
.animated.rubber {
animation-name: shake;
}
@keyframes headShake {
0% {
transform: translateX(0);
}
6.5% {
transform: translateX(-6px) rotateY(-9deg);
}
18.5% {
transform: translateX(5px) rotateY(7deg);
}
31.5% {
transform: translateX(-3px) rotateY(-5deg);
}
43.5% {
transform: translateX(2px) rotateY(3deg);
}
50% {
transform: translateX(0);
}
}
.animated.headShake {
animation-timing-function: ease-in-out;
animation-name: headShake;
}
@keyframes swing {
20% {
transform: rotate3d(0, 0, 1, 15deg);
}
40% {
transform: rotate3d(0, 0, 1, -10deg);
<