diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 22:52:50 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 22:52:50 +0200 |
| commit | 9a19a0494ef51cdac9a78e24d517ca48ba44c453 (patch) | |
| tree | 8eaae12d8047a40e29d3ea7ff3116b5c869e04bd /app | |
| parent | 85a01e35274b8d4d4165a7b26bd7986e211246bb (diff) | |
| parent | 1853082fcd8c067390c246f9daa01a9b47387497 (diff) | |
Migration from Rails 2.3.5 to Rails 8.1 successful.
Merging dev branch.
Diffstat (limited to 'app')
83 files changed, 1305 insertions, 637 deletions
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 0000000..56d7f6d --- /dev/null +++ b/app/assets/config/manifest.js | |||
| @@ -0,0 +1 @@ | |||
| //= link admin_bundle.js | |||
diff --git a/app/assets/javascripts/admin_bundle.js b/app/assets/javascripts/admin_bundle.js new file mode 100644 index 0000000..687266c --- /dev/null +++ b/app/assets/javascripts/admin_bundle.js | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | //= require jquery | ||
| 2 | //= require jquery_ujs | ||
| 3 | //= require jquery-ui | ||
| 4 | //= require jquery.hotkeys | ||
| 5 | //= require_self | ||
diff --git a/app/assets/javascripts/jquery.hotkeys.js b/app/assets/javascripts/jquery.hotkeys.js new file mode 100755 index 0000000..9a8f2de --- /dev/null +++ b/app/assets/javascripts/jquery.hotkeys.js | |||
| @@ -0,0 +1,244 @@ | |||
| 1 | /* | ||
| 2 | (c) Copyrights 2007 - 2008 | ||
| 3 | |||
| 4 | Original idea by by Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ | ||
| 5 | |||
| 6 | jQuery Plugin by Tzury Bar Yochay | ||
| 7 | tzury.by@gmail.com | ||
| 8 | http://evalinux.wordpress.com | ||
| 9 | http://facebook.com/profile.php?id=513676303 | ||
| 10 | |||
| 11 | Project's sites: | ||
| 12 | http://code.google.com/p/js-hotkeys/ | ||
| 13 | http://github.com/tzuryby/hotkeys/tree/master | ||
| 14 | |||
| 15 | License: same as jQuery license. | ||
| 16 | |||
| 17 | USAGE: | ||
| 18 | // simple usage | ||
| 19 | $(document).bind('keydown', 'Ctrl+c', function(){ alert('copy anyone?');}); | ||
| 20 | |||
| 21 | // special options such as disableInIput | ||
| 22 | $(document).bind('keydown', {combi:'Ctrl+x', disableInInput: true} , function() {}); | ||
| 23 | |||
| 24 | Note: | ||
| 25 | This plugin wraps the following jQuery methods: $.fn.find, $.fn.bind and $.fn.unbind | ||
| 26 | */ | ||
| 27 | |||
| 28 | (function (jQuery){ | ||
| 29 | // keep reference to the original $.fn.bind, $.fn.unbind and $.fn.find | ||
| 30 | jQuery.fn.__bind__ = jQuery.fn.bind; | ||
| 31 | jQuery.fn.__unbind__ = jQuery.fn.unbind; | ||
| 32 | jQuery.fn.__find__ = jQuery.fn.find; | ||
| 33 | |||
| 34 | var hotkeys = { | ||
| 35 | version: '0.7.9', | ||
| 36 | override: /keypress|keydown|keyup/g, | ||
| 37 | triggersMap: {}, | ||
| 38 | |||
| 39 | specialKeys: { 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', | ||
| 40 | 20: 'capslock', 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del', | ||
| 41 | 35:'end', 33: 'pageup', 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', | ||
| 42 | 109: '-', | ||
| 43 | 112:'f1',113:'f2', 114:'f3', 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', | ||
| 44 | 120:'f9', 121:'f10', 122:'f11', 123:'f12', 191: '/'}, | ||
| 45 | |||
| 46 | shiftNums: { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&", | ||
| 47 | "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<", | ||
| 48 | ".":">", "/":"?", "\\":"|" }, | ||
| 49 | |||
| 50 | newTrigger: function (type, combi, callback) { | ||
| 51 | // i.e. {'keyup': {'ctrl': {cb: callback, disableInInput: false}}} | ||
| 52 | var result = {}; | ||
| 53 | result[type] = {}; | ||
| 54 | result[type][combi] = {cb: callback, disableInInput: false}; | ||
| 55 | return result; | ||
| 56 | } | ||
| 57 | }; | ||
| 58 | // add firefox num pad char codes | ||
| 59 | //if (jQuery.browser.mozilla){ | ||
| 60 | // add num pad char codes | ||
| 61 | hotkeys.specialKeys = jQuery.extend(hotkeys.specialKeys, { 96: '0', 97:'1', 98: '2', 99: | ||
| 62 | '3', 100: '4', 101: '5', 102: '6', 103: '7', 104: '8', 105: '9', 106: '*', | ||
| 63 | 107: '+', 109: '-', 110: '.', 111 : '/' | ||
| 64 | }); | ||
| 65 | //} | ||
| 66 | |||
| 67 | // a wrapper around of $.fn.find | ||
| 68 | // see more at: http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d | ||
| 69 | jQuery.fn.find = function( selector ) { | ||
| 70 | this.query = selector; | ||
| 71 | return jQuery.fn.__find__.apply(this, arguments); | ||
| 72 | }; | ||
| 73 | |||
| 74 | jQuery.fn.unbind = function (type, combi, fn){ | ||
| 75 | if (jQuery.isFunction(combi)){ | ||
| 76 | fn = combi; | ||
| 77 | combi = null; | ||
| 78 | } | ||
| 79 | if (combi && typeof combi === 'string'){ | ||
| 80 | var selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); | ||
| 81 | var hkTypes = type.split(' '); | ||
| 82 | for (var x=0; x<hkTypes.length; x++){ | ||
| 83 | delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi]; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | // call jQuery original unbind | ||
| 87 | return this.__unbind__(type, fn); | ||
| 88 | }; | ||
| 89 | |||
| 90 | jQuery.fn.bind = function(type, data, fn){ | ||
| 91 | // grab keyup,keydown,keypress | ||
| 92 | var handle = type.match(hotkeys.override); | ||
| 93 | |||
| 94 | if (jQuery.isFunction(data) || !handle){ | ||
| 95 | // call jQuery.bind only | ||
| 96 | return this.__bind__(type, data, fn); | ||
| 97 | } | ||
| 98 | else{ | ||
| 99 | // split the job | ||
| 100 | var result = null, | ||
| 101 | // pass the rest to the original $.fn.bind | ||
| 102 | pass2jq = jQuery.trim(type.replace(hotkeys.override, '')); | ||
| 103 | |||
| 104 | // see if there are other types, pass them to the original $.fn.bind | ||
| 105 | if (pass2jq){ | ||
| 106 | result = this.__bind__(pass2jq, data, fn); | ||
| 107 | } | ||
| 108 | |||
| 109 | if (typeof data === "string"){ | ||
| 110 | data = {'combi': data}; | ||
| 111 | } | ||
| 112 | if(data.combi){ | ||
| 113 | for (var x=0; x < handle.length; x++){ | ||
| 114 | var eventType = handle[x]; | ||
| 115 | var combi = data.combi.toLowerCase(), | ||
| 116 | trigger = hotkeys.newTrigger(eventType, combi, fn), | ||
| 117 | selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); | ||
| 118 | |||
| 119 | //trigger[eventType][combi].propagate = data.propagate; | ||
| 120 | trigger[eventType][combi].disableInInput = data.disableInInput; | ||
| 121 | |||
| 122 | // first time selector is bounded | ||
| 123 | if (!hotkeys.triggersMap[selectorId]) { | ||
| 124 | hotkeys.triggersMap[selectorId] = trigger; | ||
| 125 | } | ||
| 126 | // first time selector is bounded with this type | ||
| 127 | else if (!hotkeys.triggersMap[selectorId][eventType]) { | ||
| 128 | hotkeys.triggersMap[selectorId][eventType] = trigger[eventType]; | ||
| 129 | } | ||
| 130 | // make trigger point as array so more than one handler can be bound | ||
| 131 | var mapPoint = hotkeys.triggersMap[selectorId][eventType][combi]; | ||
| 132 | if (!mapPoint){ | ||
| 133 | hotkeys.triggersMap[selectorId][eventType][combi] = [trigger[eventType][combi]]; | ||
| 134 | } | ||
| 135 | else if (mapPoint.constructor !== Array){ | ||
| 136 | hotkeys.triggersMap[selectorId][eventType][combi] = [mapPoint]; | ||
| 137 | } | ||
| 138 | else { | ||
| 139 | hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length] = trigger[eventType][combi]; | ||
| 140 | } | ||
| 141 | |||
| 142 | // add attribute and call $.event.add per matched element | ||
| 143 | this.each(function(){ | ||
| 144 | // jQuery wrapper for the current element | ||
| 145 | var jqElem = jQuery(this); | ||
| 146 | |||
| 147 | // element already associated with another collection | ||
| 148 | if (jqElem.attr('hkId') && jqElem.attr('hkId') !== selectorId){ | ||
| 149 | selectorId = jqElem.attr('hkId') + ";" + selectorId; | ||
| 150 | } | ||
| 151 | jqElem.attr('hkId', selectorId); | ||
| 152 | }); | ||
| 153 | result = this.__bind__(handle.join(' '), data, hotkeys.handler) | ||
| 154 | } | ||
| 155 | } | ||
| 156 | return result; | ||
| 157 | } | ||
| 158 | }; | ||
| 159 | // work-around for opera and safari where (sometimes) the target is the element which was last | ||
| 160 | // clicked with the mouse and not the document event it would make sense to get the document | ||
| 161 | hotkeys.findElement = function (elem){ | ||
| 162 | if (!jQuery(elem).attr('hkId')){ | ||
| 163 | if (jQuery.browser.opera || jQuery.browser.safari){ | ||
| 164 | while (!jQuery(elem).attr('hkId') && elem.parentNode){ | ||
| 165 | elem = elem.parentNode; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | return elem; | ||
| 170 | }; | ||
| 171 | // the event handler | ||
| 172 | hotkeys.handler = function(event) { | ||
| 173 | var target = hotkeys.findElement(event.currentTarget), | ||
| 174 | jTarget = jQuery(target), | ||
| 175 | ids = jTarget.attr('hkId'); | ||
| 176 | |||
| 177 | if(ids){ | ||
| 178 | ids = ids.split(';'); | ||
| 179 | var code = event.which, | ||
| 180 | type = event.type, | ||
| 181 | special = hotkeys.specialKeys[code], | ||
| 182 | // prevent f5 overlapping with 't' (or f4 with 's', etc.) | ||
| 183 | character = !special && String.fromCharCode(code).toLowerCase(), | ||
| 184 | shift = event.shiftKey, | ||
| 185 | ctrl = event.ctrlKey, | ||
| 186 | // patch for jquery 1.2.5 && 1.2.6 see more at: | ||
| 187 | // http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b | ||
| 188 | alt = event.altKey || event.originalEvent.altKey, | ||
| 189 | mapPoint = null; | ||
| 190 | |||
| 191 | for (var x=0; x < ids.length; x++){ | ||
| 192 | if (hotkeys.triggersMap[ids[x]][type]){ | ||
| 193 | mapPoint = hotkeys.triggersMap[ids[x]][type]; | ||
| 194 | break; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | //find by: id.type.combi.options | ||
| 199 | if (mapPoint){ | ||
| 200 | var trigger; | ||
| 201 | // event type is associated with the hkId | ||
| 202 | if(!shift && !ctrl && !alt) { // No Modifiers | ||
| 203 | trigger = mapPoint[special] || (character && mapPoint[character]); | ||
| 204 | } | ||
| 205 | else{ | ||
| 206 | // check combinations (alt|ctrl|shift+anything) | ||
| 207 | var modif = ''; | ||
| 208 | if(alt) modif +='alt+'; | ||
| 209 | if(ctrl) modif+= 'ctrl+'; | ||
| 210 | if(shift) modif += 'shift+'; | ||
| 211 | // modifiers + special keys or modifiers + character or modifiers + shift character or just shift character | ||
| 212 | trigger = mapPoint[modif+special]; | ||
| 213 | if (!trigger){ | ||
| 214 | if (character){ | ||
| 215 | trigger = mapPoint[modif+character] | ||
| 216 | || mapPoint[modif+hotkeys.shiftNums[character]] | ||
| 217 | // '$' can be triggered as 'Shift+4' or 'Shift+$' or just '$' | ||
| 218 | || (modif === 'shift+' && mapPoint[hotkeys.shiftNums[character]]); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | } | ||
| 222 | if (trigger){ | ||
| 223 | var result = false; | ||
| 224 | for (var x=0; x < trigger.length; x++){ | ||
| 225 | if(trigger[x].disableInInput){ | ||
| 226 | // double check event.currentTarget and event.target | ||
| 227 | var elem = jQuery(event.target); | ||
| 228 | if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select") | ||
| 229 | || elem.is("input") || elem.is("textarea") || elem.is("select")) { | ||
| 230 | return true; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | // call the registered callback function | ||
| 234 | result = result || trigger[x].cb.apply(this, [event]); | ||
| 235 | } | ||
| 236 | return result; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | }; | ||
| 241 | // place it under window so it can be extended and overridden by others | ||
| 242 | window.hotkeys = hotkeys; | ||
| 243 | return jQuery; | ||
| 244 | })(jQuery); | ||
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 1d1a1ca..9e8564e 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb | |||
| @@ -2,31 +2,46 @@ class AdminController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | def index | 7 | def index |
| 8 | @drafts = Node.all( | 8 | @drafts = Node.where("draft_id IS NOT NULL") |
| 9 | :limit => 20, | 9 | .limit(50).order("updated_at desc") |
| 10 | :order => "updated_at desc", | 10 | |
| 11 | :conditions => ["draft_id IS NOT NULL"] | 11 | @drafts_count = Node.where("draft_id IS NOT NULL").count |
| 12 | ) | 12 | |
| 13 | @recent_changes = Node.all( | 13 | @recent_changes = Node.where( |
| 14 | :limit => 20, | 14 | "updated_at < ? AND updated_at > ? AND parent_id IS NOT NULL", |
| 15 | :order => "updated_at desc", | 15 | Time.now, Time.now - 14.days |
| 16 | :conditions => [ | 16 | ).limit(50).order("updated_at desc") |
| 17 | "updated_at < ? AND updated_at > ? AND parent_id IS NOT NULL", Time.now, Time.now-14.days | 17 | |
| 18 | ] | 18 | all_nodes = Node.root.self_and_descendants |
| 19 | ) | 19 | @sitemap_depth = {} |
| 20 | Node.each_with_level(all_nodes) do |node, level| | ||
| 21 | @sitemap_depth[node.id] = level | ||
| 22 | end | ||
| 23 | @sitemap = all_nodes.to_a.sort! { |node1,node2| node1.lft <=> node2.lft }.delete_if { |node| node.update? } | ||
| 24 | |||
| 25 | @mypages = Page.where("user_id = ? or editor_id = ?", @current_user, @current_user) | ||
| 26 | |||
| 27 | @mynodes = Node.joins(:pages) | ||
| 28 | .where("pages.user_id = ? or pages.editor_id = ?", @current_user, @current_user) | ||
| 29 | .order("updated_at desc") | ||
| 30 | .uniq.first(50) | ||
| 20 | end | 31 | end |
| 21 | 32 | ||
| 22 | def search | 33 | def search |
| 23 | @results = Node.search params[:search_term] | 34 | @results = Node.search params[:search_term], :per_page => 1000 |
| 24 | 35 | ||
| 25 | respond_to do |format| | 36 | respond_to do |format| |
| 26 | format.html | 37 | format.html do |
| 38 | render :template => 'admin/search_results.html' | ||
| 39 | end | ||
| 27 | format.js do | 40 | format.js do |
| 28 | render( :json => @results.map do |node| | 41 | render( :json => @results.map do |node| |
| 29 | {:id => node.id, :title => node.title, :edit_path => node_path(node)} | 42 | if node |
| 43 | {:id => node.id, :title => node.title, :edit_path => node_path(node)} | ||
| 44 | end | ||
| 30 | end | 45 | end |
| 31 | ) | 46 | ) |
| 32 | 47 | ||
| @@ -46,7 +61,6 @@ class AdminController < ApplicationController | |||
| 46 | render :partial => 'admin/menu_search_results' | 61 | render :partial => 'admin/menu_search_results' |
| 47 | end | 62 | end |
| 48 | 63 | ||
| 49 | |||
| 50 | format.js do | 64 | format.js do |
| 51 | render( :json => @results.map do |node| | 65 | render( :json => @results.map do |node| |
| 52 | {:node_id => node.id, :title => node.title, :unique_name => node.unique_name} | 66 | {:node_id => node.id, :title => node.title, :unique_name => node.unique_name} |
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bce0c71..75f92c3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb | |||
| @@ -1,26 +1,21 @@ | |||
| 1 | # Filters added to this controller apply to all controllers in the application. | ||
| 2 | # Likewise, all the methods added will be available for all controllers. | ||
| 3 | |||
| 4 | class ApplicationController < ActionController::Base | 1 | class ApplicationController < ActionController::Base |
| 5 | |||
| 6 | include ExceptionNotifiable | ||
| 7 | include AuthenticatedSystem | 2 | include AuthenticatedSystem |
| 8 | |||
| 9 | helper :all # include all helpers, all the time | ||
| 10 | protect_from_forgery # See ActionController::RequestForgeryProtection for details | ||
| 11 | 3 | ||
| 12 | # Scrub sensitive parameters from your log | 4 | protect_from_forgery |
| 13 | filter_parameter_logging :password, :password_confirmation | 5 | |
| 14 | 6 | before_action :set_locale | |
| 15 | before_filter :set_locale | 7 | |
| 16 | |||
| 17 | protected | 8 | protected |
| 18 | 9 | ||
| 19 | def set_locale | 10 | def set_locale |
| 20 | if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) | 11 | if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) |
| 21 | I18n.locale = params[:locale].to_sym | 12 | I18n.locale = params[:locale].to_sym |
| 22 | else | 13 | else |
| 23 | params.delete(:locale) | 14 | I18n.locale = I18n.default_locale |
| 24 | end | ||
| 25 | end | 15 | end |
| 16 | end | ||
| 17 | |||
| 18 | def default_url_options | ||
| 19 | { locale: I18n.locale == I18n.default_locale ? nil : I18n.locale } | ||
| 20 | end | ||
| 26 | end | 21 | end |
diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index cfaf176..d150e06 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb | |||
| @@ -2,15 +2,14 @@ class AssetsController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | layout 'admin' | 7 | layout 'admin' |
| 8 | 8 | ||
| 9 | def index | 9 | def index |
| 10 | @assets = Asset.all.paginate( | 10 | @assets = Asset.order('id DESC').paginate( |
| 11 | :page => params[:page], | 11 | :page => params[:page], |
| 12 | :per_page => 20, | 12 | :per_page => 20 |
| 13 | :order => 'id DESC' | ||
| 14 | ) | 13 | ) |
| 15 | end | 14 | end |
| 16 | 15 | ||
| @@ -44,7 +43,7 @@ class AssetsController < ApplicationController | |||
| 44 | # POST /assets | 43 | # POST /assets |
| 45 | # POST /assets.xml | 44 | # POST /assets.xml |
| 46 | def create | 45 | def create |
| 47 | @asset = Asset.new(params[:asset]) | 46 | @asset = Asset.new(asset_params) |
| 48 | 47 | ||
| 49 | respond_to do |format| | 48 | respond_to do |format| |
| 50 | if @asset.save | 49 | if @asset.save |
| @@ -64,7 +63,7 @@ class AssetsController < ApplicationController | |||
| 64 | @asset = Asset.find(params[:id]) | 63 | @asset = Asset.find(params[:id]) |
| 65 | 64 | ||
| 66 | respond_to do |format| | 65 | respond_to do |format| |
| 67 | if @asset.update_attributes(params[:asset]) | 66 | if @asset.update(asset_params) |
| 68 | flash[:notice] = 'Asset was successfully updated.' | 67 | flash[:notice] = 'Asset was successfully updated.' |
| 69 | format.html { redirect_to(@asset) } | 68 | format.html { redirect_to(@asset) } |
| 70 | format.xml { head :ok } | 69 | format.xml { head :ok } |
| @@ -86,4 +85,10 @@ class AssetsController < ApplicationController | |||
| 86 | format.xml { head :ok } | 85 | format.xml { head :ok } |
| 87 | end | 86 | end |
| 88 | end | 87 | end |
| 88 | |||
| 89 | private | ||
| 90 | |||
| 91 | def asset_params | ||
| 92 | params.require(:asset).permit(:name, :upload) | ||
| 93 | end | ||
| 89 | end | 94 | end |
diff --git a/app/controllers/content_controller.rb b/app/controllers/content_controller.rb index 1b13456..8d33105 100644 --- a/app/controllers/content_controller.rb +++ b/app/controllers/content_controller.rb | |||
| @@ -1,30 +1,31 @@ | |||
| 1 | class ContentController < ApplicationController | 1 | class ContentController < ApplicationController |
| 2 | 2 | ||
| 3 | # Public | 3 | # Public |
| 4 | 4 | ||
| 5 | before_filter :find_page | 5 | before_action :find_page |
| 6 | 6 | ||
| 7 | # This is the method that renders most of the the public content. It recieves | 7 | # This is the method that renders most of the the public content. It recieves |
| 8 | # a :locale and a :page_path parameter through the params hash. It looks up | 8 | # a :locale and a :page_path parameter through the params hash. It looks up |
| 9 | # the node with the corresponding unique_name attribute. The method doesn't | 9 | # the node with the corresponding unique_name attribute. The method doesn't |
| 10 | # return a node though, the node is really a proxy object for pages. It | 10 | # return a node though, the node is really a proxy object for pages. It |
| 11 | # returns the most recent page associated to this node instead. | 11 | # returns the most recent page associated to this node instead. |
| 12 | def render_page | 12 | def render_page |
| 13 | 13 | ||
| 14 | expires_in 20.minutes, :public => true | 14 | expires_in 20.minutes, :public => true |
| 15 | 15 | ||
| 16 | if @page and @page.public? | 16 | if @page and @page.public? |
| 17 | render( | 17 | render( |
| 18 | :file => @page.valid_template, | 18 | :template => @page.valid_template, |
| 19 | :layout => true | 19 | :layout => true |
| 20 | ) | 20 | ) |
| 21 | else | 21 | else |
| 22 | render( | 22 | render( |
| 23 | :file => File.join(RAILS_ROOT, 'public', '404.html'), | 23 | :file => Rails.root.join('public', '404.html').to_s, |
| 24 | :status => 404 | 24 | :status => 404, |
| 25 | :layout => false | ||
| 25 | ) | 26 | ) |
| 26 | end | 27 | end |
| 27 | 28 | ||
| 28 | end | 29 | end |
| 29 | 30 | ||
| 30 | def render_gallery | 31 | def render_gallery |
| @@ -32,13 +33,17 @@ class ContentController < ApplicationController | |||
| 32 | @images = @page.assets.images | 33 | @images = @page.assets.images |
| 33 | render :file => "content/gallery" | 34 | render :file => "content/gallery" |
| 34 | else | 35 | else |
| 35 | render :nothing => true, :status => 404 | 36 | head :not_found |
| 36 | end | 37 | end |
| 37 | end | 38 | end |
| 38 | 39 | ||
| 39 | private | 40 | private |
| 40 | def find_page | 41 | def find_page |
| 41 | path = params[:page_path].join('/') | 42 | path = params[:page_path].is_a?(Array) ? params[:page_path].join('/') : params[:page_path] |
| 42 | @page = Node.find_page(path) | 43 | if path =~ /^[a-zA-Z\:\/\/\.\-\d_]+$/ |
| 44 | @page = Node.find_page(path) | ||
| 45 | else | ||
| 46 | @page = nil | ||
| 47 | end | ||
| 43 | end | 48 | end |
| 44 | end | 49 | end |
diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 805e941..7695e9b 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb | |||
| @@ -2,7 +2,7 @@ class EventsController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | layout 'admin' | 7 | layout 'admin' |
| 8 | 8 | ||
| @@ -47,7 +47,7 @@ class EventsController < ApplicationController | |||
| 47 | # POST /events | 47 | # POST /events |
| 48 | # POST /events.xml | 48 | # POST /events.xml |
| 49 | def create | 49 | def create |
| 50 | @event = Event.new(params[:event]) | 50 | @event = Event.new(event_params) |
| 51 | 51 | ||
| 52 | respond_to do |format| | 52 | respond_to do |format| |
| 53 | if @event.save | 53 | if @event.save |
| @@ -67,7 +67,7 @@ class EventsController < ApplicationController | |||
| 67 | @event = Event.find(params[:id]) | 67 | @event = Event.find(params[:id]) |
| 68 | 68 | ||
| 69 | respond_to do |format| | 69 | respond_to do |format| |
| 70 | if @event.update_attributes(params[:event]) | 70 | if @event.update(event_params) |
| 71 | flash[:notice] = 'Event was successfully updated.' | 71 | flash[:notice] = 'Event was successfully updated.' |
| 72 | format.html { redirect_to(edit_node_path(@event.node)) } | 72 | format.html { redirect_to(edit_node_path(@event.node)) } |
| 73 | format.xml { head :ok } | 73 | format.xml { head :ok } |
| @@ -89,4 +89,10 @@ class EventsController < ApplicationController | |||
| 89 | format.xml { head :ok } | 89 | format.xml { head :ok } |
| 90 | end | 90 | end |
| 91 | end | 91 | end |
| 92 | |||
| 93 | private | ||
| 94 | |||
| 95 | def event_params | ||
| 96 | params.require(:event).permit(:start_time, :end_time, :rrule, :custom_rrule, :allday, :url, :latitude, :longitude, :node_id, :location) | ||
| 97 | end | ||
| 92 | end | 98 | end |
diff --git a/app/controllers/menu_items_controller.rb b/app/controllers/menu_items_controller.rb index 808da15..1b1eb59 100644 --- a/app/controllers/menu_items_controller.rb +++ b/app/controllers/menu_items_controller.rb | |||
| @@ -2,23 +2,23 @@ class MenuItemsController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | layout 'admin' | 7 | layout 'admin' |
| 8 | 8 | ||
| 9 | def index | 9 | def index |
| 10 | @menu_items = MenuItem.all(:order => "position ASC") | 10 | @menu_items = MenuItem.order("position ASC").all |
| 11 | end | 11 | end |
| 12 | 12 | ||
| 13 | def show | 13 | def show |
| 14 | end | 14 | end |
| 15 | 15 | ||
| 16 | def new | 16 | def new |
| 17 | @menu_item = MenuItem.new params[:menu_item] | 17 | @menu_item = MenuItem.new menu_item_params |
| 18 | end | 18 | end |
| 19 | 19 | ||
| 20 | def create | 20 | def create |
| 21 | if MenuItem.create( params[:menu_item] ) | 21 | if MenuItem.create( menu_item_params ) |
| 22 | redirect_to menu_items_path | 22 | redirect_to menu_items_path |
| 23 | else | 23 | else |
| 24 | render :new | 24 | render :new |
| @@ -32,7 +32,7 @@ class MenuItemsController < ApplicationController | |||
| 32 | def update | 32 | def update |
| 33 | @menu_item = MenuItem.find( params[:id] ) | 33 | @menu_item = MenuItem.find( params[:id] ) |
| 34 | 34 | ||
| 35 | if @menu_item.update_attributes( params[:menu_item] ) | 35 | if @menu_item.update( menu_item_params ) |
| 36 | redirect_to menu_items_path | 36 | redirect_to menu_items_path |
| 37 | else | 37 | else |
| 38 | render :edit | 38 | render :edit |
| @@ -48,10 +48,15 @@ class MenuItemsController < ApplicationController | |||
| 48 | def sort | 48 | def sort |
| 49 | params[:menu_items].each_with_index do |item_id, index| | 49 | params[:menu_items].each_with_index do |item_id, index| |
| 50 | menu_item = MenuItem.find(item_id) | 50 | menu_item = MenuItem.find(item_id) |
| 51 | menu_item.update_attributes(:position => index + 1) | 51 | menu_item.update(:position => index + 1) |
| 52 | end | 52 | end |
| 53 | 53 | ||
| 54 | render :nothing => true | 54 | head :ok |
| 55 | end | 55 | end |
| 56 | 56 | ||
| 57 | private | ||
| 58 | |||
| 59 | def menu_item_params | ||
| 60 | params.require(:menu_item).permit(:node_id, :path, :position, :type, :type_id) | ||
| 61 | end | ||
| 57 | end | 62 | end |
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb index 4f72744..494887d 100644 --- a/app/controllers/nodes_controller.rb +++ b/app/controllers/nodes_controller.rb | |||
| @@ -4,8 +4,8 @@ class NodesController < ApplicationController | |||
| 4 | 4 | ||
| 5 | layout 'admin' | 5 | layout 'admin' |
| 6 | 6 | ||
| 7 | before_filter :login_required | 7 | before_action :login_required |
| 8 | before_filter :find_node, :only => [ | 8 | before_action :find_node, :only => [ |
| 9 | :show, | 9 | :show, |
| 10 | :edit, | 10 | :edit, |
| 11 | :update, | 11 | :update, |
| @@ -15,16 +15,17 @@ class NodesController < ApplicationController | |||
| 15 | ] | 15 | ] |
| 16 | 16 | ||
| 17 | def index | 17 | def index |
| 18 | @nodes = Node.root.descendants.paginate( | 18 | @nodes = Node.root.descendants.includes(:head, :draft) |
| 19 | :include => [:head, :draft], | 19 | .order('id DESC') |
| 20 | :page => params[:page], | 20 | .paginate(:page => params[:page], :per_page => 25) |
| 21 | :per_page => 25, | ||
| 22 | :order => 'id DESC' | ||
| 23 | ) | ||
| 24 | end | 21 | end |
| 25 | 22 | ||
| 26 | def new | 23 | def new |
| 27 | @node = Node.new params[:node] | 24 | @node = Node.new node_params |
| 25 | if params.has_key?(:parent_id) | ||
| 26 | @parent_id = params[:parent_id] | ||
| 27 | @parent_name = Node.find(@parent_id).title | ||
| 28 | end | ||
| 28 | end | 29 | end |
| 29 | 30 | ||
| 30 | def create | 31 | def create |
| @@ -33,9 +34,16 @@ class NodesController < ApplicationController | |||
| 33 | @node = Node.new | 34 | @node = Node.new |
| 34 | @node.parent_id = find_parent | 35 | @node.parent_id = find_parent |
| 35 | @node.slug = params[:title].parameterize.to_s | 36 | @node.slug = params[:title].parameterize.to_s |
| 36 | 37 | ||
| 37 | if @node.save | 38 | if @node.save |
| 38 | @node.draft.update_attributes(:title => params[:title]) | 39 | @node.draft.update(:title => params[:title]) |
| 40 | case params[:kind] | ||
| 41 | when "update" | ||
| 42 | @node.draft.tag_list.add("update") | ||
| 43 | when "press_release" | ||
| 44 | @node.draft.tag_list.add("update", "pressemitteilung") | ||
| 45 | end | ||
| 46 | @node.draft.save! | ||
| 39 | redirect_to(edit_node_path(@node)) | 47 | redirect_to(edit_node_path(@node)) |
| 40 | else | 48 | else |
| 41 | render :new | 49 | render :new |
| @@ -44,6 +52,7 @@ class NodesController < ApplicationController | |||
| 44 | 52 | ||
| 45 | def show | 53 | def show |
| 46 | node = Node.find(params[:id]) | 54 | node = Node.find(params[:id]) |
| 55 | node.wipe_draft! | ||
| 47 | @page = node.draft || node.head | 56 | @page = node.draft || node.head |
| 48 | end | 57 | end |
| 49 | 58 | ||
| @@ -53,7 +62,7 @@ class NodesController < ApplicationController | |||
| 53 | rescue LockedByAnotherUser => e | 62 | rescue LockedByAnotherUser => e |
| 54 | flash[:error] = e.message | 63 | flash[:error] = e.message |
| 55 | if request.referer | 64 | if request.referer |
| 56 | redirect_to :back | 65 | redirect_to request.referer || node_path(@node) |
| 57 | else | 66 | else |
| 58 | redirect_to node_path(@node) | 67 | redirect_to node_path(@node) |
| 59 | end | 68 | end |
| @@ -61,10 +70,10 @@ class NodesController < ApplicationController | |||
| 61 | end | 70 | end |
| 62 | 71 | ||
| 63 | def update | 72 | def update |
| 64 | @node.update_attributes(params[:node]) | 73 | @node.update(node_params) |
| 65 | @draft = @node.find_or_create_draft current_user | 74 | @draft = @node.find_or_create_draft current_user |
| 66 | @draft.tag_list = params[:tag_list] | 75 | @draft.tag_list = params[:tag_list] |
| 67 | if @draft.update_attributes( params[:page] ) | 76 | if @draft.update( page_params ) |
| 68 | flash[:notice] = "Draft has been saved: #{Time.now}" | 77 | flash[:notice] = "Draft has been saved: #{Time.now}" |
| 69 | respond_to do |format| | 78 | respond_to do |format| |
| 70 | format.html { redirect_to edit_node_path(@node) } | 79 | format.html { redirect_to edit_node_path(@node) } |
| @@ -82,7 +91,7 @@ class NodesController < ApplicationController | |||
| 82 | def publish | 91 | def publish |
| 83 | @node.publish_draft! | 92 | @node.publish_draft! |
| 84 | flash[:notice] = "Draft has been published" | 93 | flash[:notice] = "Draft has been published" |
| 85 | redirect_to node_path | 94 | redirect_to node_path(@node) |
| 86 | end | 95 | end |
| 87 | 96 | ||
| 88 | def unlock | 97 | def unlock |
| @@ -96,6 +105,14 @@ class NodesController < ApplicationController | |||
| 96 | end | 105 | end |
| 97 | 106 | ||
| 98 | private | 107 | private |
| 108 | |||
| 109 | def node_params | ||
| 110 | params.fetch(:node, {}).permit(:slug, :parent_id, :staged_slug, :staged_parent_id) | ||
| 111 | end | ||
| 112 | |||
| 113 | def page_params | ||
| 114 | params.fetch(:page, {}).permit(:title, :abstract, :body, :template_name, :published_at, :user_id) | ||
| 115 | end | ||
| 99 | 116 | ||
| 100 | def find_node | 117 | def find_node |
| 101 | @node = Node.find(params[:id]) | 118 | @node = Node.find(params[:id]) |
| @@ -107,6 +124,8 @@ class NodesController < ApplicationController | |||
| 107 | Node.root.id | 124 | Node.root.id |
| 108 | when "update" | 125 | when "update" |
| 109 | Update.find_or_create_parent.id | 126 | Update.find_or_create_parent.id |
| 127 | when "press_release" | ||
| 128 | Update.find_or_create_parent.id | ||
| 110 | when "generic" | 129 | when "generic" |
| 111 | if params[:parent_id] && Node.find(params[:parent_id]) | 130 | if params[:parent_id] && Node.find(params[:parent_id]) |
| 112 | params[:parent_id] | 131 | params[:parent_id] |
diff --git a/app/controllers/occurrences_controller.rb b/app/controllers/occurrences_controller.rb index 751be40..0f30ce3 100644 --- a/app/controllers/occurrences_controller.rb +++ b/app/controllers/occurrences_controller.rb | |||
| @@ -2,7 +2,7 @@ class OccurrencesController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | # GET /occurrences | 7 | # GET /occurrences |
| 8 | # GET /occurrences.xml | 8 | # GET /occurrences.xml |
| @@ -45,7 +45,7 @@ class OccurrencesController < ApplicationController | |||
| 45 | # POST /occurrences | 45 | # POST /occurrences |
| 46 | # POST /occurrences.xml | 46 | # POST /occurrences.xml |
| 47 | def create | 47 | def create |
| 48 | @occurrence = Occurrence.new(params[:occurrence]) | 48 | @occurrence = Occurrence.new(occurrence_params) |
| 49 | 49 | ||
| 50 | respond_to do |format| | 50 | respond_to do |format| |
| 51 | if @occurrence.save | 51 | if @occurrence.save |
| @@ -65,7 +65,7 @@ class OccurrencesController < ApplicationController | |||
| 65 | @occurrence = Occurrence.find(params[:id]) | 65 | @occurrence = Occurrence.find(params[:id]) |
| 66 | 66 | ||
| 67 | respond_to do |format| | 67 | respond_to do |format| |
| 68 | if @occurrence.update_attributes(params[:occurrence]) | 68 | if @occurrence.update(occurrence_params) |
| 69 | flash[:notice] = 'Occurrence was successfully updated.' | 69 | flash[:notice] = 'Occurrence was successfully updated.' |
| 70 | format.html { redirect_to(@occurrence) } | 70 | format.html { redirect_to(@occurrence) } |
| 71 | format.xml { head :ok } | 71 | format.xml { head :ok } |
| @@ -87,4 +87,11 @@ class OccurrencesController < ApplicationController | |||
| 87 | format.xml { head :ok } | 87 | format.xml { head :ok } |
| 88 | end | 88 | end |
| 89 | end | 89 | end |
| 90 | |||
| 91 | private | ||
| 92 | |||
| 93 | def occurrence_params | ||
| 94 | params.require(:occurrence).permit(:start_time, :end_time, :node_id, :event_id) | ||
| 95 | end | ||
| 96 | |||
| 90 | end | 97 | end |
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index a684327..2d08dea 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb | |||
| @@ -2,26 +2,24 @@ class PagesController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | def preview | 7 | def preview |
| 8 | @page = Page.find(params[:id]) | 8 | @page = Page.find(params[:id]) |
| 9 | 9 | ||
| 10 | if @page | 10 | if @page |
| 11 | template = @page.valid_template | 11 | template = @page.valid_template |
| 12 | render( | 12 | render( |
| 13 | :file => template, | 13 | template: template, |
| 14 | :layout => "application" | 14 | layout: "application" |
| 15 | ) | 15 | ) |
| 16 | end | 16 | end |
| 17 | |||
| 18 | end | 17 | end |
| 19 | 18 | ||
| 20 | |||
| 21 | def sort_images | 19 | def sort_images |
| 22 | page = Page.find(params[:id]) | 20 | page = Page.find(params[:id]) |
| 23 | page.update_assets(params[:images]) | 21 | page.update_assets(params[:images]) |
| 24 | 22 | ||
| 25 | render :nothing => true, :status => 200 | 23 | head :ok |
| 26 | end | 24 | end |
| 27 | end | 25 | end |
diff --git a/app/controllers/revisions_controller.rb b/app/controllers/revisions_controller.rb index 05e8acc..42d667e 100644 --- a/app/controllers/revisions_controller.rb +++ b/app/controllers/revisions_controller.rb | |||
| @@ -2,12 +2,13 @@ class RevisionsController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | 6 | ||
| 7 | layout 'admin' | 7 | layout 'admin' |
| 8 | 8 | ||
| 9 | def index | 9 | def index |
| 10 | @node = Node.find(params[:node_id]) | 10 | @node = Node.find(params[:node_id]) |
| 11 | @pages = @node.pages.all | ||
| 11 | end | 12 | end |
| 12 | 13 | ||
| 13 | def diff | 14 | def diff |
diff --git a/app/controllers/rss_controller.rb b/app/controllers/rss_controller.rb index acffc0e..4b47218 100644 --- a/app/controllers/rss_controller.rb +++ b/app/controllers/rss_controller.rb | |||
| @@ -1,19 +1,21 @@ | |||
| 1 | class RssController < ApplicationController | 1 | class RssController < ApplicationController |
| 2 | 2 | ||
| 3 | before_filter :authenticate, :only => :recent_changes | 3 | before_action :authenticate, :only => :recent_changes |
| 4 | before_filter :get_host | 4 | before_action :get_host |
| 5 | 5 | ||
| 6 | def updates | 6 | def updates |
| 7 | expires_in 31.minutes, :public => true | 7 | expires_in 31.minutes, :public => true |
| 8 | 8 | ||
| 9 | I18n.locale = :de | 9 | I18n.locale = :de |
| 10 | 10 | ||
| 11 | @items = Page.heads.find_tagged_with( | 11 | @items = Page.heads |
| 12 | "update", | 12 | .joins("JOIN taggings ON taggings.taggable_id = pages.id |
| 13 | :order => "published_at DESC", | 13 | AND taggings.taggable_type = 'Page' |
| 14 | :limit => 20 | 14 | AND taggings.context = 'tags'") |
| 15 | ) | 15 | .joins("JOIN tags ON tags.id = taggings.tag_id") |
| 16 | 16 | .where("LOWER(tags.name) = ?", "update") | |
| 17 | .order("published_at DESC").limit(20) | ||
| 18 | |||
| 17 | respond_to do |format| | 19 | respond_to do |format| |
| 18 | format.xml {} | 20 | format.xml {} |
| 19 | format.rdf {} | 21 | format.rdf {} |
| @@ -21,13 +23,9 @@ class RssController < ApplicationController | |||
| 21 | end | 23 | end |
| 22 | 24 | ||
| 23 | def recent_changes | 25 | def recent_changes |
| 24 | @items = Page.all( | 26 | @items = Page.where( |
| 25 | :limit => 20, | 27 | "updated_at < ? AND updated_at > ?", Time.now, Time.now - 14.days |
| 26 | :order => "updated_at desc", | 28 | ).limit(20).order("updated_at desc") |
| 27 | :conditions => [ | ||
| 28 | "updated_at < ? AND updated_at > ?", Time.now, Time.now-14.days | ||
| 29 | ] | ||
| 30 | ) | ||
| 31 | end | 29 | end |
| 32 | 30 | ||
| 33 | protected | 31 | protected |
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 565cdd4..bf6a029 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb | |||
| @@ -1,33 +1,44 @@ | |||
| 1 | class TagsController < ApplicationController | 1 | class TagsController < ApplicationController |
| 2 | 2 | ||
| 3 | # Public | 3 | # Public |
| 4 | 4 | ||
| 5 | def index | 5 | def index |
| 6 | @page = Page.new :title => "Tags" | 6 | @page = Page.new :title => "Tags" |
| 7 | 7 | ||
| 8 | @tags = Tag.all(:limit => 500) | 8 | @tags = Tag.limit(500).all |
| 9 | end | 9 | end |
| 10 | 10 | ||
| 11 | def show | 11 | def show |
| 12 | @tag = Tag.find_by_name(params[:id]) | 12 | tag_name = params[:id] |
| 13 | 13 | ||
| 14 | @tag = @tag ? @tag.name : params[:id] | 14 | if tag_name.match(/^[a-zA-Z0-9_\w\s\-\.\']+$/) |
| 15 | 15 | @tag = ActsAsTaggableOn::Tag.find_by_name(tag_name) | |
| 16 | @page = Page.new | 16 | @tag = @tag ? @tag.name : tag_name |
| 17 | @page = Page.new | ||
| 17 | 18 | ||
| 18 | params[:page] = ( params[:page].is_a?(Fixnum) ? params[:page] : 1 ) | 19 | params[:page] = (params[:page].is_a?(Integer) ? params[:page] : 1) |
| 19 | 20 | ||
| 20 | @pages = Page.heads.paginate( | 21 | @pages = Page.heads |
| 21 | Page.find_options_for_find_tagged_with(@tag).merge( | 22 | .joins("JOIN taggings ON taggings.taggable_id = pages.id |
| 22 | :order => 'published_at DESC', | 23 | AND taggings.taggable_type = 'Page' |
| 23 | :page=>params[:page], | 24 | AND taggings.context = 'tags'") |
| 24 | :per_page => 23 | 25 | .joins("JOIN tags ON tags.id = taggings.tag_id") |
| 25 | ) | 26 | .where("LOWER(tags.name) = ?", @tag.downcase) |
| 26 | ) | 27 | .order('published_at DESC') |
| 27 | 28 | .paginate( | |
| 28 | respond_to do |format| | 29 | :page => params[:page], |
| 29 | format.html {} | 30 | :per_page => 23 |
| 31 | ) | ||
| 32 | |||
| 33 | respond_to do |format| | ||
| 34 | format.html {} | ||
| 35 | end | ||
| 36 | else | ||
| 37 | respond_to do |format| | ||
| 38 | format.html { head :bad_request } | ||
| 39 | end | ||
| 30 | end | 40 | end |
| 41 | |||
| 31 | end | 42 | end |
| 32 | 43 | ||
| 33 | end | 44 | end |
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 87df678..98fd534 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb | |||
| @@ -2,24 +2,24 @@ class UsersController < ApplicationController | |||
| 2 | 2 | ||
| 3 | # Private | 3 | # Private |
| 4 | 4 | ||
| 5 | before_filter :login_required | 5 | before_action :login_required |
| 6 | before_filter :find_user, :only => [:show, :edit, :update, :destroy] | 6 | before_action :find_user, :only => [:show, :edit, :update, :destroy] |
| 7 | before_filter :verify_status, :except => [:index, :show] | 7 | before_action :verify_status, :except => [:index, :show] |
| 8 | 8 | ||
| 9 | layout 'admin' | 9 | layout 'admin' |
| 10 | 10 | ||
| 11 | def index | 11 | def index |
| 12 | @users = User.all(:order => "login ASC").group_by do |user| | 12 | @users = User.order("login ASC").all.group_by do |user| |
| 13 | user.admin? ? :admin : :user | 13 | user.admin? ? :admin : :user |
| 14 | end | 14 | end |
| 15 | end | 15 | end |
| 16 | 16 | ||
| 17 | def new | 17 | def new |
| 18 | @user = User.new( params[:user] ) | 18 | @user = User.new |
| 19 | end | 19 | end |
| 20 | 20 | ||
| 21 | def create | 21 | def create |
| 22 | @user = User.new params[:user] | 22 | @user = User.new user_params |
| 23 | 23 | ||
| 24 | if @user.save | 24 | if @user.save |
| 25 | flash[:notice] = "User created #{@user.login}" | 25 | flash[:notice] = "User created #{@user.login}" |
| @@ -33,8 +33,10 @@ class UsersController < ApplicationController | |||
| 33 | end | 33 | end |
| 34 | 34 | ||
| 35 | def update | 35 | def update |
| 36 | params[:user].delete(:admin) unless current_user.is_admin? | 36 | permitted = user_params |
| 37 | if @user.update_attributes(params[:user]) | 37 | permitted.delete(:admin) unless current_user.is_admin? |
| 38 | |||
| 39 | if @user.update(permitted) | ||
| 38 | flash[:notice] = "Updated user #{@user.login}" | 40 | flash[:notice] = "Updated user #{@user.login}" |
| 39 | redirect_to user_path(@user) | 41 | redirect_to user_path(@user) |
| 40 | else | 42 | else |
| @@ -51,6 +53,11 @@ class UsersController < ApplicationController | |||
| 51 | end | 53 | end |
| 52 | 54 | ||
| 53 | private | 55 | private |
| 56 | |||
| 57 | def user_params | ||
| 58 | params.fetch(:user, {}).permit(:login, :email, :password, :password_confirmation, :admin) | ||
| 59 | end | ||
| 60 | |||
| 54 | def find_user | 61 | def find_user |
| 55 | @user = User.find(params[:id]) | 62 | @user = User.find(params[:id]) |
| 56 | end | 63 | end |
diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index da8945e..e5c3d5c 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | module AdminHelper | 1 | module AdminHelper |
| 2 | 2 | ||
| 3 | def language_selector | 3 | def language_selector |
| 4 | case I18n.locale | 4 | case I18n.locale |
| 5 | when :de | 5 | when :de |
| 6 | link_to 'English', url_for(:overwrite_params => {:locale => :en}) | 6 | link_to raw('<span class="inactive">English</span>'), url_for(params.permit!.to_h.merge('locale' => 'en')) |
| 7 | when :en | 7 | when :en |
| 8 | link_to 'Deutsch', url_for(:overwrite_params => {:locale => :de}) | 8 | link_to raw('<span class="inactive">Deutsch</span>'), url_for(params.permit!.to_h.merge('locale' => 'de')) |
| 9 | end | 9 | end |
| 10 | end | 10 | end |
| 11 | end \ No newline at end of file | 11 | end |
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 22a7940..0be66e9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | # Methods added to this helper will be available to all templates in the application. | 1 | # Methods added to this helper will be available to all templates in the application. |
| 2 | module ApplicationHelper | 2 | module ApplicationHelper |
| 3 | def form_error_messages(form_object) | ||
| 4 | object = form_object.is_a?(ActionView::Helpers::FormBuilder) ? form_object.object : form_object | ||
| 5 | return "" unless object && object.errors.any? | ||
| 6 | content_tag(:div, :class => "error_messages") do | ||
| 7 | content_tag(:ul) do | ||
| 8 | object.errors.full_messages.map do |msg| | ||
| 9 | content_tag(:li, msg) | ||
| 10 | end.join.html_safe | ||
| 11 | end | ||
| 12 | end | ||
| 13 | end | ||
| 3 | end | 14 | end |
diff --git a/app/helpers/content_helper.rb b/app/helpers/content_helper.rb index d6c96f1..21cc579 100644 --- a/app/helpers/content_helper.rb +++ b/app/helpers/content_helper.rb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | module ContentHelper | 1 | module ContentHelper |
| 2 | 2 | ||
| 3 | def main_menu | 3 | def main_menu |
| 4 | menu_items = MenuItem.all(:order => "position ASC") | 4 | menu_items = MenuItem.order("position ASC").all |
| 5 | render( | 5 | render( |
| 6 | :partial => 'content/main_navigation', | 6 | :partial => 'content/main_navigation', |
| 7 | :locals => {:menu_items => menu_items} | 7 | :locals => {:menu_items => menu_items} |
| @@ -9,13 +9,13 @@ module ContentHelper | |||
| 9 | end | 9 | end |
| 10 | 10 | ||
| 11 | def calendar | 11 | def calendar |
| 12 | occurrences = Occurrence.find_in_range(Time.now, (Time.now+14.days)) | 12 | occurrences = Occurrence.find_in_range(Time.now, (Time.now+6.weeks)) |
| 13 | 13 | ||
| 14 | if occurrences.empty? | 14 | if occurrences.empty? |
| 15 | occurrences = Occurrence.find_next | 15 | occurrences = Occurrence.find_next |
| 16 | end | 16 | end |
| 17 | 17 | ||
| 18 | occurrences = occurrences.reject { |o| o.node.head.nil? } | 18 | occurrences = occurrences.reject { |o| o.node.nil? || o.node.head.nil? } |
| 19 | 19 | ||
| 20 | render( | 20 | render( |
| 21 | :partial => 'content/front_page_calendar', | 21 | :partial => 'content/front_page_calendar', |
| @@ -43,7 +43,7 @@ module ContentHelper | |||
| 43 | # Returns the published_at attribute of a page if it is not nil, otherwise | 43 | # Returns the published_at attribute of a page if it is not nil, otherwise |
| 44 | # it returns the auto-filled value of the created_at attribute | 44 | # it returns the auto-filled value of the created_at attribute |
| 45 | def date_for_page page | 45 | def date_for_page page |
| 46 | page.published_at.to_s(:db) rescue page.created_at.to_s(:db) | 46 | I18n.l(page.published_at, :format => :ccc) rescue I18n.l(page.created_at, :format => :ccc) |
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | def author_for_page page | 49 | def author_for_page page |
| @@ -51,7 +51,7 @@ module ContentHelper | |||
| 51 | end | 51 | end |
| 52 | 52 | ||
| 53 | def page_title | 53 | def page_title |
| 54 | if @page.title && @page.title != "" | 54 | if @page && @page.title && @page.title != "" |
| 55 | "CCC | #{@page.title}" | 55 | "CCC | #{@page.title}" |
| 56 | else | 56 | else |
| 57 | "CCC | Chaos Computer Club" | 57 | "CCC | Chaos Computer Club" |
| @@ -59,41 +59,43 @@ module ContentHelper | |||
| 59 | end | 59 | end |
| 60 | 60 | ||
| 61 | # This method is an output filter for templates. It accepts any kind of text | 61 | # This method is an output filter for templates. It accepts any kind of text |
| 62 | # and checks for an <aggregate /> tag within it. If such a tag is found, its | 62 | # and checks for an [aggregate short code within it. If such a code is found, |
| 63 | # attributes are parsed and converted into parameters for the | 63 | # its # attributes are parsed and converted into parameters for the |
| 64 | # render_collection method. The <aggregate /> tag will then be replaced | 64 | # render_collection method. The [aggregate ] short code will then be replaced |
| 65 | # entirely with the output of the render_collection method. | 65 | # entirely with the output of the render_collection method. |
| 66 | # | 66 | # |
| 67 | # Syntax of the <aggregate /> tag: | 67 | # Syntax of the [aggregate ] short code: |
| 68 | # | 68 | # |
| 69 | # <aggregate | 69 | # [aggregate |
| 70 | # flags="update, pressemitteilung" | 70 | # flags="update, pressemitteilung" |
| 71 | # limit="20" | 71 | # limit="20" |
| 72 | # order_by="published_at" | 72 | # order_by="published_at" |
| 73 | # order_direction="DESC" | 73 | # order_direction="DESC" |
| 74 | # /> | 74 | # ] |
| 75 | def aggregate? content | 75 | def aggregate? content |
| 76 | options = {} | 76 | options = {} |
| 77 | 77 | ||
| 78 | cccms_attributes = ActionView::Base.sanitized_allowed_attributes + ['lang'] | ||
| 79 | |||
| 78 | begin | 80 | begin |
| 79 | if content =~ /<aggregate([^<>]*)>/ | 81 | if content =~ /\[aggregate([^\]]*)\]/ |
| 80 | tag = $~.to_s | 82 | tag = $~.to_s |
| 81 | matched_data = $1.scan(/\w+\=\"[a-zA-Z\s\/_\d,]*\"/) | 83 | matched_data = $1.scan(/\w+\="[a-zA-Z\s\/_\d,.=]*"/) |
| 82 | 84 | ||
| 83 | matched_data.each do |data| | 85 | matched_data.each do |data| |
| 84 | splitted_data = data.split("=") | 86 | splitted_data = data.split("=", 2) |
| 85 | options[splitted_data[0].to_sym] = splitted_data[1].gsub(/\"/, "") | 87 | options[splitted_data[0].to_sym] = splitted_data[1].gsub(/"/, "") |
| 86 | end | 88 | end |
| 87 | 89 | ||
| 88 | options[:partial] = select_partial( options[:partial] ) | 90 | options[:partial] = select_partial(options[:partial]) |
| 89 | 91 | ||
| 90 | sanitize( content.sub(tag, render_collection(options)) ) | 92 | sanitize(content.sub(tag, render_collection(options)), :attributes => cccms_attributes) |
| 91 | else | 93 | else |
| 92 | sanitize( content ) | 94 | sanitize(content, :attributes => cccms_attributes) |
| 93 | end | 95 | end |
| 94 | 96 | ||
| 95 | rescue | 97 | rescue |
| 96 | sanitize( content ) | 98 | sanitize(content, :attributes => cccms_attributes) |
| 97 | end | 99 | end |
| 98 | end | 100 | end |
| 99 | 101 | ||
| @@ -124,9 +126,7 @@ module ContentHelper | |||
| 124 | # Check if a custom partial exists in the proper location | 126 | # Check if a custom partial exists in the proper location |
| 125 | def partial_exists? partial | 127 | def partial_exists? partial |
| 126 | File.exist?( | 128 | File.exist?( |
| 127 | File.join( | 129 | Rails.root.join('app', 'views', 'custom', 'partials', "_#{partial}.html.erb") |
| 128 | RAILS_ROOT, 'app', 'views', 'custom', 'partials', "_#{partial}.html.erb" | ||
| 129 | ) | ||
| 130 | ) | 130 | ) |
| 131 | end | 131 | end |
| 132 | 132 | ||
diff --git a/app/helpers/link_helper.rb b/app/helpers/link_helper.rb index 1b20e6d..878e8e4 100644 --- a/app/helpers/link_helper.rb +++ b/app/helpers/link_helper.rb | |||
| @@ -1,54 +1,62 @@ | |||
| 1 | module LinkHelper | 1 | module LinkHelper |
| 2 | 2 | ||
| 3 | def content_path_helper path_array | 3 | def content_path_helper path_array |
| 4 | url_for( | 4 | url_for( |
| 5 | :controller => :content, | 5 | :controller => :content, |
| 6 | :action => :render_page, | 6 | :action => :render_page, |
| 7 | :locale => params[:locale] || I18n.locale, | 7 | :locale => (params[:locale] || I18n.locale).to_sym == I18n.default_locale ? nil : (params[:locale] || I18n.locale), |
| 8 | :page_path => path_array | 8 | :page_path => path_array |
| 9 | ) | 9 | ) |
| 10 | end | 10 | end |
| 11 | 11 | ||
| 12 | def content_url_helper path_array | 12 | def content_url_helper path_array |
| 13 | request.protocol + request.host_with_port + content_path_helper(path_array) | 13 | request.protocol + request.host_with_port + content_path_helper(path_array) |
| 14 | end | 14 | end |
| 15 | 15 | ||
| 16 | def link_to_path title, path, html_options = {} | 16 | def link_to_path title, path, html_options = {} |
| 17 | return "" if path.nil? | ||
| 18 | |||
| 17 | if params[:page_path] | 19 | if params[:page_path] |
| 18 | active = (params[:page_path].join("/") == path.sub(/^\//, "")) | 20 | page_path = params[:page_path].is_a?(Array) ? params[:page_path].join("/") : params[:page_path] |
| 21 | active = (page_path == path.sub(/^\//, "")) | ||
| 19 | end | 22 | end |
| 20 | 23 | ||
| 21 | active_class = active ? {:class => 'active'} : {:class => 'inactive'} | 24 | active_class = active ? {:class => 'active'} : {:class => 'inactive'} |
| 22 | |||
| 23 | html_options = html_options.merge(active_class) | 25 | html_options = html_options.merge(active_class) |
| 24 | 26 | locale = (params[:locale] || I18n.locale).to_sym == I18n.default_locale ? nil : (params[:locale] || I18n.locale) | |
| 25 | params[:locale] ||= I18n.locale | 27 | |
| 26 | 28 | link_to( | |
| 27 | link_to( | 29 | title, |
| 28 | title, { | 30 | content_path(path.sub(/^\//, ""), :locale => locale), |
| 29 | :controller => :content, | ||
| 30 | :action => :render_page, | ||
| 31 | :locale => params[:locale], | ||
| 32 | :page_path => (path.sub(/^\//, "").split("/") rescue "") | ||
| 33 | }, | ||
| 34 | html_options | 31 | html_options |
| 35 | ) | 32 | ) |
| 36 | end | 33 | end |
| 37 | 34 | ||
| 38 | def selected? controller_name | 35 | def selected? controller_name |
| 39 | if params[:controller] == controller_name | 36 | if params[:controller] == controller_name |
| 40 | return :class => "selected" | 37 | return :class => "selected" |
| 41 | end | 38 | end |
| 42 | end | 39 | end |
| 43 | 40 | ||
| 44 | def unlock_link | 41 | def unlock_link |
| 45 | message = "Are you sure you want to unlock?\n" + | 42 | message = "Are you sure you want to unlock?\n" \ |
| 46 | "Locked by #{@node.lock_owner.login}\n" + | 43 | "Locked by #{@node.lock_owner.login}\n" \ |
| 47 | "Last modified #{@page.updated_at.to_s(:db)}" | 44 | "Last modified #{@page.updated_at.to_fs(:db)}" |
| 48 | 45 | button_to 'Unlock', unlock_node_path(@node), | |
| 49 | link_to( | 46 | method: :put, |
| 50 | 'Unlock', unlock_node_path(@node), :method => :put, :confirm => message | 47 | form: { data: { confirm: message } } |
| 48 | end | ||
| 49 | |||
| 50 | def content_path(page_path = nil, options = {}) | ||
| 51 | if page_path.is_a?(Hash) | ||
| 52 | options = page_path | ||
| 53 | page_path = options.delete(:page_path) | ||
| 54 | end | ||
| 55 | locale = options[:locale] || params[:locale] || I18n.locale | ||
| 56 | options[:locale] = (locale.to_sym == I18n.default_locale) ? nil : locale | ||
| 57 | Rails.application.routes.url_helpers.content_path( | ||
| 58 | Array(page_path).join("/").sub(/^\//, ""), | ||
| 59 | options | ||
| 51 | ) | 60 | ) |
| 52 | end | 61 | end |
| 53 | 62 | end | |
| 54 | end \ No newline at end of file | ||
diff --git a/app/helpers/nodes_helper.rb b/app/helpers/nodes_helper.rb index d889719..a054a2e 100644 --- a/app/helpers/nodes_helper.rb +++ b/app/helpers/nodes_helper.rb | |||
| @@ -4,6 +4,10 @@ module NodesHelper | |||
| 4 | if node.head | 4 | if node.head |
| 5 | node.head.title | 5 | node.head.title |
| 6 | else | 6 | else |
| 7 | if not node.draft or not node.draft.title | ||
| 8 | logger.error "Missing title in node #{node.id}" | ||
| 9 | return "NO TITLE" | ||
| 10 | end | ||
| 7 | node.draft.title | 11 | node.draft.title |
| 8 | end | 12 | end |
| 9 | end | 13 | end |
| @@ -24,14 +28,20 @@ module NodesHelper | |||
| 24 | def user_list | 28 | def user_list |
| 25 | User.all.map {|u| [u.login, u.id]} | 29 | User.all.map {|u| [u.login, u.id]} |
| 26 | end | 30 | end |
| 27 | 31 | ||
| 28 | def event_information | 32 | def event_information |
| 29 | if @node.event | 33 | if @node.event |
| 30 | "#{@node.event.start_time.to_s(:db)} - #{@node.event.end_time.to_s(:db)} > " \ | 34 | safe_join([ |
| 31 | "#{link_to 'show', event_path(@node.event)} " \ | 35 | "#{@node.event.start_time.to_fs(:db)} - #{@node.event.end_time.to_fs(:db)} > ", |
| 32 | "#{link_to 'edit', edit_event_path(@node.event)}" | 36 | link_to('show', event_path(@node.event)), |
| 37 | ' ', | ||
| 38 | link_to('edit', edit_event_path(@node.event)) | ||
| 39 | ]) | ||
| 33 | else | 40 | else |
| 34 | "no event attached > #{link_to 'add', new_event_path(:node_id => @node.id)}" | 41 | safe_join([ |
| 42 | 'no event attached > ', | ||
| 43 | link_to('add', new_event_path(:node_id => @node.id)) | ||
| 44 | ]) | ||
| 35 | end | 45 | end |
| 36 | end | 46 | end |
| 37 | end | 47 | end |
diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000..10a4cba --- /dev/null +++ b/app/models/application_record.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | class ApplicationRecord < ActiveRecord::Base | ||
| 2 | self.abstract_class = true | ||
| 3 | end | ||
diff --git a/app/models/asset.rb b/app/models/asset.rb index 5bfea76..aca0ee8 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb | |||
| @@ -1,39 +1,12 @@ | |||
| 1 | class Asset < ActiveRecord::Base | 1 | class Asset < ApplicationRecord |
| 2 | |||
| 3 | include FileAttachment | ||
| 2 | 4 | ||
| 3 | has_many :related_assets, :dependent => :destroy | 5 | has_many :related_assets, :dependent => :destroy |
| 4 | has_many :pages, :through => :related_assets | 6 | has_many :pages, :through => :related_assets |
| 5 | 7 | ||
| 6 | has_attached_file( | 8 | scope :images, -> { where(:upload_content_type => ["image/gif", "image/jpeg", "image/png", "image/webp"]) } |
| 7 | :upload, | 9 | scope :documents, -> { where(:upload_content_type => ["application/pdf", "text/plain", "text/rtf"]) } |
| 8 | :styles => { | 10 | scope :audio, -> { where(:upload_content_type => ["audio/mpeg", "audio/x-m4a", "audio/wav", "audio/x-wav"]) } |
| 9 | :medium => "300x300", | 11 | |
| 10 | :thumb => "100x100", | ||
| 11 | :headline => "460x250#" | ||
| 12 | } | ||
| 13 | ) | ||
| 14 | |||
| 15 | named_scope :images, :conditions => { | ||
| 16 | :upload_content_type => [ | ||
| 17 | "image/gif", | ||
| 18 | "image/jpeg", | ||
| 19 | "image/png" | ||
| 20 | ] | ||
| 21 | } | ||
| 22 | |||
| 23 | named_scope :documents, :conditions => { | ||
| 24 | :upload_content_type => [ | ||
| 25 | "application/pdf", | ||
| 26 | "text/plain", | ||
| 27 | "text/rtf" | ||
| 28 | ] | ||
| 29 | } | ||
| 30 | |||
| 31 | named_scope :audio, :conditions => { | ||
| 32 | :upload_content_type => [ | ||
| 33 | "audio/mpeg", | ||
| 34 | "audio/x-m4a", | ||
| 35 | "audio/wav", | ||
| 36 | "audio/x-wav" | ||
| 37 | ] | ||
| 38 | } | ||
| 39 | end | 12 | end |
diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb new file mode 100644 index 0000000..0e99fa2 --- /dev/null +++ b/app/models/concerns/file_attachment.rb | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | # FileAttachment — minimal drop-in replacement for Paperclip's has_attached_file. | ||
| 2 | # | ||
| 3 | # Provides the same interface used throughout this codebase: | ||
| 4 | # asset.upload.url -> "/system/uploads/:id/original/:filename" | ||
| 5 | # asset.upload.url(:thumb) -> "/system/uploads/:id/thumb/:filename" | ||
| 6 | # asset.upload.content_type -> string | ||
| 7 | # asset.upload.size -> integer (bytes) | ||
| 8 | # | ||
| 9 | # Files are stored at: | ||
| 10 | # Rails.root/public/system/uploads/:id/:style/:filename | ||
| 11 | # | ||
| 12 | # Image variants are generated via ImageMagick (convert) on upload. | ||
| 13 | # Non-image files get only an original, no variants. | ||
| 14 | # | ||
| 15 | # To replace an asset: assign a new file to asset.upload= and save. | ||
| 16 | # The filename is fixed on first upload and preserved on replacement, | ||
| 17 | # keeping all public URLs stable. | ||
| 18 | # | ||
| 19 | # Future: if more sophisticated asset management is needed (versioning, | ||
| 20 | # S3, on-demand resizing), replace this module and keep the interface. | ||
| 21 | |||
| 22 | module FileAttachment | ||
| 23 | extend ActiveSupport::Concern | ||
| 24 | |||
| 25 | STYLES = { | ||
| 26 | medium: { geometry: "300x300>", format: nil }, | ||
| 27 | thumb: { geometry: "100x100>", format: nil }, | ||
| 28 | headline: { geometry: "460x250!", format: nil } | ||
| 29 | }.freeze | ||
| 30 | |||
| 31 | IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze | ||
| 32 | VECTOR_CONTENT_TYPES = %w[image/svg+xml].freeze | ||
| 33 | DISPLAYABLE_AS_IMAGE = IMAGE_CONTENT_TYPES + VECTOR_CONTENT_TYPES | ||
| 34 | |||
| 35 | included do | ||
| 36 | attr_reader :upload | ||
| 37 | |||
| 38 | after_initialize :build_upload_proxy | ||
| 39 | after_save :process_upload | ||
| 40 | before_destroy :delete_upload_files | ||
| 41 | end | ||
| 42 | |||
| 43 | def upload=(uploaded_file) | ||
| 44 | return if uploaded_file.blank? | ||
| 45 | @pending_upload = uploaded_file | ||
| 46 | # Populate the database columns immediately so validations can use them | ||
| 47 | self.upload_file_name = sanitize_filename(uploaded_file.original_filename) | ||
| 48 | self.upload_content_type = uploaded_file.content_type.to_s.split(';').first.strip | ||
| 49 | self.upload_file_size = uploaded_file.size | ||
| 50 | self.upload_updated_at = Time.current | ||
| 51 | build_upload_proxy | ||
| 52 | end | ||
| 53 | |||
| 54 | private | ||
| 55 | |||
| 56 | def build_upload_proxy | ||
| 57 | @upload = UploadProxy.new(self) | ||
| 58 | end | ||
| 59 | |||
| 60 | def process_upload | ||
| 61 | return unless @pending_upload | ||
| 62 | uploaded_file = @pending_upload | ||
| 63 | @pending_upload = nil | ||
| 64 | |||
| 65 | old_dir = Rails.root.join("public", "system", "uploads", id.to_s) | ||
| 66 | FileUtils.rm_rf(old_dir) if Dir.exist?(old_dir) | ||
| 67 | |||
| 68 | original_path = file_path(:original) | ||
| 69 | FileUtils.mkdir_p(File.dirname(original_path)) | ||
| 70 | FileUtils.cp(uploaded_file.tempfile.path, original_path) | ||
| 71 | |||
| 72 | if IMAGE_CONTENT_TYPES.include?(upload_content_type) | ||
| 73 | generate_variants(original_path) | ||
| 74 | elsif VECTOR_CONTENT_TYPES.include?(upload_content_type) | ||
| 75 | generate_svg_variants(original_path) | ||
| 76 | end | ||
| 77 | end | ||
| 78 | |||
| 79 | def generate_variants(original_path) | ||
| 80 | STYLES.each do |style, options| | ||
| 81 | dest_path = file_path(style) | ||
| 82 | FileUtils.mkdir_p(File.dirname(dest_path)) | ||
| 83 | system("magick", original_path, "-resize", options[:geometry], dest_path) | ||
| 84 | end | ||
| 85 | end | ||
| 86 | |||
| 87 | def generate_svg_variants(original_path) | ||
| 88 | STYLES.each do |style, _| | ||
| 89 | dest_path = file_path(style) | ||
| 90 | FileUtils.mkdir_p(File.dirname(dest_path)) | ||
| 91 | FileUtils.cp(original_path, dest_path) | ||
| 92 | end | ||
| 93 | end | ||
| 94 | |||
| 95 | def delete_upload_files | ||
| 96 | dir = Rails.root.join("public", "system", "uploads", id.to_s) | ||
| 97 | FileUtils.rm_rf(dir) if Dir.exist?(dir) | ||
| 98 | end | ||
| 99 | |||
| 100 | def file_path(style) | ||
| 101 | Rails.root.join( | ||
| 102 | "public", "system", "uploads", | ||
| 103 | id.to_s, style.to_s, upload_file_name | ||
| 104 | ).to_s | ||
| 105 | end | ||
| 106 | |||
| 107 | def sanitize_filename(filename) | ||
| 108 | File.basename(filename).gsub(/[^\w\.\-]/, '_') | ||
| 109 | end | ||
| 110 | |||
| 111 | # Proxy object returned by asset.upload, providing the Paperclip-compatible | ||
| 112 | # interface used in views: .url, .url(:style), .content_type, .size | ||
| 113 | class UploadProxy | ||
| 114 | def initialize(record) | ||
| 115 | @record = record | ||
| 116 | end | ||
| 117 | |||
| 118 | def url(style = :original) | ||
| 119 | return "" if @record.upload_file_name.blank? | ||
| 120 | "/system/uploads/#{@record.id}/#{style}/#{@record.upload_file_name}" | ||
| 121 | end | ||
| 122 | |||
| 123 | def content_type | ||
| 124 | @record.upload_content_type.to_s | ||
| 125 | end | ||
| 126 | |||
| 127 | def size | ||
| 128 | @record.upload_file_size.to_i | ||
| 129 | end | ||
| 130 | |||
| 131 | def present? | ||
| 132 | @record.upload_file_name.present? | ||
| 133 | end | ||
| 134 | |||
| 135 | def blank? | ||
| 136 | !present? | ||
| 137 | end | ||
| 138 | end | ||
| 139 | end | ||
diff --git a/app/models/event.rb b/app/models/event.rb index 60b8521..94a22e3 100644 --- a/app/models/event.rb +++ b/app/models/event.rb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | class Event < ActiveRecord::Base | 1 | class Event < ApplicationRecord |
| 2 | 2 | ||
| 3 | # Associations | 3 | # Associations |
| 4 | 4 | ||
| @@ -12,14 +12,12 @@ class Event < ActiveRecord::Base | |||
| 12 | # Instance Methods | 12 | # Instance Methods |
| 13 | 13 | ||
| 14 | def occurrences_in_range start_time, end_time | 14 | def occurrences_in_range start_time, end_time |
| 15 | self.occurrences.find( | 15 | self.occurrences.where( |
| 16 | :all, :conditions => [ | 16 | "start_time > ? AND end_time < ?", |
| 17 | "start_time > ? AND end_time < ?", | 17 | start_time, end_time |
| 18 | start_time, end_time | ||
| 19 | ] | ||
| 20 | ) | 18 | ) |
| 21 | end | 19 | end |
| 22 | 20 | ||
| 23 | private | 21 | private |
| 24 | def generate_occurences | 22 | def generate_occurences |
| 25 | Occurrence.generate self | 23 | Occurrence.generate self |
diff --git a/app/models/locked_by_another_user.rb b/app/models/locked_by_another_user.rb new file mode 100644 index 0000000..6f9e272 --- /dev/null +++ b/app/models/locked_by_another_user.rb | |||
| @@ -0,0 +1 @@ | |||
| class LockedByAnotherUser < StandardError; end | |||
diff --git a/app/models/menu_item.rb b/app/models/menu_item.rb index 054e7ee..7769b7f 100644 --- a/app/models/menu_item.rb +++ b/app/models/menu_item.rb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | class MenuItem < ActiveRecord::Base | 1 | class MenuItem < ApplicationRecord |
| 2 | 2 | ||
| 3 | default_scope :conditions => {:type => "MenuItem"} | 3 | default_scope -> { where(:type => "MenuItem") } |
| 4 | 4 | ||
| 5 | translates :title | 5 | translates :title |
| 6 | 6 | ||
| @@ -24,5 +24,5 @@ end | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | class FeaturedArticle < MenuItem | 26 | class FeaturedArticle < MenuItem |
| 27 | default_scope :conditions => {:type => "FeaturedArticle"} | 27 | default_scope -> { where(:type => "FeaturedArticle") } |
| 28 | end \ No newline at end of file | 28 | end |
diff --git a/app/models/node.rb b/app/models/node.rb index 6c11fed..92ecc12 100644 --- a/app/models/node.rb +++ b/app/models/node.rb | |||
| @@ -1,14 +1,14 @@ | |||
| 1 | class Node < ActiveRecord::Base | 1 | class Node < ApplicationRecord |
| 2 | # Mixins and Plugins | 2 | # Mixins and Plugins |
| 3 | acts_as_nested_set | 3 | acts_as_nested_set |
| 4 | 4 | ||
| 5 | # Associations | 5 | # Associations |
| 6 | has_many :pages, :order => "revision ASC" | 6 | has_many :pages, -> { order("revision ASC") }, :dependent => :destroy |
| 7 | belongs_to :head, :class_name => "Page", :foreign_key => :head_id | 7 | belongs_to :head, :class_name => "Page", :foreign_key => :head_id, :dependent => :destroy, optional: true |
| 8 | belongs_to :draft, :class_name => "Page", :foreign_key => :draft_id | 8 | belongs_to :draft, :class_name => "Page", :foreign_key => :draft_id, :dependent => :destroy, optional: true |
| 9 | has_many :permissions | 9 | has_many :permissions, :dependent => :destroy |
| 10 | has_one :event | 10 | has_one :event, :dependent => :destroy |
| 11 | belongs_to :lock_owner, :class_name => "User", :foreign_key => :locking_user_id | 11 | belongs_to :lock_owner, :class_name => "User", :foreign_key => :locking_user_id, optional: true |
| 12 | 12 | ||
| 13 | # Callbacks | 13 | # Callbacks |
| 14 | after_create :initialize_empty_page | 14 | after_create :initialize_empty_page |
| @@ -16,20 +16,20 @@ class Node < ActiveRecord::Base | |||
| 16 | after_save :update_unique_names_of_children | 16 | after_save :update_unique_names_of_children |
| 17 | 17 | ||
| 18 | # Validations | 18 | # Validations |
| 19 | validates_length_of :slug, :within => 1..255, :unless => "parent_id.nil?" | 19 | validates_length_of :slug, :within => 1..255, :unless => -> { parent_id.nil? } |
| 20 | validates_presence_of :slug, :unless => "parent_id.nil?" | 20 | validates_presence_of :slug, :unless => -> { parent_id.nil? } |
| 21 | validates_uniqueness_of :slug, :scope => :parent_id, :unless => "parent_id.nil?" | 21 | validates_uniqueness_of :slug, :scope => :parent_id, :unless => -> { parent_id.nil? } |
| 22 | validates_presence_of :parent_id, :unless => "Node.root.nil?" | 22 | validates_presence_of :parent_id, :unless => -> { Node.root.nil? } |
| 23 | 23 | ||
| 24 | validate :borders # This should never ever happen. | 24 | validate :borders # This should never ever happen. |
| 25 | 25 | ||
| 26 | # Index for Fulltext Search | 26 | # Index for Fulltext Search |
| 27 | define_index do | 27 | # define_index do |
| 28 | indexes head.translations.title | 28 | # indexes head.translations.title |
| 29 | indexes slug | 29 | # indexes slug |
| 30 | indexes unique_name | 30 | # indexes unique_name |
| 31 | indexes head.translations.body | 31 | # indexes head.translations.body |
| 32 | end | 32 | # end |
| 33 | 33 | ||
| 34 | # Class methods | 34 | # Class methods |
| 35 | 35 | ||
| @@ -39,8 +39,8 @@ class Node < ActiveRecord::Base | |||
| 39 | # revision with -1. It raises an Argument error if the revision is not a | 39 | # revision with -1. It raises an Argument error if the revision is not a |
| 40 | # Fixnum | 40 | # Fixnum |
| 41 | def self.find_page path, revision = -1 | 41 | def self.find_page path, revision = -1 |
| 42 | unless revision.class == Fixnum | 42 | unless revision.is_a?(Integer) |
| 43 | raise ArgumentError, "revision must be a Fixnum" | 43 | raise ArgumentError, "revision must be a Integer" |
| 44 | end | 44 | end |
| 45 | 45 | ||
| 46 | node = Node.find_by_unique_name(path) | 46 | node = Node.find_by_unique_name(path) |
| @@ -60,6 +60,7 @@ class Node < ActiveRecord::Base | |||
| 60 | # Instance Methods | 60 | # Instance Methods |
| 61 | 61 | ||
| 62 | def find_or_create_draft current_user | 62 | def find_or_create_draft current_user |
| 63 | self.wipe_draft! | ||
| 63 | if draft && self.lock_owner == current_user | 64 | if draft && self.lock_owner == current_user |
| 64 | draft | 65 | draft |
| 65 | elsif draft && self.lock_owner.nil? | 66 | elsif draft && self.lock_owner.nil? |
| @@ -72,7 +73,7 @@ class Node < ActiveRecord::Base | |||
| 72 | raise( | 73 | raise( |
| 73 | LockedByAnotherUser, | 74 | LockedByAnotherUser, |
| 74 | "Page is locked by another user who is working on it! " \ | 75 | "Page is locked by another user who is working on it! " \ |
| 75 | "Last modification: #{draft.updated_at.to_s(:db)}" | 76 | "Last modification: #{draft.updated_at.to_fs(:db)}" |
| 76 | ) | 77 | ) |
| 77 | else | 78 | else |
| 78 | lock_for! current_user | 79 | lock_for! current_user |
| @@ -94,25 +95,55 @@ class Node < ActiveRecord::Base | |||
| 94 | end | 95 | end |
| 95 | 96 | ||
| 96 | def publish_draft! | 97 | def publish_draft! |
| 98 | # Return nil if nothing to publish and no staged changes | ||
| 99 | return nil unless self.draft || staged_slug || staged_parent_id | ||
| 100 | |||
| 97 | if self.draft | 101 | if self.draft |
| 98 | self.head = self.draft | 102 | self.head = self.draft |
| 99 | self.head.published_at ||= Time.now | 103 | self.head.published_at ||= Time.now |
| 100 | self.head.save! | 104 | self.head.save! |
| 101 | |||
| 102 | self.draft = nil | 105 | self.draft = nil |
| 106 | end | ||
| 103 | 107 | ||
| 104 | if staged_slug && (staged_slug != slug) | 108 | if staged_slug && (staged_slug != slug) |
| 105 | self.slug = staged_slug | 109 | self.slug = staged_slug |
| 106 | end | 110 | self.staged_slug = nil |
| 111 | end | ||
| 107 | 112 | ||
| 108 | if staged_parent_id && (staged_parent_id != parent_id) | 113 | if staged_parent_id && (staged_parent_id != parent_id) |
| 109 | self.parent_id = staged_parent_id | 114 | new_parent = Node.find(staged_parent_id) |
| 115 | self.staged_parent_id = nil | ||
| 116 | self.save! | ||
| 117 | self.move_to_child_of(new_parent) | ||
| 118 | else | ||
| 119 | unless self.save | ||
| 120 | raise ActiveRecord::RecordInvalid.new(self) | ||
| 110 | end | 121 | end |
| 122 | end | ||
| 111 | 123 | ||
| 112 | self.save! | 124 | self.reload |
| 125 | self.update_unique_name | ||
| 126 | self.send(:update_unique_names_of_children) | ||
| 127 | self.unlock! | ||
| 128 | self | ||
| 129 | end | ||
| 130 | |||
| 131 | # removes a draft and the lock if it is older than a day and still | ||
| 132 | # identical to head | ||
| 133 | def wipe_draft! | ||
| 134 | unless self.draft | ||
| 113 | self.unlock! | 135 | self.unlock! |
| 114 | self | 136 | return |
| 115 | end | 137 | end |
| 138 | return unless self.head | ||
| 139 | return unless self.draft.updated_at < 1.day.ago | ||
| 140 | return if self.head.has_changes_to? self.draft | ||
| 141 | |||
| 142 | self.draft.destroy | ||
| 143 | self.draft_id = nil | ||
| 144 | self.unlock! | ||
| 145 | self.save! | ||
| 146 | self.reload | ||
| 116 | end | 147 | end |
| 117 | 148 | ||
| 118 | def restore_revision! revision | 149 | def restore_revision! revision |
| @@ -126,7 +157,7 @@ class Node < ActiveRecord::Base | |||
| 126 | 157 | ||
| 127 | # returns an array with all parts of a unique_name rather than a string | 158 | # returns an array with all parts of a unique_name rather than a string |
| 128 | def unique_path | 159 | def unique_path |
| 129 | unique_name.split("/") rescue [unique_name] | 160 | unique_name.to_s.split("/") |
| 130 | end | 161 | end |
| 131 | 162 | ||
| 132 | # returns array with pages up to root excluding root | 163 | # returns array with pages up to root excluding root |
| @@ -180,6 +211,15 @@ class Node < ActiveRecord::Base | |||
| 180 | self.created_at < new_id_format_date ? unique_path : id | 211 | self.created_at < new_id_format_date ? unique_path : id |
| 181 | end | 212 | end |
| 182 | 213 | ||
| 214 | # Full-text search across all locale translations using PostgreSQL tsvector. | ||
| 215 | # Uses 'simple' dictionary (no stemming, no stopwords) so queries work | ||
| 216 | # across German and English content without language detection. | ||
| 217 | def self.search(term, _ = {}) | ||
| 218 | joins(head: :translations) | ||
| 219 | .where("page_translations.search_vector @@ plainto_tsquery('simple', ?)", term) | ||
| 220 | .distinct | ||
| 221 | end | ||
| 222 | |||
| 183 | protected | 223 | protected |
| 184 | def lock_for! current_user | 224 | def lock_for! current_user |
| 185 | self.lock_owner = current_user | 225 | self.lock_owner = current_user |
| @@ -208,8 +248,12 @@ class Node < ActiveRecord::Base | |||
| 208 | # Hopefully until no childrens occur | 248 | # Hopefully until no childrens occur |
| 209 | def update_unique_names_of_children | 249 | def update_unique_names_of_children |
| 210 | unless root? | 250 | unless root? |
| 211 | self.descendants.each do |descendant| | 251 | # Use parent_id-based traversal instead of lft/rgt descendants |
| 212 | descendant.update_unique_name | 252 | # due to awesome_nested_set not refreshing parent lft/rgt in memory |
| 253 | Node.where(:parent_id => self.id).each do |child| | ||
| 254 | child.reload | ||
| 255 | child.update_unique_name | ||
| 256 | child.send(:update_unique_names_of_children) | ||
| 213 | end | 257 | end |
| 214 | end | 258 | end |
| 215 | end | 259 | end |
| @@ -220,7 +264,3 @@ class Node < ActiveRecord::Base | |||
| 220 | end | 264 | end |
| 221 | end | 265 | end |
| 222 | end | 266 | end |
| 223 | |||
| 224 | class LockedByAnotherUser < StandardError; end | ||
| 225 | |||
| 226 | |||
diff --git a/app/models/occurrence.rb b/app/models/occurrence.rb index 591e1e0..3baf447 100644 --- a/app/models/occurrence.rb +++ b/app/models/occurrence.rb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # TODO Make a gem out of the c wrapper | 1 | # TODO Make a gem out of the c wrapper |
| 2 | require 'chaos_calendar' | 2 | require 'chaos_calendar' |
| 3 | 3 | ||
| 4 | class Occurrence < ActiveRecord::Base | 4 | class Occurrence < ApplicationRecord |
| 5 | 5 | ||
| 6 | # Associations | 6 | # Associations |
| 7 | 7 | ||
| @@ -11,29 +11,22 @@ class Occurrence < ActiveRecord::Base | |||
| 11 | # Class Methods | 11 | # Class Methods |
| 12 | 12 | ||
| 13 | def self.find_in_range start_time, end_time | 13 | def self.find_in_range start_time, end_time |
| 14 | find( | 14 | includes(:node) |
| 15 | :all, | 15 | .where("start_time > ? AND end_time < ?", start_time, end_time) |
| 16 | :include => :node, | 16 | .order("start_time") |
| 17 | :conditions => [ | ||
| 18 | "start_time > ? AND end_time < ?", start_time, end_time | ||
| 19 | ] | ||
| 20 | ) | ||
| 21 | end | 17 | end |
| 22 | 18 | ||
| 23 | def self.find_next | 19 | def self.find_next |
| 24 | find( | 20 | includes(:node) |
| 25 | :all, | 21 | .where("start_time > ?", Time.now) |
| 26 | :limit => 1, | 22 | .limit(1) |
| 27 | :include => :node, | ||
| 28 | :conditions => ["start_time > ?", Time.now] | ||
| 29 | ) | ||
| 30 | end | 23 | end |
| 31 | 24 | ||
| 32 | # Deletes all Occurrences which belong to the given event. Afterwards a few | 25 | # Deletes all Occurrences which belong to the given event. Afterwards a few |
| 33 | # variables are set to save repetitive queries. The occurrences of the given | 26 | # variables are set to save repetitive queries. The occurrences of the given |
| 34 | # event are then calculated and created. | 27 | # event are then calculated and created. |
| 35 | def self.generate event | 28 | def self.generate event |
| 36 | self.delete_all(:event_id => event.id) | 29 | self.where(:event_id => event.id).delete_all |
| 37 | 30 | ||
| 38 | node = event.node | 31 | node = event.node |
| 39 | duration = (event.end_time - event.start_time) | 32 | duration = (event.end_time - event.start_time) |
diff --git a/app/models/page.rb b/app/models/page.rb index c5da386..e6baf20 100644 --- a/app/models/page.rb +++ b/app/models/page.rb | |||
| @@ -1,25 +1,9 @@ | |||
| 1 | require 'xml' | 1 | require 'xml' |
| 2 | 2 | ||
| 3 | class Page < ActiveRecord::Base | 3 | class Page < ApplicationRecord |
| 4 | 4 | ||
| 5 | PUBLIC_TEMPLATE_PATH = File.join(%w(custom page_templates public)) | 5 | PUBLIC_TEMPLATE_PATH = File.join(%w(custom page_templates public)) |
| 6 | FULL_PUBLIC_TEMPLATE_PATH = File.join(RAILS_ROOT, 'app', 'views', PUBLIC_TEMPLATE_PATH) | 6 | FULL_PUBLIC_TEMPLATE_PATH = Rails.root.join('app', 'views', PUBLIC_TEMPLATE_PATH) |
| 7 | |||
| 8 | # named scopes | ||
| 9 | |||
| 10 | named_scope( | ||
| 11 | :drafts, | ||
| 12 | :joins => :node, | ||
| 13 | :include => [:translations], | ||
| 14 | :conditions => ["nodes.draft_id = pages.id"] | ||
| 15 | ) | ||
| 16 | |||
| 17 | named_scope( | ||
| 18 | :heads, | ||
| 19 | :joins => :node, | ||
| 20 | :include => [:translations], | ||
| 21 | :conditions => ["nodes.head_id = pages.id"] | ||
| 22 | ) | ||
| 23 | 7 | ||
| 24 | # Mixins and Plugins | 8 | # Mixins and Plugins |
| 25 | acts_as_taggable | 9 | acts_as_taggable |
| @@ -28,20 +12,21 @@ class Page < ActiveRecord::Base | |||
| 28 | translates :title, :abstract, :body # Globalize2 | 12 | translates :title, :abstract, :body # Globalize2 |
| 29 | 13 | ||
| 30 | # Associations | 14 | # Associations |
| 31 | belongs_to :node | 15 | belongs_to :node, optional: true |
| 32 | belongs_to :user | 16 | belongs_to :user, optional: true |
| 33 | belongs_to :editor, :class_name => "User" | 17 | belongs_to :editor, :class_name => "User", optional: true |
| 34 | has_many :related_assets | 18 | has_many :related_assets |
| 35 | has_many :assets, :through => :related_assets, :order => "position ASC" | 19 | has_many :assets, -> { order("position ASC") }, :through => :related_assets |
| 20 | |||
| 21 | # Named scopes | ||
| 22 | scope :drafts, -> { joins(:node).includes(:translations).where("nodes.draft_id = pages.id") } | ||
| 23 | scope :heads, -> { joins(:node).includes(:translations).where("nodes.head_id = pages.id") } | ||
| 36 | 24 | ||
| 37 | # Filter | 25 | # Filter |
| 38 | before_create :set_page_title | 26 | before_create :set_page_title |
| 39 | before_create :set_template | 27 | before_create :set_template |
| 40 | before_save :rewrite_links_in_body | 28 | before_save :rewrite_links_in_body |
| 41 | 29 | ||
| 42 | # Security | ||
| 43 | attr_accessible :title, :abstract, :body, :template_name, :published_at, :user_id | ||
| 44 | |||
| 45 | # Class Methods | 30 | # Class Methods |
| 46 | 31 | ||
| 47 | # This method is most likely called from the ContentHelper.render_collection | 32 | # This method is most likely called from the ContentHelper.render_collection |
| @@ -51,8 +36,8 @@ class Page < ActiveRecord::Base | |||
| 51 | # partially or entirely overwritten by the options hash. Afterwards the merged | 36 | # partially or entirely overwritten by the options hash. Afterwards the merged |
| 52 | # parameters are used to query the DB for Pages matching these parameters. | 37 | # parameters are used to query the DB for Pages matching these parameters. |
| 53 | # The aggregation only takes published pages into account. | 38 | # The aggregation only takes published pages into account. |
| 54 | def self.aggregate options, page=1 | ||
| 55 | 39 | ||
| 40 | def self.aggregate options, page=1 | ||
| 56 | defaults = { | 41 | defaults = { |
| 57 | :tags => "", | 42 | :tags => "", |
| 58 | :limit => 25, | 43 | :limit => 25, |
| @@ -62,15 +47,24 @@ class Page < ActiveRecord::Base | |||
| 62 | 47 | ||
| 63 | options = defaults.merge options | 48 | options = defaults.merge options |
| 64 | 49 | ||
| 65 | Page.heads.paginate( | 50 | scope = Page.heads |
| 66 | find_options_for_find_tagged_with( | 51 | unless options[:tags].blank? |
| 67 | options[:tags].gsub(/\s/, ","), :match_all => true | 52 | tag_names = options[:tags].gsub(/\s/, ",").split(",").map(&:strip).map(&:downcase).uniq.reject(&:blank?) |
| 68 | ).merge( | 53 | |
| 69 | :page => page, | 54 | unless tag_names.empty? |
| 70 | :per_page => options[:limit], | 55 | scope = scope |
| 71 | :order => "#{options[:order_by]} #{options[:order_direction]}" | 56 | .joins("JOIN taggings ON taggings.taggable_id = pages.id |
| 72 | ) | 57 | AND taggings.taggable_type = 'Page' |
| 73 | ) | 58 | AND taggings.context = 'tags'") |
| 59 | .joins("JOIN tags ON tags.id = taggings.tag_id") | ||
| 60 | .where("LOWER(tags.name) IN (?)", tag_names) | ||
| 61 | .group("pages.id") | ||
| 62 | .having("COUNT(DISTINCT tags.id) = ?", tag_names.length) | ||
| 63 | end | ||
| 64 | end | ||
| 65 | |||
| 66 | scope.order("#{options[:order_by]} #{options[:order_direction]}") | ||
| 67 | .paginate(:page => page, :per_page => options[:limit]) | ||
| 74 | end | 68 | end |
| 75 | 69 | ||
| 76 | def self.custom_templates | 70 | def self.custom_templates |
| @@ -89,11 +83,24 @@ class Page < ActiveRecord::Base | |||
| 89 | # outdated_translations? for more information. | 83 | # outdated_translations? for more information. |
| 90 | # Takes :locale => <locale> and :delta_time => 12.hours as options | 84 | # Takes :locale => <locale> and :delta_time => 12.hours as options |
| 91 | def self.find_with_outdated_translations options = {} | 85 | def self.find_with_outdated_translations options = {} |
| 92 | Page.all(:include => :translations).select do |page| | 86 | Page.includes(:translations).select do |page| |
| 93 | page.outdated_translations? options | 87 | page.outdated_translations? options |
| 94 | end | 88 | end |
| 95 | end | 89 | end |
| 96 | 90 | ||
| 91 | # Is used to compare a node's head with the node's draft | ||
| 92 | |||
| 93 | def has_changes_to? draft | ||
| 94 | return true unless node == draft.node | ||
| 95 | return true unless assets == draft.assets | ||
| 96 | return true unless tag_list == draft.tag_list | ||
| 97 | return true unless template_name == draft.template_name | ||
| 98 | return true unless translated_locales.sort_by(&:to_s) == draft.translated_locales.sort_by(&:to_s) | ||
| 99 | changed = false | ||
| 100 | translated_locales.each { |locale| I18n.with_locale(locale) { changed = true unless title == draft.title && abstract == draft.abstract && body == draft.body } } | ||
| 101 | return changed | ||
| 102 | end | ||
| 103 | |||
| 97 | # Instance Methods | 104 | # Instance Methods |
| 98 | 105 | ||
| 99 | def public_template_path | 106 | def public_template_path |
| @@ -105,7 +112,7 @@ class Page < ActiveRecord::Base | |||
| 105 | end | 112 | end |
| 106 | 113 | ||
| 107 | def template_exists? | 114 | def template_exists? |
| 108 | File.exists? "#{full_public_template_path}.html.erb" | 115 | File.exist? "#{full_public_template_path}.html.erb" |
| 109 | end | 116 | end |
| 110 | 117 | ||
| 111 | def valid_template | 118 | def valid_template |
| @@ -136,7 +143,7 @@ class Page < ActiveRecord::Base | |||
| 136 | 143 | ||
| 137 | # Clone translated attributes | 144 | # Clone translated attributes |
| 138 | page.translations.each do |translation| | 145 | page.translations.each do |translation| |
| 139 | self.translations.create!(translation.attributes) | 146 | self.translations.create!(translation.attributes.except("id", "page_id", "created_at", "updated_at")) |
| 140 | end | 147 | end |
| 141 | 148 | ||
| 142 | # Clone asset references | 149 | # Clone asset references |
| @@ -149,6 +156,16 @@ class Page < ActiveRecord::Base | |||
| 149 | published_at.nil? ? true : published_at < Time.now | 156 | published_at.nil? ? true : published_at < Time.now |
| 150 | end | 157 | end |
| 151 | 158 | ||
| 159 | def effective_lang | ||
| 160 | if translated_locales.empty? | ||
| 161 | return 'de' | ||
| 162 | elsif translated_locales.include?(I18n.locale) | ||
| 163 | return I18n.locale | ||
| 164 | else | ||
| 165 | return translated_locales.first | ||
| 166 | end | ||
| 167 | end | ||
| 168 | |||
| 152 | # Returns true if a page has translations where one of them is significantly | 169 | # Returns true if a page has translations where one of them is significantly |
| 153 | # older than the other. | 170 | # older than the other. |
| 154 | # Takes the I18n.default locale and a second :locale to test if the | 171 | # Takes the I18n.default locale and a second :locale to test if the |
| @@ -165,8 +182,8 @@ class Page < ActiveRecord::Base | |||
| 165 | 182 | ||
| 166 | translations = self.translations | 183 | translations = self.translations |
| 167 | 184 | ||
| 168 | default = *(translations.select {|x| x.locale == I18n.default_locale}) | 185 | default = translations.find {|x| x.locale.to_s == I18n.default_locale.to_s } |
| 169 | custom = *(translations.select {|x| x.locale == options[:locale]}) | 186 | custom = translations.find {|x| x.locale.to_s == options[:locale].to_s } |
| 170 | 187 | ||
| 171 | if translations.size > 1 && default && custom | 188 | if translations.size > 1 && default && custom |
| 172 | difference = (default.updated_at - custom.updated_at).to_i.abs | 189 | difference = (default.updated_at - custom.updated_at).to_i.abs |
| @@ -215,11 +232,6 @@ class Page < ActiveRecord::Base | |||
| 215 | links = links.reject { |l| l[:href] =~ /system\/uploads/ } | 232 | links = links.reject { |l| l[:href] =~ /system\/uploads/ } |
| 216 | locales = I18n.available_locales.reject {|l| l == :root} | 233 | locales = I18n.available_locales.reject {|l| l == :root} |
| 217 | 234 | ||
| 218 | if xml_doc.find("//p/aggregate")[0] | ||
| 219 | aggregate_tags = xml_doc.find("//aggregate") | ||
| 220 | aggregate_tags[0].parent.replace_with aggregate_tags[0] | ||
| 221 | end | ||
| 222 | |||
| 223 | links.each do |link| | 235 | links.each do |link| |
| 224 | unless locales.include? link[:href].slice(1,2).to_sym | 236 | unless locales.include? link[:href].slice(1,2).to_sym |
| 225 | unless link[:href] =~ /sytem\/uploads/ | 237 | unless link[:href] =~ /sytem\/uploads/ |
| @@ -238,4 +250,4 @@ class Page < ActiveRecord::Base | |||
| 238 | end | 250 | end |
| 239 | end | 251 | end |
| 240 | 252 | ||
| 241 | end \ No newline at end of file | 253 | end |
diff --git a/app/models/permission.rb b/app/models/permission.rb index 438538e..1383a4b 100644 --- a/app/models/permission.rb +++ b/app/models/permission.rb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | class Permission < ActiveRecord::Base | 1 | class Permission < ApplicationRecord |
| 2 | # Validations | 2 | # Validations |
| 3 | validates_presence_of :user_id, :node_id, :granted | 3 | validates_presence_of :user_id, :node_id, :granted |
| 4 | validates_inclusion_of :granted, :in => [true, false] | 4 | validates_inclusion_of :granted, :in => [true, false] |
| @@ -8,6 +8,6 @@ class Permission < ActiveRecord::Base | |||
| 8 | belongs_to :node | 8 | belongs_to :node |
| 9 | 9 | ||
| 10 | # Named scopes | 10 | # Named scopes |
| 11 | named_scope :for_node, lambda { |node| { :conditions => ['node_id = ?', (node.is_a? Node ? node.id : node)] } } | 11 | scope :for_node, ->(node) { where('node_id = ?', (node.is_a?(Node) ? node.id : node)) } |
| 12 | named_scope :for_user, lambda { |user| { :conditions => ['user_id = ?', (user.is_a? User ? user.id : user)] } } | 12 | scope :for_user, ->(user) { where('user_id = ?', (user.is_a?(User) ? user.id : user)) } |
| 13 | end | 13 | end |
diff --git a/app/models/related_asset.rb b/app/models/related_asset.rb index af09420..8f16460 100644 --- a/app/models/related_asset.rb +++ b/app/models/related_asset.rb | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | class RelatedAsset < ActiveRecord::Base | 1 | class RelatedAsset < ApplicationRecord |
| 2 | belongs_to :page | 2 | belongs_to :page |
| 3 | belongs_to :asset | 3 | belongs_to :asset |
| 4 | 4 | ||
| 5 | acts_as_list :scope => :page_id | 5 | acts_as_list :scope => :page_id |
| 6 | 6 | ||
| 7 | default_scope :order => "position ASC" | 7 | default_scope -> { order("position ASC") } |
| 8 | end \ No newline at end of file | 8 | end |
diff --git a/app/models/user.rb b/app/models/user.rb index ce5503f..92ac33a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | require 'digest/sha1' | 1 | require 'digest/sha1' |
| 2 | 2 | ||
| 3 | class User < ActiveRecord::Base | 3 | class User < ApplicationRecord |
| 4 | # Mixins and Plugins | 4 | # Mixins and Plugins |
| 5 | include Authentication | 5 | include Authentication |
| 6 | include Authentication::ByPassword | 6 | include Authentication::ByPassword |
| @@ -21,8 +21,6 @@ class User < ActiveRecord::Base | |||
| 21 | validates_format_of :email, :with => Authentication.email_regex, | 21 | validates_format_of :email, :with => Authentication.email_regex, |
| 22 | :message => Authentication.bad_email_message | 22 | :message => Authentication.bad_email_message |
| 23 | 23 | ||
| 24 | attr_accessible :login, :email, :password, :password_confirmation, :admin | ||
| 25 | |||
| 26 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. | 24 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. |
| 27 | def self.authenticate(login, password) | 25 | def self.authenticate(login, password) |
| 28 | return nil if login.blank? || password.blank? | 26 | return nil if login.blank? || password.blank? |
diff --git a/app/views/admin/_drafts.html.erb b/app/views/admin/_drafts.html.erb index 58b946b..a35b0ab 100644 --- a/app/views/admin/_drafts.html.erb +++ b/app/views/admin/_drafts.html.erb | |||
| @@ -17,9 +17,9 @@ | |||
| 17 | <td class="actions"> | 17 | <td class="actions"> |
| 18 | <%= link_to 'Show', node_path(draft.node) %> | 18 | <%= link_to 'Show', node_path(draft.node) %> |
| 19 | <%= link_to "Revisions", revision_path(draft.node.id) %> | 19 | <%= link_to "Revisions", revision_path(draft.node.id) %> |
| 20 | <%= link_to "Publish", publish_node_path(draft.node), :method => :put, :confirm => "Do you really want to publish?" %> | 20 | <%= button_to "Publish", publish_node_path(draft.node), method: :put, form: { data: { confirm: "Do you really want to publish?" } } %> |
| 21 | </td> | 21 | </td> |
| 22 | </tr> | 22 | </tr> |
| 23 | <% end %> | 23 | <% end %> |
| 24 | </table> | 24 | </table> |
| 25 | </div> \ No newline at end of file | 25 | </div> |
diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index e8b39ce..6f217eb 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <%= language_selector %> | 1 | <%= language_selector %> |
| 2 | <%= link_to 'Logout', :controller => :sessions, :action => :destroy %> | 2 | <%= button_to 'Logout', logout_path, method: :delete %> |
| 3 | <%= link_to 'Overview', :controller => :admin, :action => 'index' %> | 3 | <%= link_to 'Overview', admin_path %> |
| 4 | <%= link_to 'Nodes', nodes_path, selected?('nodes') %> | 4 | <%= link_to 'Nodes', nodes_path, selected?('nodes') %> |
| 5 | <%= link_to 'Assets', assets_path, selected?('assets') %> | 5 | <%= link_to 'Assets', assets_path, selected?('assets') %> |
| 6 | <%= link_to 'User', users_path, selected?('users') %> | 6 | <%= link_to 'User', users_path, selected?('users') %> |
| 7 | <%= link_to 'Navigation', menu_items_path, selected?('menu_items') %> > \ No newline at end of file | 7 | <%= link_to 'Navigation', menu_items_path, selected?('menu_items') %> > |
diff --git a/app/views/admin/_recent_changes.html.erb b/app/views/admin/_recent_changes.html.erb index 300d088..88b5e93 100644 --- a/app/views/admin/_recent_changes.html.erb +++ b/app/views/admin/_recent_changes.html.erb | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | <td><%= truncated_title_for_node node %></td> | 13 | <td><%= truncated_title_for_node node %></td> |
| 14 | <td><%= node.unique_name %></td> | 14 | <td><%= node.unique_name %></td> |
| 15 | <td><%= node.draft.user.login rescue "" %></td> | 15 | <td><%= node.draft.user.login rescue "" %></td> |
| 16 | <td><%= node.updated_at.to_s(:db) %></td> | 16 | <td><%= node.updated_at.to_fs(:db) %></td> |
| 17 | <td class="actions"> | 17 | <td class="actions"> |
| 18 | <%= link_to 'Show', node_path(node) %> | 18 | <%= link_to 'Show', node_path(node) %> |
| 19 | <%= link_to "Revisions", revision_path(:id => node.id) %> | 19 | <%= link_to "Revisions", revision_path(:id => node.id) %> |
diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb index 526aa88..2741db3 100644 --- a/app/views/admin/index.html.erb +++ b/app/views/admin/index.html.erb | |||
| @@ -1,6 +1,15 @@ | |||
| 1 | <div id="admin_wizard"> | ||
| 2 | <div class="admin_wizard_button"><%= link_to 'Create Update or Pressemitteilung', new_node_path, :only_path => false %></div> | ||
| 3 | <div class="admin_wizard_button"><a href="#" id="admin_wizard_my_work" class="button">Continue my work</a></div> | ||
| 4 | <div class="admin_wizard_button"><a href="#" id="admin_wizard_create_page" class="button">Add a page in the page tree</a></div> | ||
| 5 | <div class="admin_wizard_button"><%= link_to("Upload a new asset", new_asset_path, :only_path => false) %></div> | ||
| 6 | </div> | ||
| 7 | |||
| 1 | <p id="overview_toggle"> | 8 | <p id="overview_toggle"> |
| 2 | <a href="#" id="recent_changes_toggle" class="button">recent changes</a> | 9 | <a href="#" id="recent_changes_toggle" class="button">recent changes</a> |
| 3 | <a href="#" id="current_drafts_toggle" class="button">current drafts</a> | 10 | <a href="#" id="my_work_toggle" class="button">my work</a> |
| 11 | <a href="#" id="current_drafts_toggle" class="button">current drafts (<%= @drafts_count %>)</a> | ||
| 12 | <a href="#" id="admin_sitemap_toggle" class="button">site map</a> | ||
| 4 | </p> | 13 | </p> |
| 5 | 14 | ||
| 6 | <div id="recent_changes_table"> | 15 | <div id="recent_changes_table"> |
| @@ -30,7 +39,41 @@ | |||
| 30 | <%= node.lock_owner.login if node.lock_owner %> | 39 | <%= node.lock_owner.login if node.lock_owner %> |
| 31 | </td> | 40 | </td> |
| 32 | <td> | 41 | <td> |
| 33 | <%= node.draft ? node.draft.revision : node.head.revision %> | 42 | <%= link_to ( node.draft ? node.draft.revision : (node.head ? node.head.revision : "EMPTY" ) ), node_revisions_path(node) %> |
| 43 | </td> | ||
| 44 | </tr> | ||
| 45 | <% end %> | ||
| 46 | </table> | ||
| 47 | </div> | ||
| 48 | |||
| 49 | <div id="my_work_table"> | ||
| 50 | |||
| 51 | <h1>My Work</h1> | ||
| 52 | |||
| 53 | <table class="node_table"> | ||
| 54 | <tr class="header"> | ||
| 55 | <th class="node_id">ID</th> | ||
| 56 | <th class="title">Title</th> | ||
| 57 | <th class="actions">Actions</th> | ||
| 58 | <th class="editor">Locked by</th> | ||
| 59 | <th class="revision">Rev.</th> | ||
| 60 | </tr> | ||
| 61 | <% @mynodes.each do |node| %> | ||
| 62 | <tr class="<%= cycle("even", "odd") %>"> | ||
| 63 | <td class="node_id"><%= node.id %></td> | ||
| 64 | <td class="title"> | ||
| 65 | <h4><%= link_to title_for_node(node), node_path(node) %></h4> | ||
| 66 | <p><%= link_to_path(node.unique_name, node.unique_name) %></p> | ||
| 67 | </td> | ||
| 68 | <td class="actions"> | ||
| 69 | <%= link_to 'show', node_path(node) %> | ||
| 70 | <%= link_to 'Revisions', node_revisions_path(node) %> | ||
| 71 | </td> | ||
| 72 | <td> | ||
| 73 | <%= node.lock_owner.login if node.lock_owner %> | ||
| 74 | </td> | ||
| 75 | <td> | ||
| 76 | <%= link_to ( node.draft ? node.draft.revision : (node.head ? node.head.revision : "EMPTY" ) ), node_revisions_path(node) %> | ||
| 34 | </td> | 77 | </td> |
| 35 | </tr> | 78 | </tr> |
| 36 | <% end %> | 79 | <% end %> |
| @@ -39,7 +82,7 @@ | |||
| 39 | 82 | ||
| 40 | <div id="current_drafts_table"> | 83 | <div id="current_drafts_table"> |
| 41 | 84 | ||
| 42 | <h1>Current Drafts</h1> | 85 | <h1>Current Drafts (<%= @drafts_count %>)</h1> |
| 43 | 86 | ||
| 44 | <table class="node_table"> | 87 | <table class="node_table"> |
| 45 | <tr class="header"> | 88 | <tr class="header"> |
| @@ -64,9 +107,41 @@ | |||
| 64 | <%= node.lock_owner.login if node.lock_owner %> | 107 | <%= node.lock_owner.login if node.lock_owner %> |
| 65 | </td> | 108 | </td> |
| 66 | <td> | 109 | <td> |
| 67 | <%= node.draft ? node.draft.revision : node.head.revision %> | 110 | <%= link_to ( node.draft ? node.draft.revision : (node.head ? node.head.revision : "EMPTY" ) ), node_revisions_path(node) %> |
| 111 | </td> | ||
| 112 | </tr> | ||
| 113 | <% end %> | ||
| 114 | </table> | ||
| 115 | </div> | ||
| 116 | |||
| 117 | <div id="admin_sitemap_table"> | ||
| 118 | |||
| 119 | <h1>Sitemap</h1> | ||
| 120 | |||
| 121 | <table class="node_table"> | ||
| 122 | <tr class="header"> | ||
| 123 | <th class="node_id">ID</th> | ||
| 124 | <th class="title">Title</th> | ||
| 125 | <th class="actions">Actions</th> | ||
| 126 | <th class="editor">Locked by</th> | ||
| 127 | </tr> | ||
| 128 | <% @sitemap.each do |node| %> | ||
| 129 | <% if !node.nil? %> | ||
| 130 | <tr class="<%= cycle("even", "odd") %>"> | ||
| 131 | <td class="node_id" style="padding-left: <%= @sitemap_depth[node.id] * 30 %>px;"><%= node.id %></td> | ||
| 132 | <td class="title" style="padding-left: <%= @sitemap_depth[node.id] * 30 %>px;"> | ||
| 133 | <h4><%= link_to title_for_node(node), node_path(node) %></h4> | ||
| 134 | <p><%= link_to_path(node.unique_name, node.unique_name) %></p> | ||
| 135 | </td> | ||
| 136 | <td class="actions"> | ||
| 137 | <%= link_to 'create subpage', new_node_path(:parent_id => node.id) %> | ||
| 138 | <%= link_to 'Revisions', node_revisions_path(node) %> | ||
| 139 | </td> | ||
| 140 | <td> | ||
| 141 | <%= node.lock_owner.login if node.lock_owner %> | ||
| 68 | </td> | 142 | </td> |
| 69 | </tr> | 143 | </tr> |
| 70 | <% end %> | 144 | <% end %> |
| 145 | <% end %> | ||
| 71 | </table> | 146 | </table> |
| 72 | </div> \ No newline at end of file | 147 | </div> |
diff --git a/app/views/admin/search_results.html.erb b/app/views/admin/search_results.html.erb new file mode 100644 index 0000000..671b665 --- /dev/null +++ b/app/views/admin/search_results.html.erb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | <h1>Search Results</h1> | ||
| 2 | |||
| 3 | <ul> | ||
| 4 | <%- @results.each do |result| %> | ||
| 5 | <li><a href="<%= node_path(result) %>"><%= result.title %></a></li> | ||
| 6 | <% end %> | ||
| 7 | </ul> | ||
diff --git a/app/views/assets/edit.html.erb b/app/views/assets/edit.html.erb index d60db94..f198600 100644 --- a/app/views/assets/edit.html.erb +++ b/app/views/assets/edit.html.erb | |||
| @@ -1,12 +1,24 @@ | |||
| 1 | <h1>Editing asset</h1> | 1 | <h1>Editing asset</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@asset) do |f| %> | 3 | <%= form_for(@asset, html: { multipart: true }) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | |||
| 6 | <% if @asset.upload.present? %> | ||
| 7 | <p> | ||
| 8 | <strong>Current file:</strong> | ||
| 9 | <%= @asset.upload.url %> | ||
| 10 | (<%= number_to_human_size(@asset.upload.size) %>) | ||
| 11 | </p> | ||
| 12 | <% end %> | ||
| 13 | |||
| 14 | <p> | ||
| 15 | <label>Replace file:</label><br> | ||
| 16 | <%= f.file_field :upload %> | ||
| 17 | </p> | ||
| 5 | 18 | ||
| 6 | <p> | 19 | <p> |
| 7 | <%= f.submit 'Update' %> | 20 | <%= f.submit 'Update' %> |
| 8 | </p> | 21 | </p> |
| 9 | <% end %> | 22 | <% end %> |
| 10 | 23 | ||
| 11 | <%= link_to 'Show', @asset %> | | 24 | <%= link_to 'Show', @asset %> | <%= link_to 'Back', assets_path %> |
| 12 | <%= link_to 'Back', assets_path %> \ No newline at end of file | ||
diff --git a/app/views/assets/index.html.erb b/app/views/assets/index.html.erb index fc7c029..51fc486 100644 --- a/app/views/assets/index.html.erb +++ b/app/views/assets/index.html.erb | |||
| @@ -10,12 +10,12 @@ | |||
| 10 | </tr> | 10 | </tr> |
| 11 | <% @assets.each do |asset| %> | 11 | <% @assets.each do |asset| %> |
| 12 | <tr> | 12 | <tr> |
| 13 | <td><%= image_tag asset.upload.url(:thumb) %></td> | 13 | <td><%= image_tag asset.upload.url(:thumb), style: "max-width: 100px; max-height: 100px;" %></td> |
| 14 | <td><%= link_to asset.name, asset.upload.url %></td> | 14 | <td><%= link_to asset.name, asset.upload.url %></td> |
| 15 | <td><%= asset.upload.content_type %></td> | 15 | <td><%= asset.upload.content_type %></td> |
| 16 | <td><%= link_to 'Show', asset %></td> | 16 | <td><%= link_to 'Show', asset %></td> |
| 17 | <td><%= link_to 'Edit', edit_asset_path(asset) %></td> | 17 | <td><%= link_to 'Edit', edit_asset_path(asset) %></td> |
| 18 | <td><%= link_to 'Destroy', asset, :confirm => 'Are you sure?', :method => :delete %></td> | 18 | <td><%= button_to 'Destroy', asset, method: :delete, form: { data: { confirm: 'Are you sure?' } } %></td> |
| 19 | </tr> | 19 | </tr> |
| 20 | <% end %> | 20 | <% end %> |
| 21 | </table> \ No newline at end of file | 21 | </table> |
diff --git a/app/views/assets/new.html.erb b/app/views/assets/new.html.erb index 366488f..6c1310a 100644 --- a/app/views/assets/new.html.erb +++ b/app/views/assets/new.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>New asset</h1> | 1 | <h1>New asset</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@asset, :html => { :multipart => true }) do |f| %> | 3 | <%= form_for(@asset, :html => { :multipart => true }) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :name %><br /> | 7 | <%= f.label :name %><br /> |
| @@ -14,4 +14,4 @@ | |||
| 14 | </p> | 14 | </p> |
| 15 | <% end %> | 15 | <% end %> |
| 16 | 16 | ||
| 17 | <%= link_to 'Back', assets_path %> \ No newline at end of file | 17 | <%= link_to 'Back', assets_path %> |
diff --git a/app/views/assets/show.html.erb b/app/views/assets/show.html.erb index a64987c..694be5a 100644 --- a/app/views/assets/show.html.erb +++ b/app/views/assets/show.html.erb | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | <table> | 6 | <table> |
| 7 | <tr> | 7 | <tr> |
| 8 | <td>Thumbnail</td> | 8 | <td>Thumbnail</td> |
| 9 | <td><%= image_tag @asset.upload.url(:medium) %></td> | 9 | <td><%= image_tag @asset.upload.url(:medium), style: "max-width: 300px; max-height: 300px;" %></td> |
| 10 | </tr> | 10 | </tr> |
| 11 | <tr> | 11 | <tr> |
| 12 | <td>Public Path</td> | 12 | <td>Public Path</td> |
| @@ -20,4 +20,4 @@ | |||
| 20 | <td>Size</td> | 20 | <td>Size</td> |
| 21 | <td><%= "#{@asset.upload.size/1024} KB" %></td> | 21 | <td><%= "#{@asset.upload.size/1024} KB" %></td> |
| 22 | </tr> | 22 | </tr> |
| 23 | </table> \ No newline at end of file | 23 | </table> |
diff --git a/app/views/content/_featured_articles.html.erb b/app/views/content/_featured_articles.html.erb index 75e2e1d..6717c51 100644 --- a/app/views/content/_featured_articles.html.erb +++ b/app/views/content/_featured_articles.html.erb | |||
| @@ -1,31 +1,56 @@ | |||
| 1 | <div id="featured_articles"> | 1 | <div id="featured_articles"> |
| 2 | <h2>Featured</h2> | 2 | <h2>Featured</h2> |
| 3 | |||
| 4 | <!-- %= link_to( | ||
| 5 | image_tag( '34c3-tuwat.1e4e25c.png' ), | ||
| 6 | "https://events.ccc.de/congress/2017/wiki/Main_Page", | ||
| 7 | :id => "34C3_icon", | ||
| 8 | :size => "155x90", | ||
| 9 | :title => "Chaos Communication Congress 2017" | ||
| 10 | )% --> | ||
| 11 | |||
| 3 | <%= link_to( | 12 | <%= link_to( |
| 4 | image_tag( 'chaosradio.png' ), | 13 | '<img src="/images/chaosradio.png" alt="Chaosradio">'.html_safe, |
| 5 | "http://chaosradio.ccc.de/", | 14 | "https://chaosradio.ccc.de/", |
| 6 | :id => "chaosradio_icon", | 15 | :id => "chaosradio_icon", |
| 7 | :title => "Chaosradio" | 16 | :title => "Chaosradio" |
| 8 | )%> | 17 | )%> |
| 9 | 18 | ||
| 10 | <%= link_to( | 19 | <%= link_to( |
| 11 | image_tag( 'ds.png' ), | 20 | '<img src="/images/media-ccc-de-banner.svg" width="155" height="45" alt="Media Dot CCC Dot de">'.html_safe, |
| 12 | "http://ds.ccc.de/", | 21 | "https://media.ccc.de", |
| 22 | :id => "media_ccc_de_icon", | ||
| 23 | :title => "Media Dot CCC Dot de" | ||
| 24 | )%> | ||
| 25 | |||
| 26 | <%= link_to( | ||
| 27 | '<img src="/images/ds.png" alt="Datenschleuder">'.html_safe, | ||
| 28 | "https://ds.ccc.de/", | ||
| 13 | :id => "ds_icon", | 29 | :id => "ds_icon", |
| 14 | :title => "Datenschleuder" | 30 | :title => "Datenschleuder" |
| 15 | )%> | 31 | )%> |
| 16 | 32 | ||
| 17 | <%= link_to( | 33 | <%= link_to( |
| 18 | image_tag( 'events.png' ), | 34 | '<img src="/images/events.png" alt="Events-Blog">'.html_safe, |
| 19 | "http://events.ccc.de/", | 35 | "https://events.ccc.de/", |
| 20 | :id => "events_icon", | 36 | :id => "events_icon", |
| 21 | :title => "Events Blog" | 37 | :title => "Events-Blog" |
| 22 | )%> | 38 | )%> |
| 23 | 39 | ||
| 24 | <%= link_to( | 40 | <%= link_to( |
| 25 | image_tag( 'twitter.png' ), | 41 | '<img src="/images/Fediverse.svg" width="64" height="64" alt="Fediverse">'.html_safe, |
| 26 | "https://twitter.com/chaosupdates", | 42 | "https://social.bau-ha.us/@ccc", |
| 27 | :id => "twitter_icon", | 43 | :rel => 'me', |
| 28 | :title => "Twitter" | 44 | :id => "fediverse_icon", |
| 45 | :title => "Fediverse" | ||
| 29 | )%> | 46 | )%> |
| 47 | |||
| 48 | <%= link_to( | ||
| 49 | '<img src="/images/Bluesky_Logo.svg" width="64" height="64" alt="bsky">'.html_safe, | ||
| 50 | "https://bsky.app/profile/ccc.de", | ||
| 51 | :id => "bluesky_icon", | ||
| 52 | :title => "bsky" | ||
| 53 | )%> | ||
| 54 | |||
| 30 | </div> | 55 | </div> |
| 31 | 56 | ||
diff --git a/app/views/content/_main_navigation.html.erb b/app/views/content/_main_navigation.html.erb index 67d4ecc..2fe8b77 100644 --- a/app/views/content/_main_navigation.html.erb +++ b/app/views/content/_main_navigation.html.erb | |||
| @@ -4,4 +4,4 @@ | |||
| 4 | <li><%= link_to_path item.title, item.path %></li> | 4 | <li><%= link_to_path item.title, item.path %></li> |
| 5 | <% end %> | 5 | <% end %> |
| 6 | </ul> | 6 | </ul> |
| 7 | </div> \ No newline at end of file | 7 | </div> |
diff --git a/app/views/content/_search.html.erb b/app/views/content/_search.html.erb index 9f61042..aa91424 100644 --- a/app/views/content/_search.html.erb +++ b/app/views/content/_search.html.erb | |||
| @@ -1,8 +1,3 @@ | |||
| 1 | <% form_tag search_path, :method => 'get' do %> | 1 | <%= form_tag search_path, :method => 'get' do %> |
| 2 | <table> | 2 | <div><%= text_field_tag :search_term, params[:search_term], :placeholder => 'suchen', :type => 'search' %></div> |
| 3 | <tr> | 3 | <% end %> |
| 4 | <td><%= text_field_tag :search_term, params[:search_term] %></td> | ||
| 5 | <td style="padding-top: 2px"><%= image_submit_tag("search_button.png") %></td> | ||
| 6 | </tr> | ||
| 7 | </table> | ||
| 8 | <% end %> \ No newline at end of file | ||
diff --git a/app/views/content/_tags.html.erb b/app/views/content/_tags.html.erb index d33bc10..f0e7210 100644 --- a/app/views/content/_tags.html.erb +++ b/app/views/content/_tags.html.erb | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | <% unless @page.nil? || @page.tags.empty? %> | ||
| 1 | <div id="tags"> | 2 | <div id="tags"> |
| 2 | <h2>Tags</h2> | 3 | <h2>Tags</h2> |
| 3 | <ul class="teasertext"> | 4 | <ul class="teasertext"> |
| 4 | <% @page.tags.each do |tag| %> | 5 | <% @page.tags.each do |tag| %> |
| 5 | <li><%= link_to tag.name, tag_path(:id => tag.name) %></li> | 6 | <li><%= link_to tag.name, tag_path(tag.name) %></li> |
| 6 | <% end %> | 7 | <% end %> |
| 7 | </ul> | 8 | </ul> |
| 8 | </div> \ No newline at end of file | 9 | </div> |
| 10 | <% end %> | ||
diff --git a/app/views/custom/page_templates/public/no_date_and_author.html.erb b/app/views/custom/page_templates/public/no_date_and_author.html.erb index b019805..fa39e54 100644 --- a/app/views/custom/page_templates/public/no_date_and_author.html.erb +++ b/app/views/custom/page_templates/public/no_date_and_author.html.erb | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | <div class="article"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= @page.title %></h2> | 2 | <h2 class="headline"><%= @page.title %></h2> |
| 3 | <p><%= sanitize( @page.abstract ) %></p> | 3 | <p><%= sanitize( @page.abstract ) %></p> |
| 4 | <div id="headline_image"><%= headline_image %></div> | 4 | <div id="headline_image"><%= headline_image %></div> |
| 5 | <%= aggregate?(@page.body) %> | 5 | <%= aggregate?(@page.body) %> |
| 6 | </div> | 6 | </div> |
| 7 | 7 | ||
| 8 | <%= will_paginate(@content_collection) if @content_collection %> \ No newline at end of file | 8 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/no_date_and_author_with_map.html.erb b/app/views/custom/page_templates/public/no_date_and_author_with_map.html.erb new file mode 100644 index 0000000..6e86edf --- /dev/null +++ b/app/views/custom/page_templates/public/no_date_and_author_with_map.html.erb | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | <div class="article"> | ||
| 2 | <h2 class="headline"><%= @page.title %></h2> | ||
| 3 | <p><%= sanitize( @page.abstract ) %></p> | ||
| 4 | <object data="/system/uploads/327/original/map.svg" type="image/svg+xml"/> | ||
| 5 | <%= aggregate?(@page.body) %> | ||
| 6 | </div> | ||
| 7 | |||
| 8 | <%= will_paginate(@content_collection) if @content_collection %> | ||
diff --git a/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb b/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb index 83cbff6..64e2a7c 100644 --- a/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb +++ b/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <div class="article"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <div id="headline_image"><%= headline_image %></div> | 2 | <div id="headline_image"><%= headline_image %></div> |
| 3 | <%= aggregate?(@page.body) %> | 3 | <%= aggregate?(@page.body) %> |
| 4 | </div> | 4 | </div> |
| 5 | 5 | ||
| 6 | <%= will_paginate(@content_collection) if @content_collection %> \ No newline at end of file | 6 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/standard_template.html.erb b/app/views/custom/page_templates/public/standard_template.html.erb index 8000af5..bbc8cd0 100644 --- a/app/views/custom/page_templates/public/standard_template.html.erb +++ b/app/views/custom/page_templates/public/standard_template.html.erb | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | <div class="article"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= @page.title %></h2> | 2 | <h2 class="headline"><%= @page.title %></h2> |
| 3 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> | 3 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> |
| 4 | <div id="headline_image"><%= headline_image %></div> | 4 | <div id="headline_image"><%= headline_image %></div> |
| 5 | <div class="body"><%= aggregate?(@page.body) %></div> | 5 | <div class="body"><%= aggregate?(@page.body) %></div> |
| 6 | </div> | 6 | </div> |
| 7 | 7 | ||
| 8 | <%= will_paginate(@content_collection) if @content_collection %> \ No newline at end of file | 8 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/title_only.html.erb b/app/views/custom/page_templates/public/title_only.html.erb index 09c7455..42fe9a6 100644 --- a/app/views/custom/page_templates/public/title_only.html.erb +++ b/app/views/custom/page_templates/public/title_only.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <div class="article"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= @page.title %></h2> | 2 | <h2 class="headline"><%= @page.title %></h2> |
| 3 | <div id="headline_image"><%= headline_image %></div> | 3 | <div id="headline_image"><%= headline_image %></div> |
| 4 | <%= aggregate?(@page.body) %> | 4 | <%= aggregate?(@page.body) %> |
| 5 | </div> | 5 | </div> |
| 6 | 6 | ||
| 7 | <%= will_paginate(@content_collection) if @content_collection %> \ No newline at end of file | 7 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/update.html.erb b/app/views/custom/page_templates/public/update.html.erb index 5ea277a..d5995ac 100644 --- a/app/views/custom/page_templates/public/update.html.erb +++ b/app/views/custom/page_templates/public/update.html.erb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | <div class="article"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= @page.title %></h2> | 2 | <h2 class="headline"><%= @page.title %></h2> |
| 3 | <div class="author_and_date"><%= date_for_page @page %>, <%= @page.user.try(:login) %></div> | 3 | <div class="author_and_date"><%= date_for_page @page %>, <%= @page.user.try(:login) %></div> |
| 4 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> | 4 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> |
| @@ -6,4 +6,4 @@ | |||
| 6 | <div class="body"><%= aggregate?(@page.body) %></div> | 6 | <div class="body"><%= aggregate?(@page.body) %></div> |
| 7 | </div> | 7 | </div> |
| 8 | 8 | ||
| 9 | <%= will_paginate(@content_collection) if @content_collection %> \ No newline at end of file | 9 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/partials/_article.html.erb b/app/views/custom/partials/_article.html.erb index 433c31c..b738ac7 100644 --- a/app/views/custom/partials/_article.html.erb +++ b/app/views/custom/partials/_article.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <div class="article_partial"> | 1 | <div class="article_partial" lang="<%= page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= link_to_path page.title, page.node.unique_name %></h2> | 2 | <h2 class="headline"><%= link_to_path page.title, page.node.unique_name %></h2> |
| 3 | <div class="author_and_date"> | 3 | <div class="author_and_date"> |
| 4 | <%= date_for_page page %>, <%= author_for_page page %> | 4 | <%= date_for_page page %>, <%= author_for_page page %> |
| 5 | </div> | 5 | </div> |
| 6 | <p class="excerpt"><%= page.abstract %> <%= link_to_path t(:more), page.node.unique_name %></p> | 6 | <p class="excerpt"><%= page.abstract %> <%= link_to_path t(:more), page.node.unique_name %></p> |
| 7 | </div> \ No newline at end of file | 7 | </div> |
diff --git a/app/views/custom/partials/_no_date_and_author.html.erb b/app/views/custom/partials/_no_date_and_author.html.erb index 61d6aac..fed02ac 100644 --- a/app/views/custom/partials/_no_date_and_author.html.erb +++ b/app/views/custom/partials/_no_date_and_author.html.erb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | <div class="article_partial"> | 1 | <div class="article_partial" lang="<%= page.effective_lang %>"> |
| 2 | <h2 class="headline"><%= link_to page.title, content_path(page.node.unique_path) %></h2> | 2 | <h2 class="headline"><%= link_to page.title, content_path(page.node.unique_path) %></h2> |
| 3 | <p class="excerpt"><%= page.abstract %></p> | 3 | <p class="excerpt"><%= page.abstract %></p> |
| 4 | </div> \ No newline at end of file | 4 | </div> |
diff --git a/app/views/events/edit.html.erb b/app/views/events/edit.html.erb index 17b6980..824cd66 100644 --- a/app/views/events/edit.html.erb +++ b/app/views/events/edit.html.erb | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | <h1>Editing event</h1> | 7 | <h1>Editing event</h1> |
| 8 | 8 | ||
| 9 | <% form_for(@event) do |f| %> | 9 | <%= form_for(@event) do |f| %> |
| 10 | <%= f.error_messages %> | 10 | <%= form_error_messages(f) %> |
| 11 | 11 | ||
| 12 | <p> | 12 | <p> |
| 13 | <%= f.label :start_time %><br /> | 13 | <%= f.label :start_time %><br /> |
| @@ -47,4 +47,4 @@ | |||
| 47 | <p> | 47 | <p> |
| 48 | <%= f.submit 'Update' %> | 48 | <%= f.submit 'Update' %> |
| 49 | </p> | 49 | </p> |
| 50 | <% end %> \ No newline at end of file | 50 | <% end %> |
diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb index c1b5b48..19b21ce 100644 --- a/app/views/events/index.html.erb +++ b/app/views/events/index.html.erb | |||
| @@ -26,11 +26,11 @@ | |||
| 26 | <td><%=h event.node_id %></td> | 26 | <td><%=h event.node_id %></td> |
| 27 | <td><%= link_to 'Show', event %></td> | 27 | <td><%= link_to 'Show', event %></td> |
| 28 | <td><%= link_to 'Edit', edit_event_path(event) %></td> | 28 | <td><%= link_to 'Edit', edit_event_path(event) %></td> |
| 29 | <td><%= link_to 'Destroy', event, :confirm => 'Are you sure?', :method => :delete %></td> | 29 | <td><%= button_to 'Destroy', event, method: :delete, form: { data: { confirm: 'Are you sure?' } } %></td> |
| 30 | </tr> | 30 | </tr> |
| 31 | <% end %> | 31 | <% end %> |
| 32 | </table> | 32 | </table> |
| 33 | 33 | ||
| 34 | <br /> | 34 | <br /> |
| 35 | 35 | ||
| 36 | <%= link_to 'New event', new_event_path %> \ No newline at end of file | 36 | <%= link_to 'New event', new_event_path %> |
diff --git a/app/views/events/new.html.erb b/app/views/events/new.html.erb index 8c9812e..cd892c5 100644 --- a/app/views/events/new.html.erb +++ b/app/views/events/new.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>New event</h1> | 1 | <h1>New event</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@event) do |f| %> | 3 | <%= form_for(@event) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :start_time %><br /> | 7 | <%= f.label :start_time %><br /> |
| @@ -43,4 +43,4 @@ | |||
| 43 | </p> | 43 | </p> |
| 44 | <% end %> | 44 | <% end %> |
| 45 | 45 | ||
| 46 | <%= link_to 'Back', events_path %> \ No newline at end of file | 46 | <%= link_to 'Back', events_path %> |
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index 97b81df..890aeaa 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb | |||
| @@ -4,16 +4,15 @@ | |||
| 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| 5 | <head> | 5 | <head> |
| 6 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | 6 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| 7 | <%= csrf_meta_tags %> | ||
| 7 | 8 | ||
| 8 | <title><%= "#{params[:controller]} | #{params[:action]}" %></title> | 9 | <title><%= "#{params[:controller]} | #{params[:action]}" %></title> |
| 9 | <%= javascript_include_tag 'jquery-1.3.2.min' %> | ||
| 10 | <%= javascript_include_tag 'jquery-ui-1.7.2.custom.min' %> | ||
| 11 | <%= javascript_include_tag 'jquery.hotkeys' %> | ||
| 12 | <%= javascript_include_tag 'tiny_mce/jquery.tinymce.js' %> | ||
| 13 | <%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %> | 10 | <%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %> |
| 14 | <%= stylesheet_link_tag 'admin' %> | 11 | <%= javascript_include_tag 'admin_bundle' %> |
| 15 | <%= javascript_include_tag 'admin_search.js' %> | 12 | <%= tinymce_assets %> |
| 16 | <%= javascript_include_tag 'admin_interface.js' %> | 13 | <link rel="stylesheet" href="/stylesheets/admin.css"> |
| 14 | <script src="/javascripts/admin_search.js"></script> | ||
| 15 | <script src="/javascripts/admin_interface.js"></script> | ||
| 17 | </head> | 16 | </head> |
| 18 | 17 | ||
| 19 | <body> | 18 | <body> |
| @@ -34,7 +33,7 @@ | |||
| 34 | <% end %> | 33 | <% end %> |
| 35 | </div> | 34 | </div> |
| 36 | <div id="content"> | 35 | <div id="content"> |
| 37 | <%= yield :layout %> | 36 | <%= yield %> |
| 38 | </div> | 37 | </div> |
| 39 | 38 | ||
| 40 | <div id="results"></div> | 39 | <div id="results"></div> |
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 3c95d75..48e0a5b 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb | |||
| @@ -1,47 +1,74 @@ | |||
| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | 1 | <!DOCTYPE HTML> |
| 2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
| 3 | 2 | ||
| 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | 3 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| 5 | <head> | 4 | <head> |
| 6 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | 5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| 6 | <meta name="viewport" content="width=device-width,initial-scale=1"/> | ||
| 7 | <meta name="description" content="Der Chaos Computer Club ist eine galaktische Gemeinschaft von Lebewesen für Informationsfreiheit und Technikfolgenabschätzung."/> | ||
| 8 | |||
| 9 | <meta property="og:image" content="https://www.ccc.de/images/chaosknoten.svg" /> | ||
| 10 | <meta property="og:description" content="Der Chaos Computer Club ist eine galaktische Gemeinschaft von Lebewesen für Informationsfreiheit und Technikfolgenabschätzung." /> | ||
| 7 | 11 | ||
| 8 | <title><%= page_title %></title> | 12 | <title><%= page_title %></title> |
| 9 | <%= stylesheet_link_tag "ccc" %> | 13 | <link rel="stylesheet" href="/stylesheets/ccc.css"> |
| 10 | <%= javascript_include_tag 'jquery-1.3.2.min' %> | 14 | <script src="/javascripts/jquery-1.3.2.min.js"></script> |
| 11 | <%= javascript_include_tag 'shadowbox/shadowbox' %> | 15 | <script src="/javascripts/shadowbox/shadowbox.js"></script> |
| 12 | <%= stylesheet_link_tag "shadowbox" %> | 16 | <link rel="stylesheet" href="/stylesheets/shadowbox.css"> |
| 13 | <%= javascript_include_tag 'public' %> | 17 | <script src="/javascripts/public.js"></script> |
| 18 | |||
| 19 | <%= auto_discovery_link_tag(:atom, '/rss/updates.xml', title: "ATOM") %> | ||
| 20 | <%= auto_discovery_link_tag(:rss, '/rss/updates.rdf', title: "RSS") %> | ||
| 21 | |||
| 22 | <script> | ||
| 23 | (function() { document.addEventListener("DOMContentLoaded", function() { | ||
| 24 | if (localStorage.getItem('override-prefers-color-scheme', false)) | ||
| 25 | document.getElementById("light-mode").checked = true; | ||
| 26 | }); })(); | ||
| 27 | </script> | ||
| 14 | 28 | ||
| 15 | <%= auto_discovery_link_tag(:atom, {:locale => :de, :controller => "rss", :action => "updates", :format => :xml}) %> | ||
| 16 | <%= auto_discovery_link_tag(:rss, {:locale => :de, :controller => "rss", :action => "updates", :format => :rdf}) %> | ||
| 17 | </head> | 29 | </head> |
| 18 | 30 | ||
| 19 | <body> | 31 | <body lang="<%= @page ? @page.effective_lang : 'de' %>"> |
| 20 | <div id="wrapper"> | 32 | <div id="wrapper"> |
| 21 | <div id="header"> | 33 | <div id="header"> |
| 22 | <%= link_to_path(image_tag("header.png"), "/home") %> | 34 | <img src="/images/header.png" alt=""> |
| 23 | </div> | 35 | </div> |
| 24 | <div id="search"> | 36 | <div id="toolbox"> |
| 25 | <%= render :partial => "content/search" %> | 37 | <div id="search"> |
| 38 | <%= render :partial => "content/search" %> | ||
| 39 | </div> | ||
| 40 | <div id="light-mode-div"> | ||
| 41 | <input id="light-mode" type="checkbox" aria-label="Switch between dark and light mode" /><label for="light-mode"><span class="hide-me">lights</span></label> | ||
| 42 | </div> | ||
| 43 | <div id="burger-div"> | ||
| 44 | <input type="checkbox" id="menu-toggle" class="menu-checkbox"> | ||
| 45 | <label for="menu-toggle" class="burger-menu"><span></span><span></span><span></span></label> | ||
| 46 | </div> | ||
| 26 | </div> | 47 | </div> |
| 27 | <div id="left_column"> | 48 | <div id="left_column"> |
| 28 | <%= main_menu %> | 49 | <%= main_menu %> |
| 29 | 50 | ||
| 30 | <%= language_selector %> | ||
| 31 | <% if current_user && @page.node %> | 51 | <% if current_user && @page.node %> |
| 32 | <%= link_to "Edit", node_path(:id => @page.node) %> | 52 | <div class="main_navigation"> |
| 53 | <h2>Admin</h2> | ||
| 54 | <ul> | ||
| 55 | <li><%= link_to raw('<span class="inactive admin_edit_link">⚙️ Overview</span>'), admin_path %></li> | ||
| 56 | <li><%= link_to raw('<span class="inactive admin_edit_link">✎ Edit</span>'), node_path(@page.node) %></li> | ||
| 57 | </ul> | ||
| 58 | </div> | ||
| 33 | <% end %> | 59 | <% end %> |
| 34 | 60 | ||
| 35 | <%= calendar %> | 61 | <%= calendar %> |
| 36 | </div> | 62 | </div> |
| 37 | <div id="center_column"> | 63 | <div id="center_column"> |
| 38 | <%= yield :layout %> | 64 | <%= yield :layout %> |
| 39 | |||
| 40 | <div id="footer"> | 65 | <div id="footer"> |
| 41 | <br /> | 66 | <br /> |
| 42 | <br /> | ||
| 43 | <p style="text-align: center"> | 67 | <p style="text-align: center"> |
| 44 | <%= link_to t(:sponsors), content_path("sponsors") %> | 68 | <%= link_to "Impressum", content_path("imprint") %> |
| 69 | <%= link_to "Datenschutz", content_path("datenschutz") %> | ||
| 70 | <%= language_selector %> | ||
| 71 | <!-- %= link_to t(:sponsors), content_path("sponsors") % --> | ||
| 45 | </p> | 72 | </p> |
| 46 | </div> | 73 | </div> |
| 47 | </div> | 74 | </div> |
| @@ -50,5 +77,6 @@ | |||
| 50 | <%= featured_articles %> | 77 | <%= featured_articles %> |
| 51 | </div> | 78 | </div> |
| 52 | </div> | 79 | </div> |
| 80 | |||
| 53 | </body> | 81 | </body> |
| 54 | </html> \ No newline at end of file | 82 | </html> |
diff --git a/app/views/layouts/pages.html.erb b/app/views/layouts/pages.html.erb index 327e0eb..70ceece 100644 --- a/app/views/layouts/pages.html.erb +++ b/app/views/layouts/pages.html.erb | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| 5 | <head> | 5 | <head> |
| 6 | <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> | 6 | <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> |
| 7 | <meta name="viewport" content="width=device-width,initial-scale=1" /> | ||
| 8 | <meta property="og:image" content="https://www.ccc.de/images/chaosknoten.svg" /> | ||
| 7 | <title>Pages: <%= controller.action_name %></title> | 9 | <title>Pages: <%= controller.action_name %></title> |
| 8 | <%= stylesheet_link_tag 'scaffold' %> | 10 | <%= stylesheet_link_tag 'scaffold' %> |
| 9 | </head> | 11 | </head> |
diff --git a/app/views/menu_items/edit.html.erb b/app/views/menu_items/edit.html.erb index 9ea0fcc..9891708 100644 --- a/app/views/menu_items/edit.html.erb +++ b/app/views/menu_items/edit.html.erb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <h1>Edit Menu Item</h1> | 1 | <h1>Edit Menu Item</h1> |
| 2 | 2 | ||
| 3 | <% form_for @menu_item do |f| %> | 3 | <%= form_for @menu_item do |f| %> |
| 4 | <table> | 4 | <table> |
| 5 | 5 | ||
| 6 | <tr> | 6 | <tr> |
| @@ -29,4 +29,4 @@ | |||
| 29 | <td class="right"><%= f.submit 'Update' %></td> | 29 | <td class="right"><%= f.submit 'Update' %></td> |
| 30 | </tr> | 30 | </tr> |
| 31 | </table> | 31 | </table> |
| 32 | <% end %> \ No newline at end of file | 32 | <% end %> |
diff --git a/app/views/menu_items/index.html.erb b/app/views/menu_items/index.html.erb index 123a07a..c52c150 100644 --- a/app/views/menu_items/index.html.erb +++ b/app/views/menu_items/index.html.erb | |||
| @@ -14,13 +14,10 @@ | |||
| 14 | <td class="menu_item_title"><%= menu_item.title %></td> | 14 | <td class="menu_item_title"><%= menu_item.title %></td> |
| 15 | <td><%= link_to "Edit", edit_menu_item_path(menu_item) %></td> | 15 | <td><%= link_to "Edit", edit_menu_item_path(menu_item) %></td> |
| 16 | <td> | 16 | <td> |
| 17 | <%= link_to( | 17 | <%= button_to "Delete", menu_item_path(menu_item), |
| 18 | "Delete", | 18 | method: :delete, |
| 19 | menu_item_path(menu_item), | 19 | form: { data: { confirm: "Are you sure?" } } %> |
| 20 | :method => :delete, | ||
| 21 | :confirm => "Are you sure?" | ||
| 22 | ) %> | ||
| 23 | </td> | 20 | </td> |
| 24 | </tr> | 21 | </tr> |
| 25 | <% end %> | 22 | <% end %> |
| 26 | </table> \ No newline at end of file | 23 | </table> |
diff --git a/app/views/menu_items/new.html.erb b/app/views/menu_items/new.html.erb index 64b9abb..68081d0 100644 --- a/app/views/menu_items/new.html.erb +++ b/app/views/menu_items/new.html.erb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <h1>Add Menu Item</h1> | 1 | <h1>Add Menu Item</h1> |
| 2 | 2 | ||
| 3 | <% form_for @menu_item do |f| %> | 3 | <%= form_for @menu_item do |f| %> |
| 4 | <table> | 4 | <table> |
| 5 | 5 | ||
| 6 | <tr> | 6 | <tr> |
| @@ -29,4 +29,4 @@ | |||
| 29 | <td class="right"><%= f.submit 'Create' %></td> | 29 | <td class="right"><%= f.submit 'Create' %></td> |
| 30 | </tr> | 30 | </tr> |
| 31 | </table> | 31 | </table> |
| 32 | <% end %> \ No newline at end of file | 32 | <% end %> |
diff --git a/app/views/nodes/edit.html.erb b/app/views/nodes/edit.html.erb index 8e27d0f..b45c700 100644 --- a/app/views/nodes/edit.html.erb +++ b/app/views/nodes/edit.html.erb | |||
| @@ -2,109 +2,89 @@ | |||
| 2 | <%= link_to 'metadata', '#', :id => 'button', :class => "unselected" %> | 2 | <%= link_to 'metadata', '#', :id => 'button', :class => "unselected" %> |
| 3 | <%= link_to 'Show', @node %> | 3 | <%= link_to 'Show', @node %> |
| 4 | <%= link_to 'Preview', preview_page_path(@draft) %> | 4 | <%= link_to 'Preview', preview_page_path(@draft) %> |
| 5 | <%= link_to 'Publish', publish_node_path, :method => :put, :confirm => "Publish this draft?" %> | 5 | <%= button_to 'Publish', publish_node_path(@node), method: :put, form: { data: { confirm: "Publish this draft?" } } %> |
| 6 | <%= link_to 'Revisions', node_revisions_path(@node) %> | 6 | <%= link_to 'Revisions', node_revisions_path(@node) %> |
| 7 | <% end %> | 7 | <% end %> |
| 8 | 8 | ||
| 9 | <div id="page_editor"> | 9 | <div id="page_editor"> |
| 10 | <% form_for(@node) do |f| %> | 10 | <%= form_for(@node) do |f| %> |
| 11 | <%= f.error_messages %> | 11 | <% if @node.errors.any? %> |
| 12 | <div class="error_messages"> | ||
| 13 | <ul><% @node.errors.full_messages.each do |msg| %><li><%= msg %></li><% end %></ul> | ||
| 14 | </div> | ||
| 15 | <% end %> | ||
| 12 | 16 | ||
| 13 | <div id="metadata"> | 17 | <div id="metadata"> |
| 14 | <table> | 18 | <div class="node_description">Event</div> |
| 15 | <tr> | 19 | <div class="node_content"><%= event_information %></div> |
| 16 | <td class="description">Event</td> | 20 | |
| 17 | <td><%= event_information %></td> | 21 | <div class="node_description">Slug</div> |
| 18 | </tr> | 22 | <div class="node_content"> |
| 19 | <tr> | 23 | <%= f.text_field( |
| 20 | <td class="description">Slug</td> | 24 | :staged_slug, :value => @node.staged_slug || @node.slug |
| 21 | <td> | 25 | ) |
| 22 | <%= | 26 | %> |
| 23 | f.text_field( | 27 | </div> |
| 24 | :staged_slug, :value => @node.staged_slug || @node.slug | 28 | |
| 25 | ) | 29 | <div class="node_description">parent</div> |
| 26 | %> | 30 | <div class="node_content"> |
| 27 | </td> | 31 | <%= text_field_tag :move_to_search_term, @node.parent.title rescue "" %> |
| 28 | </tr> | 32 | <div id="search_results"> |
| 29 | <tr> | ||
| 30 | <td class="description">parent</td> | ||
| 31 | <td> | ||
| 32 | <%= text_field_tag :move_to_search_term, @node.parent.title rescue "" %> | ||
| 33 | <div id="search_results"> | ||
| 34 | 33 | ||
| 35 | </div> | 34 | </div> |
| 36 | <%= f.hidden_field( | 35 | <%= f.hidden_field( |
| 37 | :staged_parent_id, | 36 | :staged_parent_id, |
| 38 | :value => @node.staged_parent_id || @node.parent_id | 37 | :value => @node.staged_parent_id || @node.parent_id |
| 39 | ) | 38 | ) |
| 40 | %> | 39 | %> |
| 41 | </td> | 40 | </div> |
| 42 | </tr> | ||
| 43 | 41 | ||
| 44 | <% fields_for @draft do |d| %> | 42 | <%= fields_for @draft do |d| %> |
| 45 | <tr> | 43 | <div class="node_description">Tags - comma seperated</div> |
| 46 | <td class="description">Tags - comma seperated</td> | 44 | <div class="node_content"><%= text_field_tag :tag_list, @draft.tag_list %></div> |
| 47 | <td><%= text_field_tag :tag_list, @draft.tag_list %></td> | 45 | |
| 48 | </tr> | 46 | <div class="node_description">Publish at</div> |
| 49 | <tr> | 47 | <div class="node_content"><%= d.datetime_select :published_at, :value => @draft.published_at %></div> |
| 50 | <td class="description">Publish at</td> | 48 | |
| 51 | <td><%= d.datetime_select :published_at, :value => @draft.published_at %></td> | 49 | <div class="node_description">Template</div> |
| 52 | </tr> | 50 | <div class="node_content"><%= d.select :template_name, custom_page_templates, {:prompt => 'Select Template'} %></div> |
| 53 | <tr> | 51 | |
| 54 | <td class="description">Template</td> | 52 | <div class="node_description">Author</div> |
| 55 | <td><%= d.select :template_name, custom_page_templates, {:prompt => 'Select Template'} %></td> | 53 | <div class="node_content"><%= d.select :user_id, user_list %></div> |
| 56 | </tr> | 54 | |
| 57 | <tr> | 55 | <div class="node_description">Images</div> |
| 58 | <td class="description">Author</td> | 56 | <div class="node_content"> |
| 59 | <td><%= d.select :user_id, user_list %></td> | 57 | <ul id="image_box" rel="<%= @draft.id %>"> |
| 60 | </tr> | 58 | <% @draft.assets.images.each do |image| %> |
| 61 | <tr> | 59 | <li rel="images_<%= image.id %>"> |
| 62 | <td class="description">Images</td> | 60 | <%= image_tag(image.upload.url(:thumb)) %> |
| 63 | <td> | 61 | </li> |
| 64 | <ul id="image_box" rel="<%= @draft.id %>"> | 62 | <% end %> |
| 65 | <% @draft.assets.images.each do |image| %> | 63 | </ul> |
| 66 | <li rel="images_<%= image.id %>"> | 64 | <div class="clear_left right"> |
| 67 | <%= image_tag(image.upload.url(:thumb)) %> | 65 | <a id="image_browser_toggle" class="unselected" href="#">image browser</a> |
| 68 | </li> | 66 | </div> |
| 69 | <% end %> | 67 | <div id="image_browser"> |
| 70 | </ul> | 68 | <ul> |
| 71 | <div class="clear_left right"> | 69 | <% Asset.images.each do |image| %> |
| 72 | <a id="image_browser_toggle" class="unselected" href="#">image browser</a> | 70 | <li rel="images_<%= image.id %>"><%= image_tag(image.upload.url(:thumb)) %></li> |
| 73 | </div> | 71 | <% end %> |
| 74 | <div id="image_browser"> | 72 | </ul> |
| 75 | <ul> | 73 | </div> |
| 76 | <% Asset.images.each do |image| %> | 74 | </div> |
| 77 | <li rel="images_<%= image.id %>"><%= image_tag(image.upload.url(:thumb)) %></li> | ||
| 78 | <% end %> | ||
| 79 | </ul> | ||
| 80 | </div> | ||
| 81 | </td> | ||
| 82 | </tr> | ||
| 83 | </table> | ||
| 84 | </div> | 75 | </div> |
| 85 | 76 | ||
| 86 | <table id="content"> | 77 | <div id="content"> |
| 87 | <tr> | 78 | <div class="node_description">Title</div> |
| 88 | <th class="description"></th> | 79 | <div class="node_content"><%= d.text_field :title %></div> |
| 89 | <th class="content"></th> | 80 | |
| 90 | </tr> | 81 | <div class="node_description">Abstract</div> |
| 91 | <tr> | 82 | <div class="node_content"><%= d.text_area :abstract %></div> |
| 92 | <td class="description">Title</td> | 83 | |
| 93 | <td><%= d.text_field :title %></td> | 84 | <div class="node_description">Body</div> |
| 94 | </tr> | 85 | <div class="node_content"><%= d.text_area :body, :class => 'with_editor' %></div> |
| 95 | <tr> | 86 | |
| 96 | <td class="description">Abstract</td> | 87 | <div><%= d.submit 'save' %></div> |
| 97 | <td><%= d.text_area :abstract %></td> | ||
| 98 | </tr> | ||
| 99 | <tr> | ||
| 100 | <td class="description">Body</td> | ||
| 101 | <td><%= d.text_area :body, :class => 'with_editor' %></td> | ||
| 102 | </tr> | ||
| 103 | <tr> | ||
| 104 | <td></td> | ||
| 105 | <td class="right"><%= d.submit 'save' %></td> | ||
| 106 | </tr> | ||
| 107 | </table> | ||
| 108 | <% end %> | 88 | <% end %> |
| 109 | <% end %> | 89 | <% end %> |
| 110 | </div> \ No newline at end of file | 90 | </div> |
diff --git a/app/views/nodes/index.html.erb b/app/views/nodes/index.html.erb index bf01645..e5a55d4 100644 --- a/app/views/nodes/index.html.erb +++ b/app/views/nodes/index.html.erb | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | <%= node.lock_owner.login if node.lock_owner %> | 27 | <%= node.lock_owner.login if node.lock_owner %> |
| 28 | </td> | 28 | </td> |
| 29 | <td> | 29 | <td> |
| 30 | <%= node.draft ? node.draft.revision : node.head.revision %> | 30 | <%= node.draft ? node.draft.revision : (node.head ? node.head.revision : "EMPTY") %> |
| 31 | </td> | 31 | </td> |
| 32 | </tr> | 32 | </tr> |
| 33 | <% end %> | 33 | <% end %> |
diff --git a/app/views/nodes/new.html.erb b/app/views/nodes/new.html.erb index 850207b..028d727 100644 --- a/app/views/nodes/new.html.erb +++ b/app/views/nodes/new.html.erb | |||
| @@ -1,11 +1,14 @@ | |||
| 1 | <h1>Create new node</h1> | 1 | <h1>Create new node</h1> |
| 2 | 2 | ||
| 3 | <%= error_messages_for( :node ).gsub("Slug", "Title") %> | 3 | <% if @node.errors.any? %> |
| 4 | 4 | <div class="error_messages"> | |
| 5 | <ul><% @node.errors.full_messages.each do |msg| %><li><%= msg.to_s.gsub("Slug", "Title") %></li><% end %></ul> | ||
| 6 | </div> | ||
| 7 | <% end %> | ||
| 5 | 8 | ||
| 6 | <p>What kind of node do you want to create?</p> | 9 | <p>What kind of node do you want to create?</p> |
| 7 | 10 | ||
| 8 | <% form_tag nodes_path do %> | 11 | <%= form_tag nodes_path do %> |
| 9 | <table id="new_node"> | 12 | <table id="new_node"> |
| 10 | <tr> | 13 | <tr> |
| 11 | <td class="description">Type</td> | 14 | <td class="description">Type</td> |
| @@ -20,7 +23,11 @@ | |||
| 20 | </p> | 23 | </p> |
| 21 | <p> | 24 | <p> |
| 22 | <%= radio_button_tag :kind, "update" %> | 25 | <%= radio_button_tag :kind, "update" %> |
| 23 | Update / Press release ( is automatically created in /updates ) | 26 | Update ( is automatically created in /updates/<%= Time.now.year.to_s %>/ and gets tag "update" ) |
| 27 | </p> | ||
| 28 | <p> | ||
| 29 | <%= radio_button_tag :kind, "press_release" %> | ||
| 30 | Pressemitteilung ( is automatically created in /updates/<%= Time.now.year.to_s %>/ and gets tags "update, pressemitteilung" ) | ||
| 24 | </p> | 31 | </p> |
| 25 | </td> | 32 | </td> |
| 26 | </tr> | 33 | </tr> |
| @@ -31,8 +38,8 @@ | |||
| 31 | <tr id="parent_search_field"> | 38 | <tr id="parent_search_field"> |
| 32 | <td class="description">Parent</td> | 39 | <td class="description">Parent</td> |
| 33 | <td> | 40 | <td> |
| 34 | <%= text_field_tag :parent_search_term %> | 41 | <%= text_field_tag :parent_search_term, @parent_name %> |
| 35 | <%= hidden_field_tag :parent_id %> | 42 | <%= hidden_field_tag :parent_id, @parent_id %> |
| 36 | <div id="search_results"> | 43 | <div id="search_results"> |
| 37 | 44 | ||
| 38 | </div> | 45 | </div> |
| @@ -43,4 +50,4 @@ | |||
| 43 | <td class="right"><%= submit_tag "Create" %></td> | 50 | <td class="right"><%= submit_tag "Create" %></td> |
| 44 | </tr> | 51 | </tr> |
| 45 | </table> | 52 | </table> |
| 46 | <% end %> \ No newline at end of file | 53 | <% end %> |
diff --git a/app/views/nodes/update.js.erb b/app/views/nodes/update.js.erb index be26fab..35dfeee 100644 --- a/app/views/nodes/update.js.erb +++ b/app/views/nodes/update.js.erb | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | $("#flash").html( | 1 | <% if flash[:notice] %> |
| 2 | "<span><%= escape_javascript(flash.delete(:notice)) %></span>" | 2 | $("#flash").html( |
| 3 | ); \ No newline at end of file | 3 | "<span><%= escape_javascript(flash.delete(:notice)) %></span>" |
| 4 | ); | ||
| 5 | <% end %> | ||
diff --git a/app/views/occurrences/edit.html.erb b/app/views/occurrences/edit.html.erb index 6a81188..aa4f6e0 100644 --- a/app/views/occurrences/edit.html.erb +++ b/app/views/occurrences/edit.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>Editing occurrence</h1> | 1 | <h1>Editing occurrence</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@occurrence) do |f| %> | 3 | <%= form_for(@occurrence) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :summary %><br /> | 7 | <%= f.label :summary %><br /> |
| @@ -29,4 +29,4 @@ | |||
| 29 | <% end %> | 29 | <% end %> |
| 30 | 30 | ||
| 31 | <%= link_to 'Show', @occurrence %> | | 31 | <%= link_to 'Show', @occurrence %> | |
| 32 | <%= link_to 'Back', occurrences_path %> \ No newline at end of file | 32 | <%= link_to 'Back', occurrences_path %> |
diff --git a/app/views/occurrences/index.html.erb b/app/views/occurrences/index.html.erb index 06dbf07..0e99857 100644 --- a/app/views/occurrences/index.html.erb +++ b/app/views/occurrences/index.html.erb | |||
| @@ -18,11 +18,11 @@ | |||
| 18 | <td><%=h occurrence.event_id %></td> | 18 | <td><%=h occurrence.event_id %></td> |
| 19 | <td><%= link_to 'Show', occurrence %></td> | 19 | <td><%= link_to 'Show', occurrence %></td> |
| 20 | <td><%= link_to 'Edit', edit_occurrence_path(occurrence) %></td> | 20 | <td><%= link_to 'Edit', edit_occurrence_path(occurrence) %></td> |
| 21 | <td><%= link_to 'Destroy', occurrence, :confirm => 'Are you sure?', :method => :delete %></td> | 21 | <td><%= button_to 'Destroy', occurrence, method: :delete, form: { data: { confirm: 'Are you sure?' } } %></td> |
| 22 | </tr> | 22 | </tr> |
| 23 | <% end %> | 23 | <% end %> |
| 24 | </table> | 24 | </table> |
| 25 | 25 | ||
| 26 | <br /> | 26 | <br /> |
| 27 | 27 | ||
| 28 | <%= link_to 'New occurrence', new_occurrence_path %> \ No newline at end of file | 28 | <%= link_to 'New occurrence', new_occurrence_path %> |
diff --git a/app/views/occurrences/new.html.erb b/app/views/occurrences/new.html.erb index 0a77af1..c05ce40 100644 --- a/app/views/occurrences/new.html.erb +++ b/app/views/occurrences/new.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>New occurrence</h1> | 1 | <h1>New occurrence</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@occurrence) do |f| %> | 3 | <%= form_for(@occurrence) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :summary %><br /> | 7 | <%= f.label :summary %><br /> |
| @@ -28,4 +28,4 @@ | |||
| 28 | </p> | 28 | </p> |
| 29 | <% end %> | 29 | <% end %> |
| 30 | 30 | ||
| 31 | <%= link_to 'Back', occurrences_path %> \ No newline at end of file | 31 | <%= link_to 'Back', occurrences_path %> |
diff --git a/app/views/pages/edit.html.erb b/app/views/pages/edit.html.erb index 749d7e3..8b1242c 100644 --- a/app/views/pages/edit.html.erb +++ b/app/views/pages/edit.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>Editing page</h1> | 1 | <h1>Editing page</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@page) do |f| %> | 3 | <%= form_for(@page) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :title %><br /> | 7 | <%= f.label :title %><br /> |
diff --git a/app/views/pages/index.html.erb b/app/views/pages/index.html.erb index 16539da..91e5359 100644 --- a/app/views/pages/index.html.erb +++ b/app/views/pages/index.html.erb | |||
| @@ -10,9 +10,9 @@ | |||
| 10 | <tr> | 10 | <tr> |
| 11 | <td><%=h page.node_id %></td> | 11 | <td><%=h page.node_id %></td> |
| 12 | <td><%=h page.title %></td> | 12 | <td><%=h page.title %></td> |
| 13 | <td><%= link_to 'Show', link_to_path(page.node.unique_path) %></td> | 13 | <td><%= link_to 'Show', content_path(:page_path => page.node.unique_path) %></td> |
| 14 | <td><%= link_to 'Edit', edit_page_path(page) %></td> | 14 | <td><%= link_to 'Edit', edit_page_path(page) %></td> |
| 15 | <td><%= link_to 'Destroy', page, :confirm => 'Are you sure?', :method => :delete %></td> | 15 | <td><%= button_to 'Destroy', page, method: :delete, form: { data: { confirm: 'Are you sure?' } } %></td> |
| 16 | </tr> | 16 | </tr> |
| 17 | <% end %> | 17 | <% end %> |
| 18 | </table> | 18 | </table> |
diff --git a/app/views/pages/new.html.erb b/app/views/pages/new.html.erb index b27dc62..2758faf 100644 --- a/app/views/pages/new.html.erb +++ b/app/views/pages/new.html.erb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | <h1>New page</h1> | 1 | <h1>New page</h1> |
| 2 | 2 | ||
| 3 | <% form_for(@page) do |f| %> | 3 | <%= form_for(@page) do |f| %> |
| 4 | <%= f.error_messages %> | 4 | <%= form_error_messages(f) %> |
| 5 | 5 | ||
| 6 | <p> | 6 | <p> |
| 7 | <%= f.label :node_id %><br /> | 7 | <%= f.label :node_id %><br /> |
diff --git a/app/views/revisions/diff.html.erb b/app/views/revisions/diff.html.erb index f7ad79c..b8d061d 100644 --- a/app/views/revisions/diff.html.erb +++ b/app/views/revisions/diff.html.erb | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | <h1>Revisions#diff</h1> | 6 | <h1>Revisions#diff</h1> |
| 7 | 7 | ||
| 8 | <% form_tag diff_node_revisions_path do %> | 8 | <%= form_tag diff_node_revisions_path do %> |
| 9 | <%= select_tag :start_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:start_revision].to_i) %> | 9 | <%= select_tag :start_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:start_revision].to_i) %> |
| 10 | <%= select_tag :end_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:end_revision].to_i) %> | 10 | <%= select_tag :end_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:end_revision].to_i) %> |
| 11 | <%= submit_tag 'Diff' %> | 11 | <%= submit_tag 'Diff' %> |
| @@ -38,7 +38,7 @@ | |||
| 38 | </div> | 38 | </div> |
| 39 | </pre> | 39 | </pre> |
| 40 | 40 | ||
| 41 | <%= javascript_include_tag 'cacycle_diff' %> | 41 | <script src="/javascripts/cacycle_diff.js"></script> |
| 42 | <script type="text/javascript" charset="utf-8"> | 42 | <script type="text/javascript" charset="utf-8"> |
| 43 | window.onload = function() { | 43 | window.onload = function() { |
| 44 | title1 = document.getElementById('start_title').innerHTML; | 44 | title1 = document.getElementById('start_title').innerHTML; |
| @@ -62,4 +62,4 @@ | |||
| 62 | 62 | ||
| 63 | <h3>Body</h3> | 63 | <h3>Body</h3> |
| 64 | <p id="diffview_body"></p> | 64 | <p id="diffview_body"></p> |
| 65 | </div> \ No newline at end of file | 65 | </div> |
diff --git a/app/views/revisions/index.html.erb b/app/views/revisions/index.html.erb index dc9ad51..b875a4f 100644 --- a/app/views/revisions/index.html.erb +++ b/app/views/revisions/index.html.erb | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | <h2>Revisions for Node: <%= @node.unique_name %></h2> | 5 | <h2>Revisions for Node: <%= @node.unique_name %></h2> |
| 6 | 6 | ||
| 7 | <% form_tag diff_node_revisions_path(@node) do %> | ||
| 8 | <table id="revisions"> | 7 | <table id="revisions"> |
| 9 | <tr class="header"> | 8 | <tr class="header"> |
| 10 | <th>First</th> | 9 | <th>First</th> |
| @@ -14,8 +13,9 @@ | |||
| 14 | <th>Editor</th> | 13 | <th>Editor</th> |
| 15 | <th>Date</th> | 14 | <th>Date</th> |
| 16 | <th></th> | 15 | <th></th> |
| 16 | <th></th> | ||
| 17 | </tr> | 17 | </tr> |
| 18 | <% @node.pages.reverse.each do |page| %> | 18 | <% (@pages || @node.pages.all).reverse.each do |page| %> |
| 19 | <tr> | 19 | <tr> |
| 20 | <td><%= radio_button_tag :start_revision, page.revision %></td> | 20 | <td><%= radio_button_tag :start_revision, page.revision %></td> |
| 21 | <td><%= radio_button_tag :end_revision, page.revision %></td> | 21 | <td><%= radio_button_tag :end_revision, page.revision %></td> |
| @@ -23,22 +23,36 @@ | |||
| 23 | <td class="title"><%= page.title %></td> | 23 | <td class="title"><%= page.title %></td> |
| 24 | <td class="user"><%= page.editor.try(:login) %></td> | 24 | <td class="user"><%= page.editor.try(:login) %></td> |
| 25 | <td class="date"><%= page.updated_at %></td> | 25 | <td class="date"><%= page.updated_at %></td> |
| 26 | <td><%= link_to 'show', node_revision_path(@node, page) %></td> | ||
| 26 | <td> | 27 | <td> |
| 27 | <%= link_to 'show', node_revision_path(@node, page) %> | 28 | <%= button_to 'restore', restore_node_revision_path(@node, page), |
| 28 | </td> | 29 | method: :put, |
| 29 | <td> | 30 | form: { data: { confirm: "Restore this revision?" } } %> |
| 30 | <%= link_to( | ||
| 31 | 'restore', | ||
| 32 | restore_node_revision_path(@node, page), | ||
| 33 | :method => :put, | ||
| 34 | :confirm => "Restore this revision?" | ||
| 35 | ) %> | ||
| 36 | </td> | 31 | </td> |
| 37 | </tr> | 32 | </tr> |
| 38 | <% end %> | 33 | <% end %> |
| 39 | <tr class="no_hover"> | 34 | <tr class="no_hover"> |
| 40 | <td colspan="8" class="right"><%= submit_tag 'Diff revisions' %></td> | 35 | <td colspan="8" class="right"> |
| 36 | <%= button_to 'Diff revisions', diff_node_revisions_path(@node), | ||
| 37 | method: :post, | ||
| 38 | form: { id: 'diff_form' } %> | ||
| 39 | </td> | ||
| 41 | </tr> | 40 | </tr> |
| 42 | </table> | 41 | </table> |
| 43 | 42 | ||
| 44 | <% end %> \ No newline at end of file | 43 | <script> |
| 44 | document.getElementById('diff_form').addEventListener('submit', function(e) { | ||
| 45 | var start = document.querySelector('input[name="start_revision"]:checked'); | ||
| 46 | var end = document.querySelector('input[name="end_revision"]:checked'); | ||
| 47 | if (start) { | ||
| 48 | var s = document.createElement('input'); | ||
| 49 | s.type = 'hidden'; s.name = 'start_revision'; s.value = start.value; | ||
| 50 | this.appendChild(s); | ||
| 51 | } | ||
| 52 | if (end) { | ||
| 53 | var en = document.createElement('input'); | ||
| 54 | en.type = 'hidden'; en.name = 'end_revision'; en.value = end.value; | ||
| 55 | this.appendChild(en); | ||
| 56 | } | ||
| 57 | }); | ||
| 58 | </script> | ||
diff --git a/app/views/rss/recent_changes.xml.builder b/app/views/rss/recent_changes.xml.builder index c3b3ec9..cce3b5d 100644 --- a/app/views/rss/recent_changes.xml.builder +++ b/app/views/rss/recent_changes.xml.builder | |||
| @@ -2,19 +2,19 @@ xml.instruct! | |||
| 2 | 2 | ||
| 3 | xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | 3 | xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do |
| 4 | xml.title("CCC.de Recent Change") | 4 | xml.title("CCC.de Recent Change") |
| 5 | xml.link(:href => "http://www.ccc.de/") | 5 | xml.link(:href => "https://www.ccc.de/") |
| 6 | xml.link(:rel => "self", :href => "/rss/updates.xml") | 6 | xml.link(:rel => "self", :href => "/rss/updates.xml") |
| 7 | xml.updated(@items.first.updated_at.xmlschema) | 7 | xml.updated(@items.first.updated_at.xmlschema) |
| 8 | xml.author do | 8 | xml.author do |
| 9 | xml.name("Chaos Computer Club e.V.") | 9 | xml.name("Chaos Computer Club e.V.") |
| 10 | end | 10 | end |
| 11 | xml.id("http://www.ccc.de/") | 11 | xml.id("https://www.ccc.de/") |
| 12 | 12 | ||
| 13 | @items.each do |item| | 13 | @items.each do |item| |
| 14 | xml.entry do | 14 | xml.entry do |
| 15 | xml.title(item.title) | 15 | xml.title(item.title) |
| 16 | xml.link( | 16 | xml.link( |
| 17 | :href => "http://www.ccc.de/#{item.node.unique_path}", | 17 | :href => "https://www.ccc.de/#{item.node.unique_path}", |
| 18 | :rel => "alternate" | 18 | :rel => "alternate" |
| 19 | ) | 19 | ) |
| 20 | xml.id(content_url_helper(item.node.unique_path)) | 20 | xml.id(content_url_helper(item.node.unique_path)) |
| @@ -26,4 +26,4 @@ xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | |||
| 26 | 26 | ||
| 27 | end | 27 | end |
| 28 | 28 | ||
| 29 | end \ No newline at end of file | 29 | end |
diff --git a/app/views/rss/updates.rdf.builder b/app/views/rss/updates.rdf.builder index 00b6242..b02d34f 100644 --- a/app/views/rss/updates.rdf.builder +++ b/app/views/rss/updates.rdf.builder | |||
| @@ -2,26 +2,26 @@ xml.instruct! | |||
| 2 | xml.tag!("rdf:RDF", "xmlns:rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "xmlns:dc" => "http://purl.org/dc/elements/1.1/", "xmlns" => "http://purl.org/rss/1.0/") do | 2 | xml.tag!("rdf:RDF", "xmlns:rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "xmlns:dc" => "http://purl.org/dc/elements/1.1/", "xmlns" => "http://purl.org/rss/1.0/") do |
| 3 | xml.tag!( "rdf:Description", "rdf:about" => "http://www.w3.org/TR/rdf-syntax-grammar", "dc:title"=>"RDF/XML Syntax Specification (Revised)") | 3 | xml.tag!( "rdf:Description", "rdf:about" => "http://www.w3.org/TR/rdf-syntax-grammar", "dc:title"=>"RDF/XML Syntax Specification (Revised)") |
| 4 | 4 | ||
| 5 | xml.channel do | 5 | xml.channel( "rdf:about" => "https://www.ccc.de/de/rss/updates.xml" ) do |
| 6 | xml.title("Chaos Computer Club: Updates") | 6 | xml.title("Chaos Computer Club: Updates") |
| 7 | xml.link("http://www.ccc.de") | 7 | xml.link("https://www.ccc.de") |
| 8 | xml.description("Kabelsalat ist gesund.") | 8 | xml.description("Kabelsalat ist gesund.") |
| 9 | xml.tag!("dc:date", @items.first.published_at.xmlschema) | 9 | xml.tag!("dc:date", @items.first.published_at.xmlschema) |
| 10 | end | 10 | end |
| 11 | 11 | ||
| 12 | xml.image( "rdf:about" => "http://www.ccc.de/images/chaosknoten.gif") do | 12 | xml.image( "rdf:about" => "https://www.ccc.de/images/chaosknoten.gif") do |
| 13 | xml.title("Chaos Computer Club (Chaosknoten)") | 13 | xml.title("Chaos Computer Club (Chaosknoten)") |
| 14 | xml.link("http://www.ccc.de") | 14 | xml.link("https://www.ccc.de") |
| 15 | xml.url("http://www.ccc.de/images/chaosknoten.gif") | 15 | xml.url("https://www.ccc.de/images/chaosknoten.gif") |
| 16 | end | 16 | end |
| 17 | 17 | ||
| 18 | @items.each do |item| | 18 | @items.each do |item| |
| 19 | xml.item("rdf:about" => content_url(:page_path => item.node.unique_path)) do | 19 | xml.item("rdf:about" => content_url(:page_path => item.node.unique_path)) do |
| 20 | xml.title(item.title) | 20 | xml.title(CGI.escapeHTML(item.title.to_s)) |
| 21 | xml.link(content_url(:page_path => item.node.unique_path)) | 21 | xml.link(content_url(:page_path => item.node.unique_path)) |
| 22 | xml.description(item.abstract) | 22 | xml.description(CGI.escapeHTML(item.abstract.to_s)) |
| 23 | xml.tag!("dc:creator", item.user.login) | 23 | xml.tag!("dc:creator", (item.user ? item.user.login : "CCC")) |
| 24 | xml.tag!("dc:date", item.published_at.xmlschema) | 24 | xml.tag!("dc:date", item.published_at.xmlschema) |
| 25 | end | 25 | end |
| 26 | end | 26 | end |
| 27 | end \ No newline at end of file | 27 | end |
diff --git a/app/views/rss/updates.xml.builder b/app/views/rss/updates.xml.builder index c09c9c9..4b2e2f7 100644 --- a/app/views/rss/updates.xml.builder +++ b/app/views/rss/updates.xml.builder | |||
| @@ -2,17 +2,17 @@ xml.instruct! | |||
| 2 | 2 | ||
| 3 | xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | 3 | xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do |
| 4 | xml.title("Chaos Computer Club Updates") | 4 | xml.title("Chaos Computer Club Updates") |
| 5 | xml.link(:href => "http://www.ccc.de/") | 5 | xml.link(:href => "https://www.ccc.de/") |
| 6 | xml.link(:rel => "self", :href => "#{@host}/rss/updates") | 6 | xml.link(:rel => "self", :href => "#{@host}/rss/updates.xml") |
| 7 | xml.updated(@items.first.published_at.xmlschema) | 7 | xml.updated(@items.first.published_at.xmlschema) |
| 8 | xml.author do | 8 | xml.author do |
| 9 | xml.name("Chaos Computer Club e.V.") | 9 | xml.name("Chaos Computer Club e.V.") |
| 10 | end | 10 | end |
| 11 | xml.id("#{@host}/rss/updates") | 11 | xml.id("https://www.ccc.de/rss/updates") |
| 12 | 12 | ||
| 13 | @items.each do |item| | 13 | @items.each do |item| |
| 14 | xml.entry do | 14 | xml.entry do |
| 15 | xml.title(item.title) | 15 | xml.title(CGI.escapeHTML(item.title.to_s)) |
| 16 | xml.link( | 16 | xml.link( |
| 17 | :href => content_url(:page_path => item.node.unique_path), | 17 | :href => content_url(:page_path => item.node.unique_path), |
| 18 | :rel => "alternate", | 18 | :rel => "alternate", |
| @@ -21,6 +21,7 @@ xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | |||
| 21 | xml.id(content_url(:page_path => item.node.feed_id)) | 21 | xml.id(content_url(:page_path => item.node.feed_id)) |
| 22 | xml.updated(item.updated_at.xmlschema) | 22 | xml.updated(item.updated_at.xmlschema) |
| 23 | xml.published(item.published_at.xmlschema) | 23 | xml.published(item.published_at.xmlschema) |
| 24 | xml.summary(CGI.escapeHTML(item.abstract.to_s)) | ||
| 24 | xml.content(:type => "xhtml") do | 25 | xml.content(:type => "xhtml") do |
| 25 | xml.div(item.body, :xmlns => "http://www.w3.org/1999/xhtml") | 26 | xml.div(item.body, :xmlns => "http://www.w3.org/1999/xhtml") |
| 26 | end | 27 | end |
| @@ -28,4 +29,4 @@ xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | |||
| 28 | 29 | ||
| 29 | end | 30 | end |
| 30 | 31 | ||
| 31 | end \ No newline at end of file | 32 | end |
diff --git a/app/views/search/_search_result.html.erb b/app/views/search/_search_result.html.erb index 14898a2..6cd01f8 100644 --- a/app/views/search/_search_result.html.erb +++ b/app/views/search/_search_result.html.erb | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <% if node.head %> | 1 | <% if node and node.head %> |
| 2 | <div class="article_partial"> | 2 | <div class="article_partial" lang="<%= node.head.effective_lang %>"> |
| 3 | <h2 class="headline"><%= link_to node.head.title, content_path(node.unique_path) %></h2> | 3 | <h2 class="headline"><%= link_to node.head.title, content_path(node.unique_path) %></h2> |
| 4 | <p class="excerpt"><%= node.head.abstract %></p> | 4 | <p class="excerpt"><%= node.head.abstract %></p> |
| 5 | </div> | 5 | </div> |
| 6 | <% end %> \ No newline at end of file | 6 | <% end %> |
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index fef0912..3c10303 100644 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | <div id="login_form"> | 1 | <div id="login_form"> |
| 2 | <% form_tag session_path do -%> | 2 | <%= form_tag session_path do -%> |
| 3 | <table> | 3 | <table> |
| 4 | <tr> | 4 | <tr> |
| 5 | <td></td> | 5 | <td></td> |
| @@ -21,4 +21,4 @@ | |||
| 21 | </tr> | 21 | </tr> |
| 22 | </table> | 22 | </table> |
| 23 | <% end -%> | 23 | <% end -%> |
| 24 | </div> \ No newline at end of file | 24 | </div> |
diff --git a/app/views/users/_user.html.erb b/app/views/users/_user.html.erb index 8117bcd..ddb7afd 100644 --- a/app/views/users/_user.html.erb +++ b/app/views/users/_user.html.erb | |||
| @@ -7,13 +7,10 @@ | |||
| 7 | <%= link_to "edit", edit_user_path(user) %> | 7 | <%= link_to "edit", edit_user_path(user) %> |
| 8 | </td> | 8 | </td> |
| 9 | <td> | 9 | <td> |
| 10 | <%= link_to( | 10 | <%= button_to "destroy", user_path(user), |
| 11 | "destroy", | 11 | method: :delete, |
| 12 | user_path(user), | 12 | form: { data: { confirm: "Do you really want to delete user #{user.login}?" } } %> |
| 13 | :method => :delete, | ||
| 14 | :confirm => "Do you really want to delete user #{user.login}?" | ||
| 15 | ) %> | ||
| 16 | </td> | 13 | </td> |
| 17 | <% end %> | 14 | <% end %> |
| 18 | </tr> | 15 | </tr> |
| 19 | <% end %> \ No newline at end of file | 16 | <% end %> |
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 226e821..df1005b 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb | |||
| @@ -1,8 +1,13 @@ | |||
| 1 | <h1>Edit existing user</h1> | 1 | <h1>Edit existing user</h1> |
| 2 | 2 | ||
| 3 | <%= error_messages_for :user %> | 3 | <% if @user.errors.any? %> |
| 4 | <div class="error_messages"> | ||
| 5 | <ul><% @user.errors.full_messages.each do |msg| %><li><%= msg.gsub("Slug", "Title") %></li><% end %></ul> | ||
| 6 | </div> | ||
| 7 | <% end %> | ||
| 4 | 8 | ||
| 5 | <% form_for @user do |f| %> | 9 | |
| 10 | <%= form_for @user do |f| %> | ||
| 6 | <table id="new_node"> | 11 | <table id="new_node"> |
| 7 | <tr> | 12 | <tr> |
| 8 | <td class="description">Login</td> | 13 | <td class="description">Login</td> |
| @@ -31,4 +36,4 @@ | |||
| 31 | <td class="right"><%= f.submit "Update" %></td> | 36 | <td class="right"><%= f.submit "Update" %></td> |
| 32 | </tr> | 37 | </tr> |
| 33 | </table> | 38 | </table> |
| 34 | <% end %> \ No newline at end of file | 39 | <% end %> |
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 6990c27..6beda4f 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb | |||
| @@ -1,8 +1,13 @@ | |||
| 1 | <h1>Create new user</h1> | 1 | <h1>Create new user</h1> |
| 2 | 2 | ||
| 3 | <%= error_messages_for :user %> | 3 | <% if @user.errors.any? %> |
| 4 | <div class="error_messages"> | ||
| 5 | <ul><% @user.errors.full_messages.each do |msg| %><li><%= msg.gsub("Slug", "Title") %></li><% end %></ul> | ||
| 6 | </div> | ||
| 7 | <% end %> | ||
| 4 | 8 | ||
| 5 | <% form_for @user do |f| %> | 9 | |
| 10 | <%= form_for @user do |f| %> | ||
| 6 | <table id="new_node"> | 11 | <table id="new_node"> |
| 7 | <tr> | 12 | <tr> |
| 8 | <td class="description">Login</td> | 13 | <td class="description">Login</td> |
| @@ -29,4 +34,4 @@ | |||
| 29 | <td class="right"><%= f.submit "Create" %></td> | 34 | <td class="right"><%= f.submit "Create" %></td> |
| 30 | </tr> | 35 | </tr> |
| 31 | </table> | 36 | </table> |
| 32 | <% end %> \ No newline at end of file | 37 | <% end %> |
