{"id":307997,"date":"2026-06-11T12:50:50","date_gmt":"2026-06-11T12:50:50","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/dienstplan\/"},"modified":"2026-06-25T09:15:22","modified_gmt":"2026-06-25T09:15:22","slug":"dienstplan","status":"publish","type":"plugin","link":"https:\/\/arg.wordpress.org\/plugins\/dienstplan\/","author":23480443,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.5.1","stable_tag":"3.5.1","tested":"7.0","requires":"6.3","requires_php":"8.1","requires_plugins":null,"header_name":"Dienstplan","header_author":"Nusselt Management GmbH, Alexander Nusselt","header_description":"The simple solution for digital shift scheduling.","assets_banners_color":"d6dadf","last_updated":"2026-06-25 09:15:22","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/www.wp-dienstplan.de","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":155,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"3.4.2":{"tag":"3.4.2","author":"wpdienstplan","date":"2026-06-11 12:50:38"},"3.5.0":{"tag":"3.5.0","author":"wpdienstplan","date":"2026-06-15 09:00:46"},"3.5.1":{"tag":"3.5.1","author":"wpdienstplan","date":"2026-06-25 09:15:22"}},"upgrade_notice":{"3.5.1":"<p>Documentation-only update: clearer, shorter wp.org plugin page text. Safe to skip if you are already on 3.5.0.<\/p>","3.5.0":"<p>New master-detail shift planner with a resizable plan sidebar, drag-and-drop sorting, shift colours in the month view and a clearer plan comparison. Recommended for all users. Update Premium to 1.5.0 at the same time if you use it.<\/p>","3.4.0":"<p>wp.org compliance release: free is a single fully functional schedule; multi-plan, weekday restrictions, event sign-ups\/recurrences and audit log require the Premium add-on. Update Premium to 1.4.0 if you use it.<\/p>","3.3.0":"<p>wp.org compliance release: the free tier is no longer capped by artificial limits; groups require the Premium add-on. Update Premium to 1.3.0 if you use it.<\/p>","3.2.0":"<p>Reviewer-compliant rename: all internal IDs now use the <code>dienstplan_<\/code> prefix. Database schemas stay; options keys move to the new prefix.<\/p>","3.1.0":"<p>First public WordPress.org release. If you previously ran the plugin from wp-dienstplan.de, your data, rosters and settings carry over with no migration step.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3569919,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3569919,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500-de.jpg":{"filename":"banner-1544x500-de.jpg","revision":3569955,"resolution":"1544x500","location":"assets","locale":"de","width":1544,"height":500},"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3568853,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250-de.jpg":{"filename":"banner-772x250-de.jpg","revision":3569955,"resolution":"772x250","location":"assets","locale":"de","width":772,"height":250},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3568853,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["3.4.2","3.5.0","3.5.1"],"block_files":[],"assets_screenshots":{"screenshot-1-de.png":{"filename":"screenshot-1-de.png","revision":3586003,"resolution":"1","location":"assets","locale":"de","width":1584,"height":1029},"screenshot-1.png":{"filename":"screenshot-1.png","revision":3586003,"resolution":"1","location":"assets","locale":"","width":1584,"height":1033},"screenshot-2-de.png":{"filename":"screenshot-2-de.png","revision":3586003,"resolution":"2","location":"assets","locale":"de","width":1584,"height":1318},"screenshot-2-es.png":{"filename":"screenshot-2-es.png","revision":3586003,"resolution":"2","location":"assets","locale":"es","width":1584,"height":1318},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3586003,"resolution":"2","location":"assets","locale":"","width":1584,"height":1318},"screenshot-3-de.png":{"filename":"screenshot-3-de.png","revision":3586003,"resolution":"3","location":"assets","locale":"de","width":1584,"height":1029},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3586003,"resolution":"3","location":"assets","locale":"","width":1584,"height":1318},"screenshot-4-de.png":{"filename":"screenshot-4-de.png","revision":3586003,"resolution":"4","location":"assets","locale":"de","width":1584,"height":1062},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3586003,"resolution":"4","location":"assets","locale":"","width":1584,"height":1318},"screenshot-5-de.png":{"filename":"screenshot-5-de.png","revision":3586003,"resolution":"5","location":"assets","locale":"de","width":1584,"height":1318},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3586003,"resolution":"5","location":"assets","locale":"","width":1584,"height":1318}},"screenshots":{"1":"The interactive calendar on a public page \u2014 members see upcoming shifts and sign up with one click.","2":"The admin shift planner \u2014 assign members to shifts, with an at-a-glance view of who is signed up where.","3":"The events list \u2014 plan training nights, fundraisers and on-call duties with categories (per-event signup lists with Basis).","4":"The \"My shifts\" dashboard widget \u2014 every member sees their own upcoming commitments at login.","5":"The plan comparison \u2014 which features are in Free, Basis and Pro."}},"plugin_section":[262246],"plugin_tags":[416,11419,268,266666,65258],"plugin_category":[40],"plugin_contributors":[266667],"plugin_business_model":[],"class_list":["post-307997","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-calendar","plugin_tags-roster","plugin_tags-scheduling","plugin_tags-shifts","plugin_tags-volunteers","plugin_category-calendar-and-events","plugin_contributors-wpdienstplan","plugin_committers-wpdienstplan"],"banners":{"banner":"https:\/\/ps.w.org\/dienstplan\/assets\/banner-772x250.png?rev=3568853","banner_2x":"https:\/\/ps.w.org\/dienstplan\/assets\/banner-1544x500.png?rev=3568853","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/dienstplan\/assets\/icon-128x128.png?rev=3569919","icon_2x":"https:\/\/ps.w.org\/dienstplan\/assets\/icon-256x256.png?rev=3569919","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/dienstplan\/assets\/screenshot-1.png?rev=3586003","caption":"The interactive calendar on a public page \u2014 members see upcoming shifts and sign up with one click."},{"src":"https:\/\/ps.w.org\/dienstplan\/assets\/screenshot-2.png?rev=3586003","caption":"The admin shift planner \u2014 assign members to shifts, with an at-a-glance view of who is signed up where."},{"src":"https:\/\/ps.w.org\/dienstplan\/assets\/screenshot-3.png?rev=3586003","caption":"The events list \u2014 plan training nights, fundraisers and on-call duties with categories (per-event signup lists with Basis)."},{"src":"https:\/\/ps.w.org\/dienstplan\/assets\/screenshot-4.png?rev=3586003","caption":"The \"My shifts\" dashboard widget \u2014 every member sees their own upcoming commitments at login."},{"src":"https:\/\/ps.w.org\/dienstplan\/assets\/screenshot-5.png?rev=3586003","caption":"The plan comparison \u2014 which features are in Free, Basis and Pro."}],"raw_content":"<!--section=description-->\n<p>Dienstplan turns your WordPress site into a shift and duty roster that runs without a full-time coordinator.<\/p>\n\n<p>It is built for teams that rely on volunteers \u2014 fire departments, emergency medical services, first-responder and crisis-response groups, sports clubs and associations. Members open a calendar page and sign up for open shifts themselves. Coordinators see at a glance which shifts are still open, who already volunteered, and who has not yet contributed this period. Every change is recorded, so \"who removed me from Saturday?\" always has an answer.<\/p>\n\n<p>Everything runs on your own WordPress install. Member data, schedules and assignments stay in your database \u2014 no SaaS account, no recurring fee for the free version. The only optional outbound connection is the public-holiday lookup via openholidaysapi.org, disabled by default (see <strong>External services<\/strong>).<\/p>\n\n<h4>What you can do<\/h4>\n\n<ul>\n<li>Define shift types (early\/late\/night, driver\/paramedic \u2014 whatever your team uses) and build week or month rosters<\/li>\n<li>Drop the roster onto any page with the <code>[dienstplan]<\/code> shortcode<\/li>\n<li>Let members sign up for shifts and remove themselves again \u2014 coordinators see every change live, no email ping-pong<\/li>\n<li>Plan events like training nights, fundraisers or on-call duties with categories (per-event signup lists come with Basis)<\/li>\n<li>Show each member their own upcoming shifts in a dashboard widget<\/li>\n<li>Let members download their shifts as an ICS calendar file<\/li>\n<\/ul>\n\n<h4>Why WordPress<\/h4>\n\n<p>Most volunteer organisations already run a WordPress site for news and member communication. Adding the roster there means members use the account they already have, your data stays in your own database, and there is no external SaaS to vet for data protection.<\/p>\n\n<h4>Free, Basis and Pro<\/h4>\n\n<p>The version on WordPress.org is <strong>Free<\/strong> and stays free forever: one shift schedule, unlimited members, shift types and events \u2014 no artificial caps.<\/p>\n\n<p>Two optional add-ons extend the same plugin in place, with your data carrying over automatically:<\/p>\n\n<ul>\n<li><strong>Basis<\/strong> \u2014 multiple rosters, recurring events, per-event signups and tasks, shift trading, group and weekday restrictions, automated email notifications, and a community feedback channel. For established teams that need self-service workflows.<\/li>\n<li><strong>Pro<\/strong> \u2014 everything in Basis plus attendance statistics, a tamper-evident audit log and waiting-list promotion on full events. For organisations with reporting or audit obligations.<\/li>\n<\/ul>\n\n<p>Pricing and the full comparison are at <a href=\"https:\/\/www.wp-dienstplan.de\">wp-dienstplan.de<\/a>.<\/p>\n\n<h4>Languages<\/h4>\n\n<p>Ships with English, German, Spanish, French and Italian. Source strings are English; further languages can be added via standard <code>.po<\/code>\/<code>.mo<\/code> files in <code>languages\/<\/code>.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to the public OpenHolidays API (<code>https:\/\/openholidaysapi.org<\/code>) to retrieve official public-holiday dates for the country and (optional) region configured under <strong>Dienstplan \u2192 Settings \u2192 Holidays<\/strong>. The dates are stored in your own WordPress options and shown as background highlights on the calendar so members can see at a glance which days are public holidays. The feature is fully optional \u2014 clearing the holiday country in settings disables every outbound call.<\/p>\n\n<p>It sends a request to <code>https:\/\/openholidaysapi.org<\/code> in three situations:<\/p>\n\n<ul>\n<li><code>GET \/Countries<\/code> \u2014 once, when the admin opens the holiday-settings page and the country list has not been cached yet. No payload, only an HTTP request.<\/li>\n<li><code>GET \/Subdivisions?countryIsoCode=XX<\/code> \u2014 once per country, when the admin selects a country in the settings UI to populate the region dropdown. The configured country code is transmitted as a query parameter.<\/li>\n<li><code>GET \/PublicHolidays?countryIsoCode=XX&amp;languageIsoCode=YY&amp;validFrom=YYYY-01-01&amp;validTo=YYYY-12-31[&amp;subdivisionCode=ZZZZ]<\/code> \u2014 once per year via WordPress cron, plus on demand when the admin triggers a manual refresh from the settings page. The configured country code, region code (if any), language code and requested year are sent as query parameters.<\/li>\n<\/ul>\n\n<p>In every case, <strong>only configuration values entered by the administrator are transmitted<\/strong> (country \/ region \/ language \/ year). No member names, email addresses, shift data or audit-log entries are sent.<\/p>\n\n<p>This service is provided by ST\u00dcBER SYSTEMS GmbH as an Open Data project: <a href=\"https:\/\/www.stueber.de\/en\/legal\/imprint.php\">terms of use<\/a>, <a href=\"https:\/\/www.stueber.de\/en\/legal\/privacy.php\">privacy policy<\/a>. Project documentation and the data-source overview are available at <a href=\"https:\/\/www.openholidaysapi.org\">https:\/\/www.openholidaysapi.org<\/a>.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>Dienstplan is built so that all member-related data \u2014 names, email addresses (from the WordPress user account), shift assignments, signup history, audit-log entries \u2014 stays exclusively in your own WordPress database. The free plugin makes no outbound HTTP requests other than the OpenHolidays calls documented in <strong>External services<\/strong> above.<\/p>\n\n<h4>If you use the optional Basis or Pro add-on<\/h4>\n\n<p>The commercial add-on contacts a separate license server at <code>lizenz.wp-dienstplan.de<\/code> for license activation and a daily license-status check. The data transmitted is limited to the license key, your site URL, and a status flag \u2014 no member data, no shift data and no email addresses are sent. License-server activity is logged with industry-standard webserver logs (IP, timestamp, user agent) for fraud prevention; the privacy policy at <a href=\"https:\/\/www.wp-dienstplan.de\">wp-dienstplan.de<\/a> documents this in detail. The license server is <strong>not<\/strong> active in the free plugin distributed via WordPress.org.<\/p>\n\n<h4>Cookies and trackers<\/h4>\n\n<p>Dienstplan sets no cookies of its own and uses no third-party trackers. The plugin relies on WordPress's standard authentication cookies for member login and on <code>localStorage<\/code> for remembering the last selected roster on multi-roster pages.<\/p>\n\n<!--section=installation-->\n<h4>From WordPress.org (recommended)<\/h4>\n\n<ol>\n<li>Go to <strong>Plugins \u2192 Add New<\/strong> and search for \"Dienstplan\".<\/li>\n<li>Click <strong>Install Now<\/strong>, then <strong>Activate<\/strong>.<\/li>\n<li>Open the new <strong>Dienstplan<\/strong> entry in the admin sidebar to start configuring.<\/li>\n<\/ol>\n\n<h4>From a ZIP file<\/h4>\n\n<ol>\n<li>Download the latest ZIP from this plugin page or your account at wp-dienstplan.de.<\/li>\n<li>Go to <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong>, upload the ZIP, then <strong>Activate<\/strong>.<\/li>\n<\/ol>\n\n<h4>First steps<\/h4>\n\n<ol>\n<li>Open <strong>Dienstplan \u2192 Overview<\/strong> for a guided setup of shift types and event categories.<\/li>\n<li>Place the <code>[dienstplan]<\/code> shortcode on the page where members should see the calendar.<\/li>\n<li>Optionally configure public holidays under <strong>Dienstplan \u2192 Settings \u2192 Holidays<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20does%20my%20hosting%20need%3F\"><h3>What does my hosting need?<\/h3><\/dt>\n<dd><p>Standard shared hosting. Required: WordPress 6.3+ and PHP 8.1+. No special server modules and no cron daemon (WordPress's built-in cron is used). The only optional outbound call is the holiday lookup (see <strong>External services<\/strong>).<\/p><\/dd>\n<dt id=\"where%20is%20member%20data%20stored%3F\"><h3>Where is member data stored?<\/h3><\/dt>\n<dd><p>Exclusively in your own WordPress database, on your own server. The plugin sends no member data to us or any third party. If you enable public holidays, it fetches holiday dates from openholidaysapi.org \u2014 configuration values only (see <strong>External services<\/strong>).<\/p><\/dd>\n<dt id=\"can%20i%20show%20the%20roster%20on%20a%20public%20page%3F\"><h3>Can I show the roster on a public page?<\/h3><\/dt>\n<dd><p>Yes. Use the <code>[dienstplan]<\/code> shortcode on any page or post. Optional parameters scope the calendar, e.g. <code>[dienstplan year=\"2026\" shift_type_id=\"5\"]<\/code> \u2014 see the in-admin help for the full reference.<\/p><\/dd>\n<dt id=\"how%20does%20shift%20signup%20work%3F\"><h3>How does shift signup work?<\/h3><\/dt>\n<dd><p>Members log into your site, open the calendar page and click an open shift to sign up. They can remove themselves again, and the change is recorded. Coordinators see the live state on the same page and in the admin overview.<\/p><\/dd>\n<dt id=\"multiple%20shift%20types%20or%20rosters%3F\"><h3>Multiple shift types or rosters?<\/h3><\/dt>\n<dd><p>Free includes one schedule with unlimited shift types and events. Basis and Pro add multiple rosters, group restrictions, recurring events, per-event signups, statistics and an audit log.<\/p><\/dd>\n<dt id=\"will%20my%20data%20survive%20a%20switch%20between%20free%2C%20basis%20and%20pro%3F\"><h3>Will my data survive a switch between Free, Basis and Pro?<\/h3><\/dt>\n<dd><p>Yes. The add-on uses the same database tables \u2014 activating it only unlocks features, it migrates nothing. Deactivating hides premium screens; your data stays in place.<\/p><\/dd>\n<dt id=\"how%20do%20i%20suggest%20features%20or%20report%20bugs%3F\"><h3>How do I suggest features or report bugs?<\/h3><\/dt>\n<dd><p>The <strong>Improve plugin<\/strong> screen in the admin (Basis and Pro) lets you submit ideas, report bugs, vote and see what's in progress. Without a license, use the WordPress.org support forum for this plugin.<\/p><\/dd>\n<dt id=\"where%20can%20i%20get%20support%3F\"><h3>Where can I get support?<\/h3><\/dt>\n<dd><p>For the free version, use the WordPress.org support forum linked from this page. Basis and Pro customers can also email info@wp-dienstplan.de with their license key.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>3.5.1 \u2014 2026-06-25<\/h4>\n\n<p>Documentation-only update: condensed wp.org readme, plugin header description aligned with the new short tagline, German GlotPress reference docs refreshed. No code changes.<\/p>\n\n<h4>3.5.0 \u2014 2026-06-15<\/h4>\n\n<p>Focus on the shift planner and calendar readability. No breaking changes.<\/p>\n\n<ul>\n<li>Shift planner redesigned as a master-detail view: plans in a resizable sidebar on the left, shifts on the right<\/li>\n<li>Shifts can be reordered by drag &amp; drop; consistent active\/inactive toggling across all admin tables<\/li>\n<li>Shift colours now shown directly in the month view<\/li>\n<li>Clearer plan comparison with separate ICS tiers and a new \"Multiple rosters\" row<\/li>\n<li>Renamed UI term \"shift type\" to \"shift\"<\/li>\n<li>Updated translations (DE\/DE-formal\/ES\/FR\/IT)<\/li>\n<\/ul>\n\n<h4>3.4.0\u20133.4.2 \u2014 June 2026<\/h4>\n\n<ul>\n<li>wp.org compliance: free is a fully functional single-schedule roster with no trialware patterns; multi-plan, weekday restrictions, event sign-ups\/recurrences and audit log moved to the Premium add-on<\/li>\n<li>Restored the \"My shifts\" dashboard widget<\/li>\n<li>Hardened sanitization for shift-type\/event saves and holiday settings<\/li>\n<li>Clarified that openholidaysapi.org is the only optional external service (disabled by default)<\/li>\n<\/ul>\n\n<h4>3.3.0 \u2014 2026-06-01<\/h4>\n\n<ul>\n<li>wp.org compliance: removed all quantity limits (members, plans, shift types, groups, events) from the free plugin<\/li>\n<li>Groups moved entirely to the Premium add-on, including tables and access-control logic; free exposes extension hooks only<\/li>\n<li>Simplified event creation dialog and clearer plan comparison<\/li>\n<\/ul>\n\n<h4>3.2.0\u20133.2.2 \u2014 May 2026<\/h4>\n\n<p>First releases prepared for the official WordPress.org directory, addressing the plugin-review team's feedback. No feature changes \u2014 output hardening and naming only.<\/p>\n\n<ul>\n<li>Unified plugin prefix <code>dienstplan_<\/code> across all AJAX actions, nonces, options, transients, cron hooks, asset handles and CSS classes<\/li>\n<li>Output escaping hardened throughout (<code>wp_kses()<\/code> for SVG icons, <code>esc_attr()<\/code> in attributes, defensive filtering of inline styles)<\/li>\n<li>Renamed shortcode <code>[termine]<\/code> to <code>[dienstplan_termine]<\/code><\/li>\n<li>Documented the openholidaysapi.org integration under <strong>External services<\/strong><\/li>\n<\/ul>\n\n<h4>3.1.0 \u2014 2026-04-30<\/h4>\n\n<p>Preparation for the first WordPress.org release (not shipped publicly; see 3.2.0).<\/p>\n\n<ul>\n<li>Fully English source strings with DE\/ES\/FR\/IT localisations<\/li>\n<li>Public hook API (<code>dienstplan_*<\/code> filters and actions) for clean extension \u2014 reference in <code>docs\/hooks-reference.md<\/code><\/li>\n<li>Tier structure (Free \/ Basis \/ Pro) documented<\/li>\n<\/ul>","raw_excerpt":"Self-hosted shift rosters for volunteer teams \u2014 members sign themselves up, no SaaS, no monthly fee.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/307997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=307997"}],"author":[{"embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/wpdienstplan"}],"wp:attachment":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=307997"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=307997"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=307997"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=307997"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=307997"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=307997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}