summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-07-06Disable verify_foreign_keys_for_fixtures for test enverdgeist
Adding the occurrences.event_id FK constraint broke fixture loading entirely (every test failing at setup) with a misleading "Foreign key violations found in your fixture data" error. The real cause: this Rails feature does its own proactive integrity check during fixture insertion, independent of the constraint's own deferrability, by directly flipping pg_constraint.convalidated and re-validating - which needs catalog-level privilege the app's DB role correctly doesn't have. No actual fixture data was ever invalid; the check itself couldn't run. Scoped to test.rb only - this never affected real application behavior, and Postgres still fully enforces the actual constraint everywhere, in every environment, regardless of this setting.
2026-07-06Add migration for the default template name featureerdgeist
2026-07-06Add erfa/chaostreff node-kind creation conventions, part 2erdgeist
The following changes were already announced in the last commit, but the files forgotten. Here's them actually attached. lib/ccc_conventions.rb: NODE_KINDS registry replaces the kind-specific branches previously scattered across nodes_controller#create (tags), unique_path-position check). Each kind declares its parent lookup (a Proc - Update's "update"/"press_release" continue to genuinely find-or-create their year-folder via Update.find_or_create_parent; erfa/chaostreff use a plain find_by_unique_name!, since their parent nodes are fixed and a missing one should fail loudly, not be silently created), its tags, and (new) its default template. New read-only admin/conventions view dumps the NODE_KINDS registry as a reference table for whoever's confused later about how a given kind behaves - deliberately just renders the same label/hint text used on nodes#new rather than re-describing parent/tags/template separately, since decomposing the parent Proc would mean either invoking it (Update's has a real side effect - creates the year folder) or re-stating its logic a second time in a different shape, either of which risks drifting from the actual behavior.
2026-07-05Whitespace fixeserdgeist
2026-07-05Surface node-kind conventions in the admin UIerdgeist
nodes#new: each kind's radio button now shows a label plus a smaller, muted .field_hint explaining what happens automatically (parent, tags, template) - previously a single undifferentiated string mixing a short label with a long parenthetical, cluttering the smaller kinds (erfa/chaostreff) worst. Title field gets the same hint treatment, telling editors up front that the slug is auto-generated and where to adjust it later - the previous silence here meant editors only discovered slug generation after already committing to a title, with no visible way to fix it. New "Resulting path" row live-previews the full URL (origin + kind's path prefix + a debounced call to the new parameterize_preview route, reusing the exact same slug_for helper "create" now calls, so the preview can never diverge from what actually gets created) as the editor types, plus a copy-to-clipboard button. For "generic", the prefix comes from whichever parent gets chosen via the search widget, not the registry - parent_search.link_closure now stashes the chosen node's unique_name as a data attribute for exactly this. New read-only admin/conventions view dumps the NODE_KINDS registry as a reference table for whoever's confused later about how a given kind behaves - deliberately just renders the same label/hint text used on nodes#new rather than re-describing parent/tags/template separately, since decomposing the parent Proc would mean either invoking it (Update's has a real side effect - creates the year folder) or re-stating its logic a second time in a different shape, either of which risks drifting from the actual behavior. nodes#edit's Template field gets a one-line hint noting the value may already be pre-filled based on how the node was created - the one place the previous commit's new inheritance mechanism actually surfaces on this view.
2026-07-05Add erfa/chaostreff node-kind creation conventionserdgeist
lib/ccc_conventions.rb: NODE_KINDS registry replaces the kind-specific branches previously scattered across nodes_controller#create (tags), unique_path-position check). Each kind declares its parent lookup (a Proc - Update's "update"/"press_release" continue to genuinely find-or-create their year-folder via Update.find_or_create_parent; erfa/chaostreff use a plain find_by_unique_name!, since their parent nodes are fixed and a missing one should fail loudly, not be silently created), its tags, and (new) its default template. Node gains a default_template_name column (migration, with backfill for existing update-tree nodes via node.update? - reusing that method rather than re-deriving its unique_path check in raw SQL). Page#set_template now inherits from node.default_template_name, falling back to the old update?-based check only when the column is blank, and only fills in template_name when nothing's already been explicitly chosen - a deliberate change from the previous behavior, which unconditionally overwrote template_name on every save regardless of manual selection. Node#update? itself is unchanged and still used as-is by admin_controller's sitemap filtering - a genuinely different, still valid use of that check. "generic" stays special-cased in the controller, parametrized by params[:parent_id] at request time - doesn't fit "kind implies a fixed lookup" and isn't in the registry. nodes#new's four hardcoded radio buttons and nodes_controller's kind-specific case/when branches are both replaced by iterating/looking up this one registry - adding a new kind now means one new hash entry, not four scattered edits.
2026-07-05Fix admin search results colliding with other search widgetserdgeist
layouts/admin.html.erb's top-bar search results div shared id "search_results" with nodes#new/nodes#edit's parent-search widget - since the layout renders on every admin page, whichever widget's JS ran last silently won the shared ID, putting top-bar results into the parent-search box on affected pages. Renamed to "menu_search_results" and updated admin_search.js to match. Also modernizes admin_search.js's event bindings from keyup/keydown/ keypress/paste/cut + .attr("value") to input + .val() throughout (menu_items, parent_search, move_to_search) - the multi-event binding was working around old IE compatibility that .val() + "input" already handles correctly. parent_search's result rendering now matches menu_search's convention (real <p>/<a> markup with a .result_path span) instead of a bare <a> in a throwaway wrapper div, so the same CSS rule now correctly applies to both. menu_search's JSON response gains node_path per result, matching what admin_search's own results already provide - not yet consumed by parent_search/move_to_search, which still render click-to-select links rather than navigable ones (correct for their purpose - selecting a value, not leaving the page). Known remaining gap, not fixed here: menu_items, parent_search, and move_to_search still all target the literal id "search_results" between themselves. No live collision today since none of the three currently share a page, but it's the same fragility as the bug above - tracked alongside the existing menu_items/parent_search/move_to_search consolidation backlog item rather than treated as resolved.
2026-07-04Retire event_information, superseded by nodes#show's event managererdgeist
The metadata-panel "Event" field on nodes#edit called event_information, a second, tag-less implementation of "list events + add one" - now redundant now that nodes#show has the tag-aware version with the auto-tag flash explanation. Confirmed via grep this was the only call site before removing both it and the method definition.
2026-07-04Fix safe_return_to being uncallable from controllerserdgeist
Defined only in ApplicationHelper, which Rails auto-mixes into views but not controllers - so events#create and events#update, which call it directly, have been broken since introduction. Likely unexercised until now because every existing event was created via node.events.create! in the seed script, never through a real POST. Moved to ApplicationController as a protected method + helper_method declaration, so both controllers and views can call it (form_error_ messages stays in ApplicationHelper - it's genuinely view-only, content_tag isn't available in a controller either). Logic unchanged, caught by the new EventsController tests in the previous commit.
2026-07-04Add self-service event creation from nodes#showerdgeist
nodes#show's events table now renders unconditionally (previously hidden entirely for a zero-event node) and gains an "add event" link. The suggested tag_list is derived from the page's own category tags via NodesHelper::DEFAULT_EVENT_TAG_BY_PAGE_TAG (erfa-detail/ chaostreff-detail -> open-day) rather than hardcoded, and degrades to a blank field for any node whose tags don't match - deliberately universal, not chapter-specific, since Updates have historically carried event dates the same way. events#new surfaces *why* the tag was pre-filled via flash.now (not flash - this is a same-request render, not a redirect), using an explicit auto_tag_source param passed alongside tag_list rather than having the controller re-derive the reason from node_id. No destroy link added to nodes#show's events list - deliberate, per existing subnav-semantics convention (destructive actions live on the resource's own views). Covered directly by test. Adds real coverage for EventsController, previously 100% commented-out scaffold, plus unit tests for the new tag-mapping helper and the weekday-abbreviation helpers from the prior commit.
2026-07-03Change open-today widget labelerdgeist
2026-07-03Reduce right-column widget font size to 0.9remerdgeist
2026-07-03Style open-today widget for wrapped multi-line entrieserdgeist
2026-07-03Add weekday abbreviation for open-today widgeterdgeist
RruleHumanizer gains WEEKDAY_NAMES_ABBR (Mo/Di/Mi/...) alongside the existing WEEKDAY_NAMES and WEEKDAY_NAMES_ADVERBIAL hashes, plus a self.wday_abbr(time, locale) utility mapping a Time's wday to its RFC5545 code and looking up the abbreviation - keeping RFC5545 vocabulary in one place rather than teaching ContentHelper about day codes directly. ContentHelper#weekday_abbr is a thin wrapper passing I18n.locale through. The partial now renders "Fr 19:00" instead of just "19:00", joined with a non-breaking space so the pair can't split across a line wrap. Takes an explicit Time rather than reading Date.today, matching this file's existing style of passing state in rather than reading it ambiently - and staying correct if the currently-unused calendar/_front_page_calendar partial (spanning six weeks, not just today) is ever revived and reuses this helper.
2026-07-03Correct chapters seed against live ccc.de pageserdgeist
2026-07-03ascade-destroy occurrences; support events without a fixed start timeerdgeist
- Event#occurrences is now dependent: :destroy, so destroying an Event (directly, or via Node's cascade) removes its Occurrence rows instead of orphaning them. - Renamed generate_occurences -> generate_occurrences (typo fix); callback and method updated together. - Occurrence.generate returns early when event.start_time is nil, so a chapter with no sourced time produces zero occurrences instead of a guessed one. - seed_chapter no longer falls back to 19:00 when start_time is absent; base_time/end_time are nil in that case. Database-level foreign key cascade on occurrences.event_id is still pending.
2026-07-02rc.d: gemset auto-detection, occurrence regeneration commanderdgeist
- Derive rvm gemset path from .ruby-version and .ruby-gemset in the app directory, with fallback to current hardcoded values — no more manual rc.d edits on gemset changes - New extra command: service cccms regenerate_occurrences - Poststart staleness check: regenerates occurrences when marker file /var/db/cccms_occurrences_regenerated is missing or older than one year; runs only after successful server start, synchronously for error visibility Deployment note: updated script must be manually copied to /usr/local/etc/rc.d/cccms on live.
2026-07-02Add 'open today' sidebar widget and open days in chapter listserdgeist
- open_erfas_today helper: samples 3 random open-day-tagged occurrences of the current day; widget hidden entirely on days without open chapters; heading shows current weekday - content/_open_erfas_today partial rendered in right column above tags and featured articles - _chapter partial: open-day schedules (event_schedule_text) shown inline in aggregated chapter lists with 'Offene Tage' label - ccc.css: open_erfas_today added to existing right-column widget selector groups (headings, lists, links)
2026-07-02Fix DST drift in occurrence generationerdgeist
- Occurrence.generate_dates: use ChaosCalendar::occurrences_for_timezone with Time.zone.tzinfo.identifier — occurrences now keep wall-clock time across DST boundaries (19:00 stays 19:00 in summer and winter); requires chaoscalendar gem with occurrences_for_timezone support (Gemfile.lock bumped accordingly) - Occurrence.find_in_range: joins(:event) inner join excludes occurrences whose event no longer exists (107k orphaned rows from the pre-revival calendar era were purged from the test DB); includes(:node) retained for eager loading; column references qualified with table name
2026-07-02Add direct edit link to nodes#indexerdgeist
First application of subnav visual conventions to nodes: actions column now shows show | edit | revisions as plain informational links. edit intentionally uses edit_node_path (locking is expected behaviour for nodes, unlike event views where node_path is used to avoid inadvertent locking).
2026-07-02Remove review notes fileerdgeist
2026-07-02Rewrite chapter seeds: multi-event support, drop is_primary, fix dataerdgeist
- seed_chapter now accepts events: array instead of flat rrule:/ start_time: params; each event hash supports rrule:, start_time:, tag_list:, location:, duration_hours: - Chapters with multiple open days now represented correctly (Stralsund: Thursday Chaostreff + 2nd/4th Saturday OpenSpace; Hamburg: 2nd Friday + last Tuesday; Stuttgart: 1st Tuesday + 3rd Wednesday; Freiburg: Mon+Tue open + biweekly Plenum; Backnang: 3rd Sunday + 1st Tuesday; Tübingen: last Sunday + 2nd Monday at different venues) - is_primary removed from migration entirely — replaced by tag_list: 'open-day' on events - Stale EN descriptions corrected: Berlin, Darmstadt, Erlangen, Essen, Freiburg, Göttingen, Hamburg, Hannover, Karlsruhe, Paderborn, Stuttgart, Ulm - chaostreff-stralsund duplicate entry removed (Port39 is erfa only)
2026-07-02Rewrite chapter_detail template with humanized event scheduleerdgeist
- Split events into open-day tagged events (prominent, via tagged_with) and other events (secondary listing) - Use event_schedule_text helper for humanized recurrence + start time rather than raw rrule string - Section headings via i18n open_days / upcoming_events keys
2026-07-02Add tagging support to Event modelerdgeist
- Event: acts_as_taggable_on :tags — uses existing polymorphic taggings table, no migration needed - events/edit and events/new: tag_list field added, tag_list permitted in events_controller strong params - locales: add open_days (Offene Tage / Open days), upcoming_events (Weitere Termine / Upcoming events), event_schedule_time, event_schedule_unrecognized, event_schedule_none keys
2026-07-02Clean up events views: return_to, subnav, remove custom_rruleerdgeist
- events_controller: wire return_to through show and new actions; create respects return_to with fallback to node/event path; new pre-populates node_id and tag_list from params - events/edit: remove custom_rrule checkbox; node link removed from subnav (use show for node navigation); destroy button added - events/new: remove custom_rrule checkbox; add return_to hidden field and back link; tag_list field added - events/show: fix back link via safe_return_to; add node link to subnav; add destroy button; remove custom_rrule display; show humanized rrule below raw string - events/index: destructive class on destroy button; node_id column replaced with node link; show/edit links carry return_to - nodes/show: add show/edit links to event entries with return_to
2026-07-02Fix button_to styling for Rails 8.1, add destructive varianterdgeist
- Extend all selectors to cover button[type="submit"] alongside input[type="submit"] — Rails 8.1 generates <button> not <input> - Add appearance: none / -webkit-appearance: none to kill browser native button chrome - Default hover now matches plain link hover (color: #ff9600) - Add form.button_to.destructive variant: #cc0000 at rest, white-on-red pill on hover - Usage: form: { class: 'button_to destructive' } in button_to calls
2026-07-01Add RRULE humanizer and wire events into nodes#showerdgeist
- app/models/concerns/rrule_humanizer.rb: new concern included into Event, renders recurring schedule as natural-language German or English from RRULE string; handles WEEKLY/MONTHLY, biweekly (INTERVAL=2), ordinal weekday positions (1TU, -1TH, -2WE), BYMONTH single-month exclusions (December pause convention); gracefully returns nil for COUNT/UNTIL/unrecognized shapes - test/models/concerns/rrule_humanizer_test.rb: 15 tests covering all distinct RRULE shapes found in production data - app/helpers/nodes_helper.rb: add event_schedule_text helper combining humanize_rrule with start_time formatting - app/views/nodes/show.html.erb: add events row, conditionally rendered when node has associated events - config/locales/de.yml, en.yml: add event_schedule_time, event_schedule_unrecognized, event_schedule_none keys
2026-06-30Fix events CRUD for standalone events and add events to admin menuerdgeist
- event_params now permits title, description, is_primary - event_information helper lists all node.events, not just the first - Occurrence.generate handles nil node (standalone events) - Page.aggregate order_by title uses correlated subquery to avoid GROUP BY conflict with tag-filter path; order_direction whitelisted to ASC/DESC to prevent SQL injection - Events link added to admin menu bar - events/index shows title, is_primary; drops latitude/longitude columns
2026-06-30Add chapter_detail template with events and external URL renderingerdgeist
New public page template for erfa and chaostreff nodes. Renders the node's external_url and lists associated events below the page content. Seed script updated to set template_name: 'chapter_detail' on all chapter drafts so the template is applied on publish.
2026-06-30Phase 2: chapter nodes, aggregate partial, fixeserdgeist
- _chapter.html.erb: new partial for erfa/chaostreff aggregated lists; renders title, location, external_url, sanitized body - content_helper: fix aggregate attr regex to allow hyphens in values (erfa-detail tag was silently dropped); add debug logging (remove) - page.rb: suppress libxml stderr noise in rewrite_links_in_body - db/seeds/chapters.rb: one-shot seed script for erfa and chaostreff chapter nodes under parent nodes 548/549; creates bilingual pages, external_url, primary events with RRULEs where known Note: run Node.rebuild!(false) after execution to fix lft/rgt values
2026-06-30Phase 1: standalone events, external_url on nodeserdgeist
- Migration: node_id nullable on events and occurrences, add title/description/is_primary to events, external_url to nodes - Existing events marked is_primary: true (were all 1:1 with nodes) - Node: has_one :event -> has_many :events - Event: belongs_to :node optional, validates title presence for standalone events, is_primary uniqueness scoped to node_id, display_title helper falling back through node title - Occurrence: belongs_to :node optional, summary falls back to event.display_title - nodes_helper: event_information uses events.first (interim; will be replaced in Phase 3 event UI) - Tests: fix node.event -> node.events.first in event_test
2026-06-30Address brakeman security findingserdgeist
- Replace permit! with permit(:locale, :page_path) in AdminHelper#language_selector
2026-06-30Permit :admin in params only for adminserdgeist
2026-06-30Remove recent_changes RSS feed. It leaks unpublished drafts and the basic auth was only symbolicerdgeist
2026-06-30Remove obsolete viewerdgeist
2026-06-30Remove obsolete partialerdgeist
2026-06-30Prevent xss by not allowing return_to to point to javascript resourceserdgeist
2026-06-30Fix aggregate shortcode syntax in content_controller_testerdgeist
Test used the old <aggregate ...> tag form; production templates already use the [aggregate ...] shortcode.
2026-06-30Replace installing click event handler with non-jquery codeerdgeist
2026-06-30Replace Shadowbox with GLightbox, drop jQuery from public siteerdgeist
Vendors GLightbox 3.3.1 (MIT, dependency-free) as static files in public/javascripts and public/stylesheets, replacing the Shadowbox 2009 vendor tree and its jQuery adapter. Public site no longer loads jQuery at all. - app/views/layouts/application.html.erb: swap Shadowbox script/style includes and the public_bundle (jQuery) include for GLightbox's CSS/JS - app/views/content/_headline_image.html.erb: headline image is now itself a GLightbox trigger; additional images are direct a.glightbox links sharing a per-page data-gallery group, replacing the hidden shadowbox_images div and its click-forwarding trigger - public/javascripts/public.js: replace Shadowbox.init/setup and the click-forwarding handler with a single GLightbox() init call; remove the unused image_handler object - Remove public/javascripts/shadowbox/ (including vendored Sizzle, swfobject, and unused video/Flash players) and public/stylesheets/shadowbox.css - Remove app/assets/javascripts/public_bundle.js (jquery require)
2026-06-30Unify jQuery: serve public site jQuery via asset pipelineerdgeist
Remove vendored jquery-1.3.2.min.js, jquery-ui-1.7.2.custom.min.js, and the unreferenced duplicate jquery.hotkeys.js from public/javascripts/. Public layout now loads jQuery via a small public_bundle.js manifest through the asset pipeline, same mechanism already used for the admin interface (admin_bundle.js). This brings the public site from jQuery 1.3.2 (2009) to the current jquery-rails-provided version (3.7.x). Shadowbox's jQuery adapter (shadowbox-jquery.js) only uses stable APIs (.css, .remove, .bind, .unbind, .append, .extend) unchanged across this version span. Verified by manual click-test: gallery image opens, displays, and dismisses correctly. public.js required no changes — all jQuery APIs used (.ready, .bind, .trigger, .length) are stable across versions.
2026-06-30Ignore public/assetserdgeist
2026-06-30Improve admin search overlay layout and behaviourerdgeist
- Widen overlay (300px -> min(520px, 90vw)), centre instead of hardcoded left:400px, so it scales from mobile to desktop - Split title and unique_name into separate JSON fields and DOM elements; two-line result layout (bold title, small grey monospace path) instead of "Title (path)" wrapping awkwardly - Add small margin between title and path line - Fix event handler stacking: keyup/escape/outside-click handlers were being rebound on every display_toggle call. Moved all bindings to initialize(), display_toggle() now only shows/hides - Switch search input from keyup to input event, catching paste and cut via mouse which keyup misses - Add Escape key and outside-click to dismiss the overlay - Stop clearing search box and results on close; reopening now preserves prior search, matching standard search UI behaviour - Link search results to node_path instead of edit_node_path, since opening edit auto-locks the node - Add "press Enter to see all results" hint in dropdown - Disable browser autocomplete on search input
2026-06-29Remove debug output for admin searcherdgeist
2026-06-29Restore and improve admin node searcherdgeist
- Admin search broke when routing-filter was removed: hardcoded /admin/search and /admin/menu_search URLs in admin_search.js no longer matched the locale-scoped routes. Fix by emitting locale-aware URLs from the layout as JS variables. - Also fixes form submission (POST -> GET, missing = on form_tag), jQuery .attr("value") -> .val() for typeahead input reading, and template name for Rails 8 compatibility. - Adds a visible "search" link to the admin menu so editors can discover the feature without knowing the Alt+F shortcut. Search results now show node path alongside title and link directly to the edit view. Named route admin_menu_search added to routes.rb.
2026-06-28Fix tag list rendering in node editorerdgeist
tag_list.to_s produces space-separated output which acts-as-taggable-on 13.0.0 (comma delimiter only) treats as a single tag on re-save. Use join(', ') to render comma-separated tags in the input field.
2026-06-27rss: add per-tag Atom feed at /rss/tags/:tag/updates.xmlerdgeist
- rss#tag_updates action: filters Page.heads by tag name, default locale, 20 items, same caching as updates feed - tag_updates.xml.builder: Atom feed with CGI.escapeHTML on title and summary, consistent with updates.xml.builder - tags/show.html.erb: add subscription link above article list - routes: two routes per existing pattern (format-less + .:format constrained to /xml/)
2026-06-27Migration from Rails 2.3.5 to Rails 8.1 successful.erdgeist
Merging dev branch.
2026-06-27rss: fix self link to include .xml suffixerdgeist
/rss/updates without format suffix returns HTTP 406 when the client does not send an appropriate Accept header. The self link in the Atom feed was pointing to the format-less URL, causing feed readers that follow the self link to hit the 406. Fixed to /rss/updates.xml.
2026-06-27rc.d: switch to rails8-upgrade gemset, hook up start_precmderdgeist
- command: update gemset path from rails7-upgrade to rails8-upgrade - start_precmd: hook was defined but never assigned, so log/pid directory setup was silently skipped on service start