diff --git a/assets/images/services/ansible.svg b/assets/images/services/ansible.svg new file mode 100644 index 00000000..07a76db8 --- /dev/null +++ b/assets/images/services/ansible.svg @@ -0,0 +1,14 @@ + + diff --git a/assets/scss/components/_banner.scss b/assets/scss/components/_banner.scss index 1f976847..8f5751d8 100644 --- a/assets/scss/components/_banner.scss +++ b/assets/scss/components/_banner.scss @@ -25,6 +25,7 @@ } p { + margin: 0 0 15px; max-width: 700px; } diff --git a/assets/scss/components/_breadcrumb.scss b/assets/scss/components/_breadcrumb.scss new file mode 100644 index 00000000..b5b5a7d8 --- /dev/null +++ b/assets/scss/components/_breadcrumb.scss @@ -0,0 +1,24 @@ +@use '../abstracts' as *; + +.breadcrumb { + margin: 50px 0 30px; + display: flex; + justify-content: flex-start; +} + +.breadcrumb__item { + &:before { + display: none; + } + + &:after { + top: 50%; + transform: translateY(-50%); + content: '\e90b'; + font-size: toRem(16px); + } + + a { + text-decoration: none; + } +} diff --git a/assets/scss/components/_glossary-list.scss b/assets/scss/components/_glossary-list.scss new file mode 100644 index 00000000..47febe1d --- /dev/null +++ b/assets/scss/components/_glossary-list.scss @@ -0,0 +1,118 @@ +@use 'sass:math'; +@use '../abstracts' as *; + +.glossary-list { + margin: 0; + padding: 0; + width: math.div(100%, 3); + min-width: math.div(100%, 3); +} + +.glossary-list__item { + margin-bottom: 15px; + padding-right: 30px; + padding-left: 100px; + display: flex; + + &:before, + &:after { + display: none; + } + + &:first-of-type { + margin-top: 0; + } + + a { + font-size: toRem(20px); + line-height: 1.3; + } +} + +[class*="glossary-list__item--"] { + margin-top: 50px; + position: relative; + + &:before { + height: unset; + width: unset; + position: absolute; + top: -8px; + left: 0; + display: flex; + font-family: $tertiary-font; + font-size: toRem(72px); + line-height: 1; + text-transform: uppercase; + border: none; + background: none; + } +} + +$characters: ( + 0: '#', + a: 'a', + b: 'b', + c: 'c', + d: 'd', + e: 'e', + f: 'f', + g: 'g', + h: 'h', + i: 'i', + j: 'j', + k: 'k', + l: 'l', + m: 'm', + n: 'n', + o: 'o', + p: 'p', + q: 'q', + r: 'r', + s: 's', + t: 't', + u: 'u', + v: 'v', + w: 'w', + x: 'x', + y: 'y', + z: 'z' +); + +@each $character, $character-icon in $characters { + .glossary-list__item--#{$character} { + &:before { + content: $character-icon; + } + } +} + +@media(max-width: $screen-md) { + .glossary-list__item { + padding-left: 60px; + + a { + font-size: toRem(18px); + } + } + + [class*="glossary-list__item--"] { + &:before { + top: -1px; + font-size: toRem(40px); + } + } +} + +@media(max-width: $screen-xs) { + .glossary-list { + width: 100%; + min-width: 100%; + } + + [class*="glossary-list__item--"] { + &:first-of-type { + margin-top: 50px; + } + } +} diff --git a/assets/scss/components/_glossary.scss b/assets/scss/components/_glossary.scss new file mode 100644 index 00000000..83549814 --- /dev/null +++ b/assets/scss/components/_glossary.scss @@ -0,0 +1,13 @@ +@use '../abstracts' as *; + +.glossary { + margin: 0 0 100px; + display: flex; + flex-wrap: wrap; +} + +@media (max-width: $screen-xs) { + .glossary { + margin: 0 0 50px; + } +} diff --git a/assets/scss/layout/_footer.scss b/assets/scss/layout/_footer.scss index 2d581b8b..c9f14e6b 100644 --- a/assets/scss/layout/_footer.scss +++ b/assets/scss/layout/_footer.scss @@ -140,6 +140,7 @@ } .pages { + margin-top: 100px; width: 300px; display: flex; } diff --git a/assets/scss/pages/_page-glossary.scss b/assets/scss/pages/_page-glossary.scss new file mode 100644 index 00000000..0ce1be27 --- /dev/null +++ b/assets/scss/pages/_page-glossary.scss @@ -0,0 +1,28 @@ +@use '../abstracts' as *; + +.page-glossary { + .banner { + height: 1550px; + } + + main { + background-image: none; // remove background-image to prevent ugliness when not much content on page + } + + .glossary-logo { + margin: 0 auto 50px; + max-width: 400px; + } + + .content-links { + margin-top: 300px; + } +} + +@media (max-width: $screen-md) { + .page-glossary { + .content-links { + margin-top: 100px; + } + } +} diff --git a/assets/scss/style.scss b/assets/scss/style.scss index d7723e08..98fab185 100644 --- a/assets/scss/style.scss +++ b/assets/scss/style.scss @@ -1,13 +1,3 @@ -// @use "~prismjs/themes/prism-tomorrow.css"; -// @use '~aos/dist/aos'; - -// Prevents hiding elements for animations if js is not enabled: -// html.no-js [data-aos] { -// opacity: 1; -// transform: none; -// pointer-events: unset; -// } - @use "base/_reset"; @use "base/_font-face"; @@ -29,6 +19,7 @@ @use "components/_banner"; @use "components/_button"; @use "components/_comment"; +@use "components/_breadcrumb"; @use "components/_blockquote"; @use "components/_miniature"; @use "components/_miniature-inline"; @@ -53,6 +44,8 @@ @use "components/_preview"; @use "components/_miniature-highlight"; @use "components/_side-image"; +@use "components/_glossary"; +@use "components/_glossary-list"; @use "generic/_a"; @use "generic/_code"; @@ -61,8 +54,6 @@ @use "generic/_p"; @use "generic/_titles"; @use "generic/_ul"; -// // @use "generic/_iframe"; -// // @use "generic/_kbd"; @use "utilities/_screen-reader"; @@ -76,3 +67,4 @@ @use "pages/_page-legals"; @use "pages/_page-error"; @use "pages/_page-signature"; +@use "pages/_page-glossary"; diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 808d615d..3d47229c 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -24,7 +24,7 @@ twig: trackers: matomo: "%env(MATOMO_ID)%" - + caseStudies: enabled: true @@ -45,6 +45,7 @@ twig: footer: - { path: "case_studies", label: "Cas clients" } - { path: "about", label: "À propos" } + - { path: "glossary", label: "Glossaire" } - { path: "contact", label: "Contact" } footerServices: diff --git a/content/member/_sample.yaml b/content/member/_sample.yaml index 31dab47f..2684f689 100644 --- a/content/member/_sample.yaml +++ b/content/member/_sample.yaml @@ -20,10 +20,6 @@ linkedIn: ~ email: ~ avatar: content/images/member/avatars/path-to-avatar.jpg -certifications: - - symfony - - opquast - emojis: - 🎲 - 🎮 diff --git a/content/member/frey.yaml b/content/member/frey.yaml index 2717cca3..64bb985e 100644 --- a/content/member/frey.yaml +++ b/content/member/frey.yaml @@ -17,8 +17,6 @@ linkedIn: ~ email: florian.rey@elao.com avatar: content/images/member/avatars/ffrey.jpg -certifications: [ ] - emojis: - 🌰 - 👾 diff --git a/content/member/gfaivre.yaml b/content/member/gfaivre.yaml index 2af72b72..8ee082d9 100644 --- a/content/member/gfaivre.yaml +++ b/content/member/gfaivre.yaml @@ -14,8 +14,6 @@ avatar: content/images/member/avatars/gfaivre.jpg phone: '007' -certifications: [ ] - emojis: - 🤾🏻♂️ - 🎮 diff --git a/content/member/yheitz.yaml b/content/member/yheitz.yaml index c2cd88ab..19d18d75 100644 --- a/content/member/yheitz.yaml +++ b/content/member/yheitz.yaml @@ -13,6 +13,4 @@ linkedIn: ~ email: yves.heitz@elao.com avatar: content/images/member/avatars/yheizt.png -certifications: [ ] - emojis: [ ] diff --git a/content/term/ansible.md b/content/term/ansible.md new file mode 100644 index 00000000..071e44f0 --- /dev/null +++ b/content/term/ansible.md @@ -0,0 +1,34 @@ +--- +name: "Ansible" +logo: "build/images/services/ansible.svg" +externalLink: https://www.ansible.com/ +metaDescription: Adeptes de la première heure d'Ansible, nous continuons 10 ans plus tard à l'utiliser de manière intensive pour la construction de nos infrastructures et de nos environnement de développement. +--- + +## C'est quoi Ansible ? +Ansible est une plateforme open-source de gestion de configuration et d'automatisation des tâches. +Elle permet aux administrateurs système mais aussi aux développeurs de définir des configurations, des déploiements et des actions à effectuer sur des serveurs et des infrastructures de manière reproductible. + +Ansible se distingue par sa simplicité d'utilisation grâce à sa syntaxe déclarative en **YAML**, qui **décrit l'état souhaité du système**. Il n'exige **aucune installation d'agent** sur les machines cibles, fonctionne via SSH ou d'autres protocoles, et offre une grande flexibilité pour automatiser des opérations complexes, la gestion de configurations, et le déploiement d'applications. + +Nous l'utilisons maintenant depuis 10 ans afin de piloter la configuration de nos environnements applicatifs et mettons à disposition de la communauté de nombreux rôles éprouvés en production sur des infrastructures conséquentes à travers notre projet Open Source [Manala](https://github.com/manala/ansible-roles). + +Nous sommes également à l'origine de la création des **« meetups » Lyonnais Ansible**, que nous avons organisés et pilotés pendant plusieurs années. + +## Pourquoi Ansible ? + +Questions souvent posée, nous avons travaillons par le passé avec Chief et Puppet en passant par Salt mais quand Ansible est apparu il s'est rapidement imposé chez nous notamment en raison de sa rapidité d'apprentissage et de sa popularité au sein des équipes de développeurs. + +En apportant notre expertise Ops nous devons également réfléchir à la facilité de prise en main des solutions que nous proposons aux équipes applicatives. + +## Son utilisation chez Rix + +Il est utilisé sur l'ensemble des tâches de configuration des environnements, entre autres: + +- Gestion des configurations +- Installation des services +- Gestion des accès + +Nous le couplons à Terraform qui porte lui la responsabilité de constructions des éléments d'infrastructure. + +Il est également prépondérant pour la construction des environnements de développement à destination des équipes applicatives. \ No newline at end of file diff --git a/content/term/aws.md b/content/term/aws.md new file mode 100644 index 00000000..4a2010a0 --- /dev/null +++ b/content/term/aws.md @@ -0,0 +1,8 @@ +--- +name: "AWS" +logo: "build/images/services/aws.svg" +externalLink: https://aws.amazon.com/fr/ +#metaDescription: TODO +--- + +Some **markdown** content diff --git a/content/term/aws.yaml b/content/term/aws.yaml deleted file mode 100644 index 19474b6d..00000000 --- a/content/term/aws.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: "AWS" -logo: "build/images/services/aws.svg" -link: https://aws.amazon.com/fr/ diff --git a/content/term/example.md b/content/term/example.md new file mode 100644 index 00000000..a3469a6c --- /dev/null +++ b/content/term/example.md @@ -0,0 +1,17 @@ +--- +name: "Exemple" +logo: "build/images/technos/exemple.svg" +externalLink: http://example.org + +# False to prevent listing it on the glossary page. +# Cans till be externalLinked from articles or case studies. +listInGlossary: false + +# Array of slugs of related articles to show on the glossary term page. +# If not provided (null), will search for related articles by their tags. +articles: [] + +metaDescription: Une description courte à utiliser dans les meta de la page +--- + +Some **markdown** content diff --git a/content/term/example.yaml b/content/term/example.yaml deleted file mode 100644 index 17f798a4..00000000 --- a/content/term/example.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: "Exemple" -logo: "build/images/technos/exemple.svg" -link: http://example.org diff --git a/content/term/ovh-cloud.md b/content/term/ovh-cloud.md new file mode 100644 index 00000000..520c35ce --- /dev/null +++ b/content/term/ovh-cloud.md @@ -0,0 +1,8 @@ +--- +name: "OVH Cloud" +logo: "build/images/services/ovh-cloud.svg" +externalLink: https://www.ovhcloud.com/fr/ +#metaDescription: TODO +--- + +Some **markdown** content diff --git a/content/term/ovh-cloud.yaml b/content/term/ovh-cloud.yaml deleted file mode 100644 index e824d23b..00000000 --- a/content/term/ovh-cloud.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: "OVH Cloud" -logo: "build/images/services/ovh-cloud.svg" -link: https://www.ovhcloud.com/fr/ diff --git a/content/term/scaleway.md b/content/term/scaleway.md new file mode 100644 index 00000000..1179ed93 --- /dev/null +++ b/content/term/scaleway.md @@ -0,0 +1,8 @@ +--- +name: "Scaleway" +logo: "build/images/services/scaleway.svg" +externalLink: https://www.scaleway.com/fr/ +#metaDescription: TODO +--- + +Some **markdown** content diff --git a/content/term/scaleway.yaml b/content/term/scaleway.yaml deleted file mode 100644 index 19e7b3eb..00000000 --- a/content/term/scaleway.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: "Scaleway" -logo: "build/images/services/scaleway.svg" -link: https://www.scaleway.com/fr/ diff --git a/src/Controller/GlossaryController.php b/src/Controller/GlossaryController.php new file mode 100644 index 00000000..d581b064 --- /dev/null +++ b/src/Controller/GlossaryController.php @@ -0,0 +1,62 @@ +manager = $manager; + } + + #[Route('/', name: 'glossary')] + public function glossary(GlossaryBuilder $builder): Response + { + $terms = $this->manager->getContents(Term::class, 'name', ['listInGlossary' => true]); + $articles = $this->manager->getContents(Article::class, ['date' => false]); + + return $this->render('glossary/index.html.twig', [ + 'glossary' => $builder->build($terms), + 'articles' => \array_slice($articles, 0, 2), + ]); + } + + #[Route('/{term}', name: 'glossary_term')] + public function show(Term $term): Response + { + $articlesFilter = null !== $term->articles + // Search for articles by their slug if provided + ? static fn ($article) => \in_array($article->slug, $term->articles, true) + // otherwise by their tags matching the term slug + : static fn (Article $article): bool => $article->hasTag($term->slug) + ; + + $articles = $this->manager->getContents(Article::class, ['date' => false], $articlesFilter); + + $caseStudies = $this->manager->getContents( + CaseStudy::class, + ['date' => false], + fn (CaseStudy $caseStudy): bool => $caseStudy->enabled && $caseStudy->hasTerm($term) + ); + + return $this->render('glossary/term.html.twig', [ + 'term' => $term, + 'articles' => \array_slice($articles, 0, 3), + 'caseStudies' => $caseStudies, + ])->setLastModified($term->lastModified); + } +} diff --git a/src/Glossary/GlossaryBuilder.php b/src/Glossary/GlossaryBuilder.php index f44b997f..6e193059 100644 --- a/src/Glossary/GlossaryBuilder.php +++ b/src/Glossary/GlossaryBuilder.php @@ -9,8 +9,8 @@ class GlossaryBuilder { /** - * @param array|Term[] $terms - * @param int<0, max> $split + * @param Term[] $terms + * @param int<0, max> $split */ public function build(array $terms, int $split = 3): array { diff --git a/src/Model/Glossary/Term.php b/src/Model/Glossary/Term.php index 6b1eafca..43e93983 100644 --- a/src/Model/Glossary/Term.php +++ b/src/Model/Glossary/Term.php @@ -4,11 +4,37 @@ namespace App\Model\Glossary; +use App\Model\MetaTrait; + class Term { - public string $name; - public ?string $logo = null; + use MetaTrait; + public string $slug; - public string $link; + + public ?string $logo = null; + + /** Link to outside resource for this term. */ + public string $externalLink; + + public string $name; + + /** Main, markdown content */ + public ?string $content = null; + + /** + * Array of slugs of related articles to show on the glossary term page. + * If not provided (null), will search for related articles by their tags. + * + * @var string[]|null + */ + public ?array $articles = null; + public \DateTimeInterface $lastModified; + + /** + * Set as false to prevent this term to appear in glossary listing. + * The term can still be referenced from articles or case studies. + */ + public bool $listInGlossary = true; } diff --git a/src/Model/Member.php b/src/Model/Member.php index 142ec773..7f1bde52 100644 --- a/src/Model/Member.php +++ b/src/Model/Member.php @@ -34,9 +34,6 @@ class Member public ?string $phone = null; - /** @var string[] */ - public array $certifications = []; - public ?array $emojis = []; // Flags diff --git a/templates/case_study/show.html.twig b/templates/case_study/show.html.twig index df8ef417..5cf88b94 100644 --- a/templates/case_study/show.html.twig +++ b/templates/case_study/show.html.twig @@ -1,12 +1,13 @@ {% import "macros.html.twig" as macros %} + {% extends 'base.html.twig' %} {% block meta_title -%} - {{ caseStudy.metaTitle|default(caseStudy.title) }} | {{ parent() }} + {{ caseStudy.metaTitle ?? caseStudy.title }} | {{ parent() }} {%- endblock %} {% block meta_description -%} - {{ caseStudy.metaDescription|default(caseStudy.description)|default(parent()) }} + {{ caseStudy.metaDescription ?? parent() }} {%- endblock %} {% block og_image asset(caseStudy.images|first|glide_image_preset('opengraph_image')) %} @@ -42,7 +43,7 @@
Pour aller encore plus loin dans le quotidien d'un projet web, en apprendre plus sur notre métier, sur nos retours d'expérience.
+{{ article.description }}
+ + +{{ caseStudy.description }}
+ +{{ article.description }}
+ + +