Skip to content
Closed
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
49 changes: 49 additions & 0 deletions .github/workflows/fetch-faq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Update Discourse data

on:
workflow_dispatch:
schedule:
- cron: "0 6 * * *" # every day at 06:00 UTC

jobs:
update-discourse-data:
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Create GitHub App token
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.WEBSITE_UPDATER_APPID }}
private-key: ${{ secrets.WEBSITE_UPDATER_KEY }}

- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"

- name: Fetch latest news from Discourse
run: python tools/fetch-news.py

- name: Configure Git author
run: |
git config --local user.name "precice-bot"
git config --local user.email "info@precice.org"

- name: Commit changes (if any)
run: |
git add assets/data/news.json
git commit -m "Update Discourse news data [skip ci]" || echo "No changes to commit"

- name: Push commit
uses: ad-m/github-push-action@master
with:
github_token: ${{ steps.app-token.outputs.token }}
branch: ${{ github.ref }}
4 changes: 2 additions & 2 deletions _data/sidebars/community_sidebar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ entries:
- title: Example - OpenFOAM adapter
url: /community-guidelines-adapters-openfoam.html
output: web



- title: Example - OpenDiHu adapter
url: /community-guidelines-adapters-opendihu.html
Expand All @@ -138,7 +140,5 @@ entries:
- title: Community channels
url: /community-channels.html
output: web




7 changes: 6 additions & 1 deletion _data/sidebars/docs_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ entries:
- title: Roadmap
url: /fundamentals-roadmap.html
output: web, pdf


- title: FAQ
url: /fundamentals-faq.html
output: web, pdf
tags: faq

- title: Previous versions
url: /fundamentals-previous-versions.html
output: web, pdf
Expand Down
29 changes: 29 additions & 0 deletions content/docs/fundamentals/fundamentals-faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
layout: default
title: FAQ
parent: Fundamentals
permalink: /fundamentals-faq.html
tags: [faq]
---

<h1>Frequently Asked Questions</h1>
<p style="color:#666;">Browse and search frequently asked questions mirrored from the preCICE Discourse forum.</p>

<div style="display:flex;flex-wrap:wrap;gap:8px;margin:12px 0;">
<input id="q" placeholder="Search questions..." style="padding:8px;border:1px solid #ddd;border-radius:8px;min-width:240px;">
<select id="sort" style="padding:8px;border:1px solid #ddd;border-radius:8px;">
<option value="last_posted_at">Sort by last activity</option>
<option value="created_at">Sort by creation date</option>
<option value="posts_count">Sort by replies</option>
<option value="views">Sort by views</option>
<option value="like_count">Sort by likes</option>
</select>
</div>

<p id="meta" style="margin:0 0 8px 0;color:#666;"></p>
<p id="stats" style="margin:0 0 16px 0;color:#666;"></p>

<div id="list" style="display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));"></div>
<div id="empty" style="display:none;color:#666;padding:16px 0;text-align:center;">No results found.</div>

<script src="/js/forum-fetch.js"></script>
13 changes: 12 additions & 1 deletion css/landing-page.css
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,15 @@ div.logo-holder > img {

#news-container .col-md-4 {
flex: 1;
}
}


@media (max-width: 768px) {
#news-container {
flex-wrap: wrap;
}
#news-container .col-md-4 {
flex: 1 1 100%;
}
}
}
130 changes: 130 additions & 0 deletions js/forum-fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
console.log("forum-fetch.js loaded!");

