Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 1 addition & 56 deletions pwa/app/(con)/[locale]/con/2026/components/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,55 +51,11 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => {
{t("buy_tickets")}
</BuyButton>
)}
<Button
className="empty"
to={`/${locale}/con/2026/call-for-papers`}
>
{t("2026.cfp.button")}
</Button>
</div>
</div>
</div>
<Wave className="absolute opacity-30 z-0 bottom-0 h-[60vh] left-1/2 top-[68%] -translate-y-1/2" />
</Section>
<Section
section="lastYear"
className="bg-white z-10 relative pb-10 overflow-y-clip"
>
<div className="container text-center">
<SectionTitle>
<Translate translationKey="last_edition.title" />
</SectionTitle>
<SectionSubTitle>
<Translate
translationKey="last_edition.subtitle"
translationParams={{
edition: "2025",
link: (
<a href={`/${locale}/con/2025/review`} className="link">
{t("last_edition.subtitle_link")}
</a>
),
}}
/>
</SectionSubTitle>
<PictureGallery
className="py-4"
link="https://www.flickr.com/photos/194052559@N02/albums/72177720329148577/"
>
{images.map((image: string) => (
<Image
className="object-cover"
key={image}
fill
src={image}
alt=""
sizes="(max-width: 640px) 200px, (max-width: 768px) 240px, (max-width: 1536px) 300px, 400px"
/>
))}
</PictureGallery>
</div>
</Section>
<Section
section="speakers"
className="bg-grey z-10 relative py-4 overflow-x-hidden"
Expand All @@ -110,18 +66,7 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => {
</SectionTitle>
<SectionSubTitle>
<Translate
translationKey="2026.our_speakers.subtitle"
translationParams={{
edition: "2026",
link: (
<a
href={`/${locale}/con/2026/call-for-papers`}
className="link"
>
{t("2026.our_speakers.subtitle_link")}
</a>
),
}}
translationKey="2026.our_speakers.subtitle2"
/>
</SectionSubTitle>
<SpeakerList speakers={speakers} max={9} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SpeakerImage from "components/con/speakers/SpeakerImage";
import classNames from "classnames";
import { getConferenceDate } from "utils/con";
import Link from "next/link";
import TagLabel from "components/con/conferences/TagLabel";

interface ConferencesProps {
conferences: Conference[];
Expand All @@ -21,7 +22,7 @@ export default function SpeakerPageListTemplate({
edition,
days,
}: ConferencesProps) {
const is2025 = edition === "2025";
const is2025 = edition === "2025" || edition === "2026";
const { t, locale, Translate } = useContext(LanguageContext);
return (
<div className="container flex flex-col items-center pt-10 | sm:pt-20">
Expand Down Expand Up @@ -123,6 +124,11 @@ export default function SpeakerPageListTemplate({
</div>
</div>
<div className="flex flex-col gap-2 flex-1">
<div className="flex flex-row gap-1">
{conference.tag
? conference.tag.split(",").map((t) => <TagLabel key={t} small tag={t} />)
: null}
</div>
<h2 className="font-title font-bold text-2xl lined-blue lined-center md:after:left-0 md:after:translate-x-0">
{conference.title}
</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const ConferenceSpeaker = ({ conference }: SpeakerProps) => {
speakers.length === 1 && "md:mx-auto md:w-60 md:h-60"
)}
>
{conference.edition === "2025" ? (
{conference.edition === "2025" ||
conference.edition === "2026" ? (
<SpeakerImage2025
speaker={speaker}
image={image}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
}

.description ul {
@apply list-disc text-left pl-7;
@apply list-disc text-left pl-7 mb-6;
}

.description ul li:not(last-child) {
.description ul li {
@apply mb-4;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}

.description p:not(:last-child) {
@apply mb-6;
@apply mb-4;
}

.description a {
Expand All @@ -21,9 +21,9 @@
}

.description ul {
@apply list-disc text-left pl-7;
@apply list-disc text-left pl-7 mb-8;
}

.description ul li:not(last-child) {
@apply mb-2;
@apply mb-1;
}
1 change: 1 addition & 0 deletions pwa/app/(con)/[locale]/con/[edition]/conferences/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const generateStaticParams = async () => {
{ edition: "2023" },
{ edition: "2024" },
{ edition: "2025" },
{ edition: "2026" },
];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function SpeakerPageTemplate({
</div>
<div className="flex flex-col relative flex-wrap items-center bg-grey px-10 pb-10 pt-28 | lg:flex-row lg:items-start | sm:pb-20">
<div className="w-72 h-72 | md:w-80 md:h-80 | lg:w-[400px] lg:h-[400px]">
{edition === "2025" ? (
{edition === "2025" || edition === "2026" ? (
<SpeakerImage2025
speaker={speakerData}
big
Expand Down
1 change: 1 addition & 0 deletions pwa/app/(con)/[locale]/con/[edition]/speakers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const generateStaticParams = async () => {
{ edition: "2023" },
{ edition: "2024" },
{ edition: "2025" },
{ edition: "2026" },
];
};

Expand Down
2 changes: 1 addition & 1 deletion pwa/components/con/speakers/SpeakerImage2025.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function SpeakerImage({
placeholder,
id,
}: SpeakerImageProps) {
if (speaker.edition === "2025") {
if (speaker.edition === "2025" || speaker.edition === "2026") {
const { name } = speaker;
const angle = nameToAngle(name);
const size = nameToSize(name);
Expand Down
2 changes: 1 addition & 1 deletion pwa/components/con/speakers/SpeakerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default function SpeakerItem({
minified ? "flex flex-row items-center" : "text-center"
)}
>
{edition === "2025" ? (
{edition === "2025" || edition === "2026" ? (
<div
className={classNames(minified ? "w-20 h-20" : "mx-auto w-64 h-64")}
>
Expand Down
11 changes: 11 additions & 0 deletions pwa/data/con/2026/conferences/antoine-opening-keynote.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
type: conference
speakers: -antoine-bluchet-2026
short: TBA
tag: feedback
track: '1'
---

# Opening Keynote (🇺🇸)

This talk topic will be announced shortly.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
type: conference
speakers: -matthieu-werner-2026
short: "Alliez la richesse d'API Platform à la puissance brute de Go. Un REX pragmatique sur l'orchestration de microservices via des DTOs, Jane PHP et AutoMapper."
tag: tools
track: '1'
---

# API Platform : Le Hub Sémantique qu'on mérite (et comment piloter du Go avec) (🇫🇷)

Faire du microservice, c'est souvent troquer une stack cohérente contre une armée de petits services qui parlent tous un dialecte potentiellement différent. On choisit Go pour la perf brute (et parce que c'est cool), mais on finit avec des **APIs "plates"** qui ont perdu toute la richesse sémantique qu'on aime tant dans l'écosystème PHP.

L'idée de ce talk ? Arrêter de forcer Go à faire du Web élégant et arrêter de forcer PHP à faire du calcul ultra-critique.
Je vous propose d'explorer un pattern que j'affectionne : **API Platform utilisé comme un "Semantic Hub"**. On va voir comment poser API Platform en frontal pour garantir le contrat (JSON-LD, Hydra, OpenAPI) et déléguer le "sale boulot" à des microservices derrière.

Au menu de cette session :

- Pourquoi API Platform est la **meilleure gateway du marché** pour unifier votre SI.
- Comment **Jane PHP et AutoMapper** sauvent vos State Providers en générant des clients type-safe en deux commandes.
- Comment on "court-circuite" l'ORM pour mapper des **DTOs** sans perdre les bénéfices du framework.
- Cas pratique : On prendra des exemples dans la monétique pour illustrer comment gérer des flux transactionnels sans casser la sémantique.
- Vibe Coding & IA : Pourquoi une API sémantique est le seul moyen de ne pas rendre vos futurs agents IA complètement fous.

On ne parlera pas de futur, mais de pragmatisme : comment garder la **maîtrise de son contrat d'interface** quand le backend part dans tous les sens.
13 changes: 13 additions & 0 deletions pwa/data/con/2026/conferences/building-a-framework-by-accident.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
type: conference
speakers: -brent-roose-2026
short: "An accidental journey into modern software design. Uncover the lessons learned and the core features behind the Tempest framework."
tag: tools
track: '1'
---

# Building a framework by accident (🇺🇸)

For the past three years — and by **total accident** — I've had the chance to work on the most impactful project of my programming career.

In this talk, I want to walk you through how that happened, and share the many lessons I learned along the way. We'll talk about **the power of open source**, designing modern software and dive into some of Tempest's features.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
type: conference
speakers: -johan-janssens-2026
short: "PHP on the desktop sounds crazy—until it works. Discover how to combine FrankenPHP and Wails to build fast, native desktop applications within a single binary."
tag: archi
track: '1'
---

# Building Desktop Apps with FrankenPHP (🇺🇸)

HP on the desktop sounds like a bad idea. Until it works.

FrankenPHP isn't just a Caddy module, it's a Go library you can embed anywhere. FrankenWails combines it with Wails, Go's answer to Electron. The result: native desktop apps where PHP handles the backend, HTML/CSS/JS handles the UI, and Go is the glue. No Node.js, no Electron, no server. Just a single binary.

In this talk, we'll look at how PHP, Go, and the frontend communicate inside a single process, how to expose native menus, dialogs, and system tray to PHP, and how to distribute your app, either as a single binary or by packaging your PHP code as a PHAR archive that the runtime can load directly.

We'll walk through the code, run live demos, and end with a working desktop app that you'd never guess isn't native. Don't worry if you don't know Go, if you know PHP it'll feel very familiar.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
type: conference
speakers: -abdellah-el-ghailani-2026
short: Keep your APIs fast and resilient when legacy backends are slow.
tag: feedback
track: '1'
---

# Building Resilient Architecture : Event-Driven Design with API Platform, Messenger & Redis (🇺🇸)

Modern enterprise systems can't afford to be fragile. When a critical downstream service is slow, an ERP takes 3 seconds to respond, or traffic spikes unexpectedly, your API needs to keep serving gracefully.

In this talk, I'll share hard-won lessons from a real-world migration: **replacing a legacy BizTalk middleware layer with a Symfony/API Platform application** that talks directly to SAP via RFC, processes orders asynchronously through Messenger, and uses Redis both as a cache layer and a message transport.

We'll cover how to design API Platform resources that respond instantly by deferring heavy work to Messenger workers, how to implement smart Redis caching strategies that protect your backend from stampedes, and how to structure your message handlers for retry, failure isolation, and observability.

We'll also look at the tricky parts nobody warns you about : backward compatibility with legacy REST consumers, cache invalidation timing, and what happens when your SAP connection pool runs dry on a Monday morning.

No slides full of theory. This is a production architecture, running today, handling real orders for a manufacturing company. **You'll leave with a concrete, production-tested architecture pattern you can apply to any project where reliability matters more than cleverness.**
18 changes: 18 additions & 0 deletions pwa/data/con/2026/conferences/ddd-x-api-platform-4-years-later.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
type: conference
speakers: -mathias-arlaud-2026
short: "When business complexity outgrows the defaults. Discover how to use API Platform 4 and DDD to build robust architectures, on and off the framework's rails."
tag: good-practices
track: '1'
---

# DDD x API Platform: 4 years later (🇺🇸)

In 2022, we explored how **Domain-Driven Design** principles could be applied with API Platform 3, which helped making API Platform better.

Four years later, **API Platform 4, PHP 8.5 and Symfony 8** have reshaped the landscape. Time to revisit the topic!
API Platform is the most productive framework for building web APIs. Its conventions and Doctrine integration make it incredibly fast to get started. But when **business complexity grows**, that simplicity slowly becomes a constraint.

This talk picks up where the first edition left off. With its **revamped resource model**, state processors/providers and filters system, API Platform 4 makes it easier than ever to structure applications around your domain. But the real value of DDD shows when the framework's defaults no longer fit: **heavy data processing**, **large dataset streaming powered by Symfony's JsonStreamer** - the kind of scenarios where you need to step beyond the built-in conventions.

**Hexagonal architecture**, **message-oriented design**, **clear boundaries between domain and infrastructure**: we'll show how these patterns translate concretely into an API Platform 4 project, both when you stay on the rails and when you deliberately leave them.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
type: conference
speakers: -sebastien-rogier-2026
short: "D'une usine à gaz à un système d'agents asynchrones : comment abstraire, orchestrer et fiabiliser 40 000 requêtes IA par jour en PHP."
tag: feedback
track: '1'
---

# De GPT-3 aux agents : 5 ans d'évolution d'une stack LLM en PHP (🇫🇷)

En 2021, l'effet "magique" : nous intégrons GPT-3 à notre SaaS SEO (stack Symfony/API Platform). Un simple appel à une API, un prompt, et nous avons des suggestions de titres dans notre application.

Deux ans plus tard, l'effet magique s'estompe. Nous maintenons des dizaines de "générateurs". **L'architecture (1 classe = 1 prompt) est devenue une usine à gaz**, difficile à maintenir ou à faire évoluer.

2024 : Le besoin d'intégrer Claude expose notre dépendance technique. Nous devons intégrer un second provider dans une architecture 100% OpenAI. Première refonte : une abstraction multi-provider avec fallback. Changer de LLM devient une ligne de config. Mais les nouvelles features exigent d'aller plus loin. Le besoin émerge de gérer le streaming, de maintenir des échanges LLM de plusieurs minutes, et d'orchestrer des prompts secondaires. Deuxième transformation : **nous passons à un système d'agent asynchrone**. L'agent peut utiliser des "tools" (connectés à notre stack ou des API tierces) pour exécuter ces workflows complexes, tout en gardant la performance comme priorité.
Cette nouvelle stack a soulevé des défis majeurs en PHP : fiabilisation de l'exécution, observabilité de workflows complexes, et gestion de la parallélisation/asynchronisme des "tools" sans async/await natif.

Aujourd'hui, notre système (templates versionnés, observabilité complète, error recovery) gère environ 40 000 requêtes/jour. Ce talk est le REX de 5 ans de **choix d'archi**, de **patterns**, et de belles problématiques pour **faire tourner des LLMs en production... avec PHP**.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
type: conference
speakers: -yoan-bernabeu-2026
short: Du local à la production en une seule commande.
tag: feedback
track: '1'
---

# De zéro à la prod : le déploiement Symfony enfin accessible aux débutant·es (🇫🇷)

Beaucoup de devs Symfony savent construire une application, mais **bloquent au moment de la mise en ligne**. Le fossé entre le local et la production (serveur, conteneurs, certificats) reste immense pour les novices.

Dans cette conférence, je vous présente **FrankenDeploy**, un CLI open source permettant de déployer une application Symfony sur n'importe quel VPS en une seule commande. Nous aborderons :

- Les problématiques de déploiement pour les débutant·es ;
- Les choix techniques et les coulisses de l'outil (détection auto, orchestration, rollback) ;
- Les défis rencontrés lors de sa conception.

L'objectif est de montrer qu'un déploiement serein ne doit plus être réservé aux expert·s et d'encourager la création d'outils rendant l'écosystème Symfony plus accessible.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
type: conference
speakers: -mathieu-santostefano-2026
short: "De OAuth2 à Keycloak en passant par Symfony, découvrez comment implémenter des standards de sécurité modernes pour vos APIs sans y laisser votre santé mentale."
tag: security
track: '1'
---

# Des APIs sécurisées sans perdre la tête (🇫🇷)

La sécurisation d'une API n'a pas toujours été facile, mais ces dernières années, **l'authentification a été standardisée**. Des solutions modernes et robustes ont vu le jour.

Vous avez peut-être rencontré les mots-clés Oauth2, OIDC, JWT, Rate Limiting au cours des dernières années. Ce sont les technologies qui sont les fondations de la sécurisation de vos API. Mais nous irons plus loin, avec des outils comme **Keycloak** et de toutes nouvelles fonctionnalités de Symfony, qui nous éviteront d'avoir à implémenter des protocoles complexes en PHP.

En tant que développeur d'API, vous découvrirez comment **améliorer la sécurité de votre API** de façon moderne, en utilisant les bons outils.
En tant que consommateur d'API, vous découvrirez comment interagir **en toute sécurité** avec des API externes.

Que vous développiez votre propre API ou que vous soyez client d'une API externe, venez apprendre à travailler en toute sécurité sans perdre la tête !
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
type: conference
speakers: -damien-fernandes-2026
short: "Vous les croisez tous les jours dans vos composer.json. Il est temps de démystifier les extensions PHP, de comprendre leurs rouages et d'apprendre à créer la vôtre."
tag: archi
track: '1'
---

# Extension 101 : Invisibles mais indispensables (🇫🇷)

Vous avez sûrement déjà croisé des noms comme **ext-json**, **ext-mbstring**, ou **ext-libxml** dans vos fichiers composer.json, sans forcément comprendre ce qu’ils font — à part qu’ils sont indispensables au bon fonctionnement de vos applications.

Mais ces packages ne viennent pas de Packagist : ce sont des **extensions PHP**, des modules natifs qui enrichissent le langage avec des fonctionnalités supplémentaires et souvent essentielles.

C'est l'heure de **démystifier ces fameuses extensions** : à quoi elles servent, comment elles fonctionnent, et surtout, comment créer la vôtre ! L’occasion de (re)découvrir PHP sous un nouvel angle, et de donner un peu de sens à ces lignes parfois obscures dans vos composer.json.
Loading
Loading