Merge pull request 'Aus Datenschutzgründen alles via kirche.social laden' (#5) from alles-via-kirche-social into pages

Reviewed-on: https://codeberg.org/kirche-im-netz/Startodon-Hub/pulls/5
This commit is contained in:
Alexander Müller 2025-01-14 19:24:26 +00:00
commit e58c09b990
17 changed files with 234 additions and 413 deletions

View file

@ -3,15 +3,8 @@ import { checkConsent, showConsentPopup, setUserConsent } from '../components/co
export async function loadPostwall() { export async function loadPostwall() {
const container = document.getElementById('postswall-container'); const container = document.getElementById('postswall-container');
// Überprüfe, ob Consent erteilt wurde
if (!checkConsent()) {
// Consent nicht erteilt alternative Kachel anzeigen
renderConsentRequest();
return; // Beende die Funktion, kein weiterer Datenabruf
}
// Mastodon API-URL für Hashtag-Suche // Mastodon API-URL für Hashtag-Suche
const apiUrl = 'https://libori.social/api/v1/timelines/tag/fedikirche?limit=20'; const apiUrl = 'https://kirche.social/api/v1/timelines/tag/fedikirche?limit=20';
// Posts laden // Posts laden
async function fetchPosts() { async function fetchPosts() {
@ -106,54 +99,6 @@ export async function loadPostwall() {
fetchPosts(); fetchPosts();
} }
// Alternative Kachel anzeigen, wenn kein Consent erteilt wurde
function renderConsentRequest() {
const container = document.getElementById('postswall-container');
container.innerHTML = ''; // Vorherige Inhalte leeren
const consentCard = document.createElement('div');
consentCard.classList.add('post'); // Verwendet die Post-Klasse für Konsistenz
consentCard.innerHTML = `
<div class="post-header">
<!-- Skeleton-Loader für Avatar -->
<div class="skeleton avatar-skeleton"></div>
<!-- Skeleton-Loader für Autor und Username -->
<div class="post-author">
<div class="skeleton skeleton-text skeleton-text-name"></div>
<div class="skeleton skeleton-text skeleton-text-username"></div>
</div>
</div>
<div class="post-content">
<p>Du musst zuerst zustimmen, um Inhalte anzuzeigen.</p>
<div class="consent-buttons">
<button id="open-consent-popup" class="btn">Datenschutzeinstellungen öffnen</button>
<a href="https://libori.social/tags/fedikirche" target="_blank" rel="noopener noreferrer">
<button class="btn">Beiträge auf Mastodon ansehen</button>
</a>
</div>
</div>
`;
container.appendChild(consentCard);
// Event-Listener für Button zum erneuten Anzeigen des Consent-Popups
document.getElementById('open-consent-popup').addEventListener('click', () => {
showConsentPopup(
() => {
setUserConsent(true); // Zustimmung speichern
loadPostwall(); // Nachträglich Posts laden
},
() => {
setUserConsent(false); // Ablehnung speichern
console.log('Consent abgelehnt');
}
);
});
}
// Zeitberechnung für Posts // Zeitberechnung für Posts
function getTimeAgo(date) { function getTimeAgo(date) {
const now = new Date(); const now = new Date();
@ -177,7 +122,7 @@ function getTimeAgo(date) {
function addReadMoreButton() { function addReadMoreButton() {
const container = document.getElementById('postswall-container'); const container = document.getElementById('postswall-container');
const readMoreButton = document.createElement('a'); const readMoreButton = document.createElement('a');
readMoreButton.href = 'https://libori.social/tags/fedikirche'; readMoreButton.href = 'https://kirche.social/tags/fedikirche';
readMoreButton.target = '_blank'; readMoreButton.target = '_blank';
readMoreButton.rel = 'noopener noreferrer'; readMoreButton.rel = 'noopener noreferrer';
readMoreButton.classList.add('read-more-button'); readMoreButton.classList.add('read-more-button');

View file

@ -2,24 +2,10 @@ import { createStarterKitElement, enhanceStarterKits } from './utils/starterkit-
import { seededShuffleChildren } from './utils/shuffle-utils.js'; import { seededShuffleChildren } from './utils/shuffle-utils.js';
import { initializeCreateStarterKitPopup } from './utils/create-starterkit.js'; import { initializeCreateStarterKitPopup } from './utils/create-starterkit.js';
import { loadPostwall } from './components/postwall.js'; import { loadPostwall } from './components/postwall.js';
import { checkConsent, setUserConsent, showConsentPopup } from './components/consentManager.js';
document.addEventListener('DOMContentLoaded', async function () { document.addEventListener('DOMContentLoaded', async function () {
// Starte sofort den Seitenaufbau // Starte sofort den Seitenaufbau
initializeSite(); initializeSite();
// Überprüfe parallel den Consent-Status
const consent = checkConsent();
if (!consent) {
showConsentPopup(
() => {
setUserConsent(true);
},
() => {
setUserConsent(false);
}
);
}
}); });
async function initializeSite() { async function initializeSite() {

View file

@ -10,7 +10,7 @@ export function getServerClass(instance) {
export function extractHostname(url) { export function extractHostname(url) {
try { try {
const hostname = url.match(/^https?:\/\/([^\/]+)/i)[1]; // Regex: extrahiert den Hostnamen const hostname = url.split('@')[1];
return hostname; return hostname;
} catch (error) { } catch (error) {
console.error('Fehler beim Extrahieren des Hostnamens:', error, 'URL:', url); console.error('Fehler beim Extrahieren des Hostnamens:', error, 'URL:', url);

View file

@ -1,37 +1,16 @@
import { getServerClass } from './instances.js'; import { getServerClass } from './instances.js';
export async function fetchProfile(profileUrl, options = {}) { export async function fetchProfile(handle, options = {}) {
const { updateElement = null, createCard = false } = options; const { returnData = null, createCard = false } = options;
try { try {
const url = new URL(profileUrl); const data = await fetchProfileViaMastodon(handle);
// Schritt 1: Plattform-Erkennung if (returnData) {
const platform = await detectPlatform(url);
// Schritt 2: Profil-Daten abrufen
let data;
if (platform === 'mastodon') {
data = await fetchMastodonProfile(url);
} else if (platform === 'wordpress') {
data = await fetchWordpressProfile(url);
} else {
throw new Error('Unbekannte Plattform');
}
// Schritt 3: Ausgabe vorbereiten
if (updateElement) {
updateElement.textContent = data.display_name || data.name || data.username;
const avatarImage = document.createElement('img');
avatarImage.classList.add('account-avatar');
avatarImage.alt = data.display_name || data.name || 'Profilbild nicht verfügbar';
avatarImage.src = data.avatar || data.icon?.url || '';
updateElement.prepend(avatarImage);
return data; return data;
} else if (createCard) { } else if (createCard) {
const card = createAccountCard(data, profileUrl, url.hostname); const url = new URL(data.url);
const card = createAccountCard(data, data.url, url.hostname);
return { card, data }; return { card, data };
} }
} catch (error) { } catch (error) {
@ -40,81 +19,14 @@ export async function fetchProfile(profileUrl, options = {}) {
} }
} }
async function detectPlatform(url) { async function fetchProfileViaMastodon(handle) {
// Test auf Mastodon-API const lookupUrl = `https://kirche.social/api/v1/accounts/lookup?acct=${handle}`;
try {
const mastodonTest = await fetch(`${url.origin}/api/v1/instance`);
if (mastodonTest.ok) return 'mastodon';
} catch (error) {
console.warn('Fehler beim Mastodon-Test:', error);
}
// Test auf WordPress-ActivityPub
try {
const wpTest = await fetch(`${url.origin}/wp-json/activitypub/1.0/actors/1`, {
headers: { Accept: 'application/activity+json' }
});
if (wpTest.ok) return 'wordpress';
} catch (error) {
console.warn('Fehler beim WordPress-Test:', error);
}
// Fallback, wenn kein Test erfolgreich war
return 'unknown';
}
async function fetchMastodonProfile(url) {
const handle = url.pathname.split('/')[1].substring(1);
const lookupUrl = `https://${url.hostname}/api/v1/accounts/lookup?acct=${handle}`;
const response = await fetch(lookupUrl); const response = await fetch(lookupUrl);
if (!response.ok) throw new Error('Mastodon-Profil nicht gefunden'); if (!response.ok) throw new Error(`Mastodon-Profil ${handle} nicht gefunden`);
return await response.json(); return await response.json();
} }
async function fetchWordpressProfile(url) {
const actorId = url.pathname.split('/').pop(); // ID aus der URL extrahieren
const lookupUrl = `${url.origin}/${actorId}`;
const response = await fetch(lookupUrl, {
headers: { Accept: 'application/activity+json' }
});
if (!response.ok) throw new Error('WordPress-Profil nicht gefunden');
const data = await response.json();
// Letzten Post aus der Outbox holen
const lastPostDate = await fetchWordpressLastPost(data.outbox);
// Kompatibilität herstellen
return {
username: data.preferredUsername,
display_name: data.name,
avatar: data.icon?.url,
note: data.summary,
followers_count: data.followers ? data.followers.length : 0,
last_status_at: lastPostDate || data.published,
};
}
async function fetchWordpressLastPost(outboxUrl) {
try {
const response = await fetch(`${outboxUrl}?page=1`, {
headers: { Accept: 'application/activity+json' }
});
if (!response.ok) throw new Error('Outbox konnte nicht geladen werden');
const data = await response.json();
if (data.orderedItems && data.orderedItems.length > 0) {
const latestPost = data.orderedItems[0];
return latestPost.published || latestPost.object.published;
}
} catch (error) {
console.warn('Fehler beim Abrufen des letzten Beitrags:', error);
}
return null;
}
export function createAccountCard(data, href, instance) { export function createAccountCard(data, href, instance) {
const serverClass = getServerClass(instance); const serverClass = getServerClass(instance);
const link = document.createElement('a'); const link = document.createElement('a');

View file

@ -1,6 +1,5 @@
import { fetchProfile } from './profile-utils.js'; import { fetchProfile } from './profile-utils.js';
import { extractHostname, getServerClass } from './instances.js'; import { extractHostname, getServerClass } from './instances.js';
import { checkConsent } from '../components/consentManager.js';
export function createRecommendationPopup(accounts, title, authors, description) { export function createRecommendationPopup(accounts, title, authors, description) {
const template = document.getElementById('popup-template').content.cloneNode(true); const template = document.getElementById('popup-template').content.cloneNode(true);
@ -115,34 +114,27 @@ export function populateAuthorsContainer(authorsContainer, authors) {
const additionalAuthorsCount = authors.length - authorsToShow.length; const additionalAuthorsCount = authors.length - authorsToShow.length;
authorsToShow.forEach(author => { authorsToShow.forEach(author => {
const authorLink = document.createElement('a'); const authorLink = document.createElement('a');
authorLink.href = author;
authorLink.classList.add('account'); authorLink.classList.add('account');
authorLink.target = '_blank'; // Link öffnet neues Fenster authorLink.target = '_blank'; // Link öffnet neues Fenster
// Consent prüfen fetchProfile(author, { returnData: true }).then((data) => {
if (checkConsent()) { authorLink.href = data.url;
// Consent erteilt - Profilbild laden
fetchProfile(author, { updateElement: authorLink }).then(() => {
const avatarImage = authorLink.querySelector('.account-avatar');
if (avatarImage) {
authorLink.textContent = '';
authorLink.appendChild(avatarImage);
// Server-Klasse für Avatar hinzufügen const avatarImage = document.createElement('img');
const hostname = extractHostname(author); avatarImage.classList.add('account-avatar');
const serverClass = getServerClass(hostname); avatarImage.alt = data.display_name || data.name || 'Profilbild nicht verfügbar';
if (serverClass) { avatarImage.src = data.avatar || '';
avatarImage.classList.add(serverClass);
} authorLink.appendChild(avatarImage);
}
}); // Server-Klasse für Avatar hinzufügen
} else { const hostname = extractHostname(author);
// Kein Consent Skeleton-Loader anzeigen const serverClass = getServerClass(hostname);
const skeletonAvatar = document.createElement('div'); if (serverClass) {
skeletonAvatar.classList.add('skeleton', 'avatar-skeleton', 'account-avatar'); avatarImage.classList.add(serverClass);
authorLink.appendChild(skeletonAvatar); }
} });
authorsContainer.appendChild(authorLink); authorsContainer.appendChild(authorLink);
}); });

View file

@ -1,5 +1,4 @@
import { createRecommendationPopup, populateAuthorsContainer } from './recommendations-utils.js'; import { createRecommendationPopup, populateAuthorsContainer } from './recommendations-utils.js';
import { checkConsent, showConsentPopup, setUserConsent } from '../components/consentManager.js';
// StarterKit-Element erstellen // StarterKit-Element erstellen
export function createStarterKitElement(kit) { export function createStarterKitElement(kit) {
@ -23,6 +22,7 @@ export function createStarterKitElement(kit) {
populateAuthorsContainer(authorsContainer, kit.authors); populateAuthorsContainer(authorsContainer, kit.authors);
kitElement.dataset.accounts = JSON.stringify(kit.accounts); kitElement.dataset.accounts = JSON.stringify(kit.accounts);
kitElement.dataset.authors = JSON.stringify(kit.authors);
return kitElement; return kitElement;
} }
@ -40,21 +40,7 @@ export function enhanceStarterKits() {
// StarterKit-Klick behandeln // StarterKit-Klick behandeln
function handleStarterKitClick(kit) { function handleStarterKitClick(kit) {
if (checkConsent()) { loadStarterKitProfiles(kit);
// Zustimmung vorhanden StarterKit-Popup öffnen
loadStarterKitProfiles(kit);
} else {
// Keine Zustimmung Consent-Popup anzeigen
showConsentPopup(
() => {
setUserConsent(true); // Zustimmung speichern
loadStarterKitProfiles(kit); // Nachträglich StarterKit-Popup öffnen
},
() => {
console.log('Consent wurde abgelehnt. StarterKit-Popup wird nicht geöffnet.');
}
);
}
} }
// StarterKit-Profile laden // StarterKit-Profile laden
@ -62,7 +48,7 @@ function loadStarterKitProfiles(kit) {
const title = kit.querySelector('h3').textContent; const title = kit.querySelector('h3').textContent;
const description = kit.querySelector('p').textContent; const description = kit.querySelector('p').textContent;
const accounts = JSON.parse(kit.dataset.accounts || '[]'); const accounts = JSON.parse(kit.dataset.accounts || '[]');
const authors = Array.from(kit.querySelectorAll('.authors-container .account')).map(author => author.href); const authors = JSON.parse(kit.dataset.authors || '[]');
const popup = createRecommendationPopup(accounts, title, authors, description); const popup = createRecommendationPopup(accounts, title, authors, description);
document.body.appendChild(popup); document.body.appendChild(popup);

View file

@ -2,19 +2,19 @@
"name": "100 Morgen Wald", "name": "100 Morgen Wald",
"description": "Bildung, viel Bildung.\n", "description": "Bildung, viel Bildung.\n",
"authors": [ "authors": [
"https://kirche.social/@frau_sanders" "frau_sanders@kirche.social"
], ],
"accounts": [ "accounts": [
"https://social.tchncs.de/@kuketzblog", "kuketzblog@social.tchncs.de",
"https://mastodon.social/@bahnkundenv", "bahnkundenv@mastodon.social",
"https://sueden.social/@BlumeEvolution", "BlumeEvolution@sueden.social",
"https://artikel91.eu/@fxneumann", "fxneumann@artikel91.eu",
"https://social.bund.de/@DLR", "DLR@social.bund.de",
"https://mastodon.social/@sundogplanets", "sundogplanets@mastodon.social",
"https://linuxhotel.social/@linuxhotel", "linuxhotel@linuxhotel.social",
"https://mastodon.art/@Fuchskind", "Fuchskind@mastodon.art",
"https://chaos.social/@leah", "leah@chaos.social",
"https://hostsharing.coop/@Pflege42", "Pflege42@hostsharing.coop",
"https://chaos.social/@irgendwiejuna" "irgendwiejuna@chaos.social"
] ]
} }

View file

@ -2,13 +2,13 @@
"name": "tägliche Impulse", "name": "tägliche Impulse",
"description": "Tägliche spirituelle Impulse Inspiration und Besinnung für deinen Alltag.", "description": "Tägliche spirituelle Impulse Inspiration und Besinnung für deinen Alltag.",
"authors": [ "authors": [
"https://kirche.social/@frau_sanders" "frau_sanders@kirche.social"
], ],
"accounts": [ "accounts": [
"https://kirche.social/@morgengebet", "morgengebet@kirche.social",
"https://kirche.social/@vaterunser", "vaterunser@kirche.social",
"https://kirche.social/@tagesimpuls", "tagesimpuls@kirche.social",
"https://social.vivaldi.net/@losungen", "losungen@vivaldi.net",
"https://kirche.social/@bibelvers" "bibelvers@kirche.social"
] ]
} }

View file

@ -2,20 +2,20 @@
"name": "Erzbistum Paderborn", "name": "Erzbistum Paderborn",
"description": "Menschen, Institutionen und Initiativen aus dem Erzbistum Paderborn.", "description": "Menschen, Institutionen und Initiativen aus dem Erzbistum Paderborn.",
"authors": [ "authors": [
"https://libori.social/@alex" "alex@libori.social"
], ],
"accounts": [ "accounts": [
"https://libori.social/@news_erzbistum_paderborn", "news_erzbistum_paderborn@libori.social",
"https://libori.social/@wir_erzbistum_paderborn", "wir_erzbistum_paderborn@libori.social",
"https://libori.social/@gotteswerker", "gotteswerker@libori.social",
"https://libori.social/@youpax_redaktion", "youpax_redaktion@libori.social",
"https://libori.social/@attendorn_katholisch", "attendorn_katholisch@libori.social",
"https://libori.social/@koenigsmuenster", "koenigsmuenster@libori.social",
"https://libori.social/@Franz_Stock_org", "Franz_Stock_org@libori.social",
"https://libori.social/@gemeindepflanzen", "gemeindepflanzen@libori.social",
"https://libori.social/@alex", "alex@libori.social",
"https://libori.social/@jonathan", "jonathan@libori.social",
"https://nrw.social/@pmaurus", "pmaurus@nrw.social",
"https://libori.social/@KatholischeKircheAmPhoenixsee" "KatholischeKircheAmPhoenixsee@libori.social"
] ]
} }

View file

@ -2,20 +2,20 @@
"name": "#FediKirche", "name": "#FediKirche",
"description": "Accounts rund um #FediKirche engagiert für die Stärkung der kirchlichen Community im Fediverse.", "description": "Accounts rund um #FediKirche engagiert für die Stärkung der kirchlichen Community im Fediverse.",
"authors": [ "authors": [
"https://libori.social/@alex" "alex@libori.social"
], ],
"accounts": [ "accounts": [
"https://reliverse.social/@comenius", "comenius@reliverse.social",
"https://katholisch.social/@kdsz_bayern", "kdsz_bayern@katholisch.social",
"https://kirche.social/@luki", "luki@kirche.social",
"https://kirche.social/@librechurch", "librechurch@kirche.social",
"https://libori.social/@alex", "alex@libori.social",
"https://reliverse.social/@joerglohrer", "joerglohrer@reliverse.social",
"https://kirche.social/@csett86", "csett86@kirche.social",
"https://kirche.social/@Netzwerk_dig_Bildung", "Netzwerk_dig_Bildung@kirche.social",
"https://muenchen.social/@ttarses", "ttarses@muenchen.social",
"https://bildung.social/@ebinger", "ebinger@bildung.social",
"https://kirche.social/@morgengebet", "morgengebet@kirche.social",
"https://kirche.social/@onlinekirche" "onlinekirche@kirche.social"
] ]
} }

View file

@ -2,14 +2,14 @@
"name": "Inklusion", "name": "Inklusion",
"description": "Dickes Brett. Hier bohren schon einige.\nEs geht um Gerechtigkeit, Freiheit und Bildung. Es geht um Inklusion. Für alle.", "description": "Dickes Brett. Hier bohren schon einige.\nEs geht um Gerechtigkeit, Freiheit und Bildung. Es geht um Inklusion. Für alle.",
"authors": [ "authors": [
"https://kirche.social/@frau_sanders" "frau_sanders@kirche.social"
], ],
"accounts": [ "accounts": [
"https://mastodon.cloud/@RaulKrauthausen", "RaulKrauthausen@mastodon.cloud",
"https://troet.cafe/@EinAugenschmaus", "EinAugenschmaus@troet.cafe",
"https://troet.cafe/@Frau_Mensch", "Frau_Mensch@troet.cafe",
"https://kirche.social/@SandiPavkovic", "SandiPavkovic@kirche.social",
"https://kirche.social/@inklusion_ruhrbistum", "inklusion_ruhrbistum@kirche.social",
"https://bildung.social/@komin" "komin@bildung.social"
] ]
} }

View file

@ -2,62 +2,62 @@
"name": "katholisch", "name": "katholisch",
"description": "Eine vielseitige Auswahl aus dem katholischen Umfeld von engagierten Gläubigen und theologischen Stimmen bis hin zu verschiedenen Bistümern, Institutionen und Einrichtungen.", "description": "Eine vielseitige Auswahl aus dem katholischen Umfeld von engagierten Gläubigen und theologischen Stimmen bis hin zu verschiedenen Bistümern, Institutionen und Einrichtungen.",
"authors": [ "authors": [
"https://libori.social/@alex" "alex@libori.social"
], ],
"accounts": [ "accounts": [
"https://libori.social/@news_erzbistum_paderborn", "news_erzbistum_paderborn@libori.social",
"https://libori.social/@wir_erzbistum_paderborn", "wir_erzbistum_paderborn@libori.social",
"https://libori.social/@news_katholisch", "news_katholisch@libori.social",
"https://libori.social/@gotteswerker", "gotteswerker@libori.social",
"https://libori.social/@attendorn_katholisch", "attendorn_katholisch@libori.social",
"https://libori.social/@KatholischeKircheAmPhoenixsee", "KatholischeKircheAmPhoenixsee@libori.social",
"https://libori.social/@koenigsmuenster", "koenigsmuenster@libori.social",
"https://kirche.social/@bistumwuerzburg", "bistumwuerzburg@kirche.social",
"https://katholisch.social/@bistumpassau", "bistumpassau@katholisch.social",
"https://kirche.social/@medienkompetenzzentrum", "medienkompetenzzentrum@kirche.social",
"https://libori.social/@Franz_Stock_org", "Franz_Stock_org@libori.social",
"https://kirche.social/@weltkirche_de", "weltkirche_de@kirche.social",
"https://katholisch.social/@kdsz_bayern", "kdsz_bayern@katholisch.social",
"https://katholisch.social/@pvpv", "pvpv@katholisch.social",
"https://libori.social/@gemeindepflanzen", "gemeindepflanzen@libori.social",
"https://kirche.social/@himmelwaerts_und_erdverbunden", "himmelwaerts_und_erdverbunden@kirche.social",
"https://kirche.social/@ebhh_hochschule", "ebhh_hochschule@kirche.social",
"https://libori.social/@alex", "alex@libori.social",
"https://libori.social/@jonathan", "jonathan@libori.social",
"https://kirche.social/@missio", "missio@kirche.social",
"https://kirche.social/@inklusion_ruhrbistum", "inklusion_ruhrbistum@kirche.social",
"https://kirche.social/@Frau_Sanders", "Frau_Sanders@kirche.social",
"https://bonn.social/@fxneumann", "fxneumann@bonn.social",
"https://nrw.social/@pmaurus", "pmaurus@nrw.social",
"https://wien.rocks/@PfarreWaehring", "PfarreWaehring@wien.rocks",
"https://openbiblio.social/@BPS_TR", "BPS_TR@openbiblio.social",
"https://libori.social/@nordwalde", "nordwalde@libori.social",
"https://colearn.social/@Religionsunterricht", "Religionsunterricht@colearn.social",
"https://kirche.social/@k_le", "k_le@kirche.social",
"https://kirche.social/@liebfrauen", "liebfrauen@kirche.social",
"https://kirche.social/@marienschule", "marienschule@kirche.social",
"https://kirche.social/@stellief", "stellief@kirche.social",
"https://kirche.social/@proficisci", "proficisci@kirche.social",
"https://swiss.social/@eva_maria_faber", "eva_maria_faber@swiss.social",
"https://social.regenpfeifer.net/@linkskatholisch", "linkskatholisch@social.regenpfeifer.net",
"https://mastodon.social/@dieterzitzler", "dieterzitzler@mastodon.social",
"https://openbiblio.social/@DombibliothekKoeln", "DombibliothekKoeln@openbiblio.social",
"https://sueden.social/@statiopontis", "statiopontis@sueden.social",
"https://archaeo.social/@hoelschmichel", "hoelschmichel@archaeo.social",
"https://dju.social/@Theowiss", "Theowiss@dju.social",
"https://reliverse.social/@DigitalRUnde", "DigitalRUnde@reliverse.social",
"https://kirche.social/@florian", "florian@kirche.social",
"https://kirche.social/@bf", "bf@kirche.social",
"https://kirche.social/@infoleck", "infoleck@kirche.social",
"https://kirche.social/@clearingstellemedienkompetenz", "clearingstellemedienkompetenz@kirche.social",
"https://kirche.social/@andreasbuesch", "andreasbuesch@kirche.social",
"https://social.cologne/@BroWoelfie", "BroWoelfie@social.cologne",
"https://mastodon.social/@Kapuziner", "Kapuziner@mastodon.social",
"https://bildung.social/@menneboy", "menneboy@bildung.social",
"https://kirche.social/@OratoriumL", "OratoriumL@kirche.social",
"https://mastodon.social/@Pallottiner", "Pallottiner@mastodon.social",
"https://kirche.social/@ludgerus_norderney", "ludgerus_norderney@kirche.social",
"https://kirche.social/@bdkj", "bdkj@kirche.social",
"https://muenchen.social/@rainerhepler" "rainerhepler@muenchen.social"
] ]
} }

View file

@ -2,11 +2,11 @@
"name": "Nachrichten, Meinungen & Analysen", "name": "Nachrichten, Meinungen & Analysen",
"description": "Redaktionen mit eigenen Inhalten von Nachrichten und Analysen bis hin zu Meinungsbeiträgen und Hintergrundberichten. Ideal für alle, die fundierte Informationen und journalistische Perspektiven aus erster Hand schätzen.", "description": "Redaktionen mit eigenen Inhalten von Nachrichten und Analysen bis hin zu Meinungsbeiträgen und Hintergrundberichten. Ideal für alle, die fundierte Informationen und journalistische Perspektiven aus erster Hand schätzen.",
"authors": [ "authors": [
"https://libori.social/@alex" "alex@libori.social"
], ],
"accounts": [ "accounts": [
"https://mastodon.social/@eulemagazin", "eulemagazin@mastodon.social",
"https://libori.social/@news_katholisch", "news_katholisch@libori.social",
"https://bonn.social/@fxneumann" "fxneumann@bonn.social"
] ]
} }

View file

@ -2,34 +2,34 @@
"name": "religionsbezogene Bildung", "name": "religionsbezogene Bildung",
"description": "Eine bunte Auswahl an Profilen zur religionsbezogenen Bildung von pädagogischen Konzepten und theologischen Impulsen bis zu Projekten, die Dialog und Lernen über Religion fördern.", "description": "Eine bunte Auswahl an Profilen zur religionsbezogenen Bildung von pädagogischen Konzepten und theologischen Impulsen bis zu Projekten, die Dialog und Lernen über Religion fördern.",
"authors": [ "authors": [
"https://reliverse.social/@joerglohrer" "joerglohrer@reliverse.social"
], ],
"accounts": [ "accounts": [
"https://reliverse.social/@heller", "heller@reliverse.social",
"https://bildung.social/@FrauEmmEn", "FrauEmmEn@bildung.social",
"https://reliverse.social/@relilab", "relilab@reliverse.social",
"https://reliverse.social/@johappel", "johappel@reliverse.social",
"https://reliverse.social/@rpi", "rpi@reliverse.social",
"https://libori.social/@alex", "alex@libori.social",
"https://reliverse.social/@jens_dechow", "jens_dechow@reliverse.social",
"https://reliverse.social/@DigitalRUnde", "DigitalRUnde@reliverse.social",
"https://kirche.social/@jutta_wa", "jutta_wa@kirche.social",
"https://reliverse.social/@comenius", "comenius@reliverse.social",
"https://reliverse.social/@joerglohrer", "joerglohrer@reliverse.social",
"https://reliverse.social/@bianca_goes_europe", "bianca_goes_europe@reliverse.social",
"https://reliverse.social/@Colibri260", "Colibri260@reliverse.social",
"https://reliverse.social/@NadineGlage", "NadineGlage@reliverse.social",
"https://sueden.social/@BlumeEvolution", "BlumeEvolution@sueden.social",
"https://reliverse.social/@farbenspiel_family", "farbenspiel_family@reliverse.social",
"https://kirche.social/@Frau_Sanders", "Frau_Sanders@kirche.social",
"https://kirche.social/@manfred", "manfred@kirche.social",
"https://kirche.social/@arenzdom", "arenzdom@kirche.social",
"https://bildung.social/@minetestbildung", "minetestbildung@bildung.social",
"https://bildung.social/@ebinger", "ebinger@bildung.social",
"https://colearn.social/@Religionsunterricht", "Religionsunterricht@colearn.social",
"https://bildung.social/@herrlarbig", "herrlarbig@bildung.social",
"https://bildung.social/@ViP", "ViP@bildung.social",
"https://reliverse.social/@Fl_OhMyGod", "Fl_OhMyGod@reliverse.social",
"https://reliverse.social/@digitale_relitanten" "digitale_relitanten@reliverse.social"
] ]
} }

View file

@ -2,16 +2,16 @@
"name": "Vereine und Initiativen", "name": "Vereine und Initiativen",
"description": "Kirchliche Vereine und Initiativen von Bibelprojekten und Gemeindegründungen bis hin zu ökumenischen Projekten und Linux in der Kirche. Entdecke Vielfalt und Engagement!", "description": "Kirchliche Vereine und Initiativen von Bibelprojekten und Gemeindegründungen bis hin zu ökumenischen Projekten und Linux in der Kirche. Entdecke Vielfalt und Engagement!",
"authors": [ "authors": [
"https://libori.social/@alex" "alex@libori.social"
], ],
"accounts": [ "accounts": [
"https://kirche.social/@offenebibel", "offenebibel@kirche.social",
"https://kirche.social/@luki", "luki@kirche.social",
"https://kirche.social/@librechurch", "librechurch@kirche.social",
"https://libori.social/@gemeindepflanzen", "gemeindepflanzen@libori.social",
"https://kirche.social/@Netzwerk_dig_Bildung", "Netzwerk_dig_Bildung@kirche.social",
"https://kirche.social/@christians4future", "christians4future@kirche.social",
"https://libori.social/@Franz_Stock_org", "Franz_Stock_org@libori.social",
"https://kirche.social/@oesg" "oesg@kirche.social"
] ]
} }

View file

@ -2,28 +2,28 @@
"name": "Evangelische Kirchengemeinden, Dekanate und Kirchspiele", "name": "Evangelische Kirchengemeinden, Dekanate und Kirchspiele",
"description": "Eine Liste von evangelischen Kirchengemeinden, Dekanaten und Kirchspielen.\nFehlt etwas? Wir sind für Info dankbar.", "description": "Eine Liste von evangelischen Kirchengemeinden, Dekanaten und Kirchspielen.\nFehlt etwas? Wir sind für Info dankbar.",
"authors": [ "authors": [
"https://kirche.social/@onlinekirche" "onlinekirche@kirche.social"
], ],
"accounts": [ "accounts": [
"https://kirche.social/@campusgemeinde", "campusgemeinde@kirche.social",
"https://kirche.social/@dekanatleutershausen", "dekanatleutershausen@kirche.social",
"https://kirche.social/@esg_leipzig", "esg_leipzig@kirche.social",
"https://kirche.social/@EvKgmSiegburg", "EvKgmSiegburg@kirche.social",
"https://kirche.social/@emmaus", "emmaus@kirche.social",
"https://kirche.social/@frankenberg", "frankenberg@kirche.social",
"https://kirche.social/@friedenskirche_madrid", "friedenskirche_madrid@kirche.social",
"https://kirche.social/@Hochdahl_Evangelisch", "Hochdahl_Evangelisch@kirche.social",
"https://kirche.social/@kirchspiel_probstzella", "kirchspiel_probstzella@kirche.social",
"https://kirche.social/@Laucha", "Laucha@kirche.social",
"https://kirche.social/@marc", "marc@kirche.social",
"https://kirche.social/@marienberghausen", "marienberghausen@kirche.social",
"https://kirche.social/@neunburg_evangelisch", "neunburg_evangelisch@kirche.social",
"https://kirche.social/@peterskirche", "peterskirche@kirche.social",
"https://kirche.social/@Prediger_EF", "Prediger_EF@kirche.social",
"https://kirche.social/@Refwohlenvillmergen", "Refwohlenvillmergen@kirche.social",
"https://kirche.social/@ruhrPott", "ruhrPott@kirche.social",
"https://kirche.social/@sw_evangelisch", "sw_evangelisch@kirche.social",
"https://kirche.social/@neulussheim", "neulussheim@kirche.social",
"https://rheinneckar.social/@ekilue" "ekilue@rheinneckar.social"
] ]
} }

View file

@ -2,42 +2,42 @@
"name": "Gemeinden und so", "name": "Gemeinden und so",
"description": "Kirche auf Feldebene, katholisch und evangelisch: Pfarr-/Kirchengemeinden, Kirchspiele, Pastoralverbünde, pastorale Räume etc.", "description": "Kirche auf Feldebene, katholisch und evangelisch: Pfarr-/Kirchengemeinden, Kirchspiele, Pastoralverbünde, pastorale Räume etc.",
"authors": [ "authors": [
"https://katholisch.social/@pvpv" "pvpv@katholisch.social"
], ],
"accounts": [ "accounts": [
"https://libori.social/@attendorn_katholisch", "attendorn_katholisch@libori.social",
"https://kirche.social/@bf", "bf@kirche.social",
"https://kirche.social/@liebfrauen", "liebfrauen@kirche.social",
"https://kirche.social/@bottwartal", "bottwartal@kirche.social",
"https://libori.social/@KatholischeKircheAmPhoenixsee", "KatholischeKircheAmPhoenixsee@libori.social",
"https://kirche.social/@Prediger_EF", "Prediger_EF@kirche.social",
"https://kirche.social/@marc", "marc@kirche.social",
"https://kirche.social/@k_le", "k_le@kirche.social",
"https://rheinneckar.social/@ekilue", "ekilue@rheinneckar.social",
"https://kirche.social/@neunburg_evangelisch", "neunburg_evangelisch@kirche.social",
"https://kirche.social/@ludgerus_norderney", "ludgerus_norderney@kirche.social",
"https://libori.social/@nordwalde", "nordwalde@libori.social",
"https://kirche.social/@obernkirchen", "obernkirchen@kirche.social",
"https://kirche.social/@kirchspiel_probstzella", "kirchspiel_probstzella@kirche.social",
"https://katholisch.social/@pvpv", "pvpv@katholisch.social",
"https://kirche.social/@fegrenningen", "fegrenningen@kirche.social",
"https://kirche.social/@st_martin_sb", "st_martin_sb@kirche.social",
"https://wien.rocks/@PfarreWaehring", "PfarreWaehring@wien.rocks",
"https://kirche.social/@BoniWiesbaden", "BoniWiesbaden@kirche.social",
"https://mastodon.social/@fegffb", "fegffb@mastodon.social",
"https://mastodon.social/@fegbruchmuehlen", "fegbruchmuehlen@mastodon.social",
"https://kirche.social/@campusgemeinde", "campusgemeinde@kirche.social",
"https://kirche.social/@esg_leipzig", "esg_leipzig@kirche.social",
"https://kirche.social/@EvKgmSiegburg", "EvKgmSiegburg@kirche.social",
"https://kirche.social/@emmaus", "emmaus@kirche.social",
"https://kirche.social/@frankenberg", "frankenberg@kirche.social",
"https://kirche.social/@friedenskirche_madrid", "friedenskirche_madrid@kirche.social",
"https://kirche.social/@Hochdahl_Evangelisch", "Hochdahl_Evangelisch@kirche.social",
"https://kirche.social/@Laucha", "Laucha@kirche.social",
"https://kirche.social/@marienberghausen", "marienberghausen@kirche.social",
"https://kirche.social/@peterskirche", "peterskirche@kirche.social",
"https://kirche.social/@Refwohlenvillmergen", "Refwohlenvillmergen@kirche.social",
"https://kirche.social/@KathKircheAffaltrach", "KathKircheAffaltrach@kirche.social",
"https://kirche.social/@neulussheim" "neulussheim@kirche.social"
] ]
} }