document.addEventListener("DOMContentLoaded", async function () {
console.log("FAQ loader running...");

const list = document.getElementById("list");
const empty = document.getElementById("empty");
const searchInput = document.getElementById("q");
const sortSelect = document.getElementById("sort");

const loadingText = document.createElement("p");
loadingText.textContent = "Loading FAQs...";
list.parentElement.insertBefore(loadingText, list);

try {
const res = await fetch("/assets/data/faq.json");
if (!res.ok) throw new Error(`HTTP ${res.status}`);

const data = await res.json();
const topics = data.topics || [];
loadingText.remove();

if (!topics.length) {
empty.style.display = "block";
return;
}

let visibleCount = 10;
let filteredTopics = [...topics];

function filterAndSort() {
const q = searchInput.value.trim().toLowerCase();
const sortKey = sortSelect.value;

// Filter
filteredTopics = topics.filter((t) =>
(t.title + " " + (t.excerpt || "")).toLowerCase().includes(q)
);

// Sort
filteredTopics.sort((a, b) => {
if (sortKey === "created_at" || sortKey === "last_posted_at") {
return new Date(b[sortKey]) - new Date(a[sortKey]);
}
return (b[sortKey] || 0) - (a[sortKey] || 0);
});

visibleCount = 10;
renderTopics();
}

function renderTopics() {
list.innerHTML = "";

const shown = filteredTopics.slice(0, visibleCount);

if (!shown.length) {
empty.style.display = "block";
return;
} else {
empty.style.display = "none";
}

shown.forEach((t) => {
const card = document.createElement("div");
card.className = "faq-card";
card.style.cssText =
"border:1px solid #ddd;padding:12px;border-radius:8px;background:#fff;";

const excerpt =
t.excerpt && t.excerpt.trim().length > 0
? t.excerpt
: "No description available.";

card.innerHTML = `
<h4 style="margin-bottom:8px;">
<strong>${t.title}</strong>
</h4>
<p style="color:#333;line-height:1.4;">
${excerpt}
<a href="${t.url}" target="_blank" rel="noopener noreferrer"
style="text-decoration:none;color:#0069c2;" data-noicon>
Read more
</a>
</p>
<p style="color:#666;font-size:0.9em;">
Last updated: ${new Date(t.last_posted_at).toLocaleDateString()} |
Replies: ${t.posts_count} | Views: ${t.views}
</p>
`;
list.appendChild(card);
});

if (visibleCount < filteredTopics.length) {
const btn = document.createElement("button");
btn.textContent = "Load more";
btn.style.cssText =
"padding:8px 16px;margin:12px 0 12px auto;display:block;border:1px solid #ccc;border-radius:8px;background:#f9f9f9;cursor:pointer;";
btn.addEventListener("click", () => {
visibleCount += 10;
renderTopics();
});
list.appendChild(btn);
}

// 🧽 JS-based CSS injection to remove external icon pseudo-element
if (!document.getElementById("noicon-style")) {
const style = document.createElement("style");
style.id = "noicon-style";
style.textContent = `
[data-noicon]::after {
content: none !important;
background-image: none !important;
}
`;
document.head.appendChild(style);
}
}

// Event listeners
searchInput.addEventListener("input", filterAndSort);
sortSelect.addEventListener("change", filterAndSort);

// Initial render
filterAndSort();
} catch (err) {
console.error("Error loading FAQ:", err);
loadingText.textContent = "Failed to load FAQs.";
}
});
87 changes: 87 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"name": "precice.github.io",
"version": "1.0.0",
"description": "The website is using [Jekyll](https://jekyllrb.com/) static website generator and [Github pages](https://pages.github.com/).\r To run and develop it locally you would need [Ruby](https://www.ruby-lang.org/en/) and [Bundler](https://bundler.io/).\r With Ruby, you can install bundler using `gem install bundler`.\r Then install [`pre-commit`](https://repology.org/project/python:pre-commit/versions) to keep your commits clean.",
"main": "index.js",
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.0",
"bytes": "^3.1.2",
"call-bind-apply-helpers": "^1.0.2",
"call-bound": "^1.0.4",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.2",
"cookie-signature": "^1.2.2",
"cors": "^2.8.5",
"debug": "^4.4.3",
"depd": "^2.0.0",
"dunder-proto": "^1.0.1",
"ee-first": "^1.1.1",
"encodeurl": "^2.0.0",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"express": "^5.1.0",
"finalhandler": "^2.1.0",
"forwarded": "^0.2.0",
"fresh": "^2.0.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.3.0",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"http-errors": "^2.0.0",
"iconv-lite": "^0.6.3",
"inherits": "^2.0.4",
"ipaddr.js": "^1.9.1",
"is-promise": "^4.0.0",
"math-intrinsics": "^1.1.0",
"media-typer": "^1.1.0",
"merge-descriptors": "^2.0.0",
"mime-db": "^1.54.0",
"mime-types": "^3.0.1",
"ms": "^2.1.3",
"negotiator": "^1.0.0",
"node-fetch": "^2.7.0",
"object-assign": "^4.1.1",
"object-inspect": "^1.13.4",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.3.0",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"raw-body": "^3.0.1",
"router": "^2.2.0",
"safe-buffer": "^5.2.1",
"safer-buffer": "^2.1.2",
"send": "^1.2.0",
"serve-static": "^2.2.0",
"setprototypeof": "^1.2.0",
"side-channel": "^1.1.0",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2",
"statuses": "^2.0.2",
"toidentifier": "^1.0.1",
"tr46": "^0.0.3",
"type-is": "^2.0.1",
"unpipe": "^1.0.0",
"vary": "^1.1.2",
"webidl-conversions": "^3.0.1",
"whatwg-url": "^5.0.0",
"wrappy": "^1.0.2"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Loading