wontomedia 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +661 -0
- data/COPYING.DOCUMENTATION +450 -0
- data/LICENSE +661 -0
- data/README.markdown +56 -0
- data/Rakefile +185 -0
- data/VERSION.yml +4 -0
- data/app/controllers/admin_controller.rb +144 -0
- data/app/controllers/application_controller.rb +29 -0
- data/app/controllers/connections_controller.rb +150 -0
- data/app/controllers/items_controller.rb +365 -0
- data/app/helpers/connections_helper.rb +67 -0
- data/app/helpers/format_helper.rb +154 -0
- data/app/helpers/items_helper.rb +105 -0
- data/app/models/category_item.rb +23 -0
- data/app/models/connection.rb +210 -0
- data/app/models/individual_item.rb +23 -0
- data/app/models/item.rb +86 -0
- data/app/models/property_item.rb +23 -0
- data/app/models/qualified_item.rb +23 -0
- data/app/views/admin/index.html.erb +74 -0
- data/app/views/connections/_index_outbound_links.html.erb +48 -0
- data/app/views/connections/_spo_select_controls.html.erb +151 -0
- data/app/views/connections/edit.html.erb +70 -0
- data/app/views/connections/index.html.erb +84 -0
- data/app/views/connections/new.html.erb +61 -0
- data/app/views/connections/show.html.erb +110 -0
- data/app/views/items/_active_content.html.erb +26 -0
- data/app/views/items/_content_examples.html.erb +55 -0
- data/app/views/items/_core_tasks.html.erb +23 -0
- data/app/views/items/_form_fields.html.erb +69 -0
- data/app/views/items/_list_outbound_links.html.erb +58 -0
- data/app/views/items/_screen_select.html.erb +24 -0
- data/app/views/items/_show_outbound_links.html.erb +70 -0
- data/app/views/items/_topic_list.html.erb +26 -0
- data/app/views/items/_type_select.html.erb +47 -0
- data/app/views/items/edit.html.erb +63 -0
- data/app/views/items/index.html.erb +74 -0
- data/app/views/items/new.html.erb +124 -0
- data/app/views/items/newpop.html.erb +58 -0
- data/app/views/items/show.html.erb +209 -0
- data/app/views/layouts/_amazon_ads.html.erb +55 -0
- data/app/views/layouts/_glossary_help_box.html.erb +43 -0
- data/app/views/layouts/_google_ads.html.erb +40 -0
- data/app/views/layouts/_language_select.html.erb +24 -0
- data/app/views/layouts/_login_controls.html.erb +24 -0
- data/app/views/layouts/_master_help.html.erb +24 -0
- data/app/views/layouts/_navigation_menu.html.erb +39 -0
- data/app/views/layouts/_search_box.html.erb +27 -0
- data/app/views/layouts/_status_msgs.html.erb +25 -0
- data/app/views/layouts/application.html.erb +67 -0
- data/app/views/layouts/base.html.erb +93 -0
- data/app/views/layouts/home.html.erb +67 -0
- data/app/views/layouts/popup.html.erb +23 -0
- data/assets/wontomedia-sample.rb +47 -0
- data/config/asset_packages.yml +44 -0
- data/config/boot.rb +110 -0
- data/config/cucumber.yml +65 -0
- data/config/database-mysql-development.yml +47 -0
- data/config/database-mysql.yml +26 -0
- data/config/environment.rb +94 -0
- data/config/environments/cucumber.rb +29 -0
- data/config/environments/development.rb +26 -0
- data/config/environments/production.rb +33 -0
- data/config/environments/test.rb +31 -0
- data/config/initializers/inflections.rb +19 -0
- data/config/initializers/mime_types.rb +14 -0
- data/config/initializers/new_rails_defaults.rb +26 -0
- data/config/locales/en.yml +14 -0
- data/config/routes.rb +37 -0
- data/db/fixtures/connections.yml +96 -0
- data/db/fixtures/items.yml +277 -0
- data/db/migrate/20090312212805_create_items.rb +31 -0
- data/db/migrate/20090406221320_create_connections.rb +32 -0
- data/db/migrate/20090411014503_add_type_for_item_subclasses.rb +29 -0
- data/db/migrate/20090415142152_rename_item_type.rb +31 -0
- data/db/migrate/20090518022918_rename_object_and_self.rb +33 -0
- data/db/migrate/20090529171442_add_flags_to_items.rb +27 -0
- data/db/migrate/20090529171508_add_flags_to_connections.rb +27 -0
- data/db/migrate/20090605213800_flags_columns_not_null.rb +29 -0
- data/db/migrate/20090605215028_flags_columns_default_zero.rb +29 -0
- data/db/schema.rb +30 -0
- data/default-custom/app/views/items/_home_extern_list.html.erb +32 -0
- data/default-custom/app/views/items/_home_introductory_text.html.erb +70 -0
- data/default-custom/app/views/items/home.html.erb +77 -0
- data/default-custom/public/images/logo.png +0 -0
- data/default-custom/public/images/logo.svg +74 -0
- data/default-custom/public/stylesheets/wm.css +301 -0
- data/doc/README.markdown +44 -0
- data/doc/README_FOR_APP +82 -0
- data/doc/customization.markdown +93 -0
- data/doc/scripts/rake-customize.markdown +83 -0
- data/lib/helpers/connection_helper.rb +41 -0
- data/lib/helpers/item_helper.rb +141 -0
- data/lib/helpers/tripple_navigation.rb +158 -0
- data/lib/tasks/cucumber.rake +83 -0
- data/lib/tasks/customize.rake +70 -0
- data/lib/tasks/db.rake +65 -0
- data/lib/tasks/javascript_testing_tasks.rake +176 -0
- data/public/404.html +50 -0
- data/public/422.html +50 -0
- data/public/500.html +53 -0
- data/public/dispatch.cgi +20 -0
- data/public/dispatch.fcgi +34 -0
- data/public/dispatch.rb +20 -0
- data/public/favicon.ico +0 -0
- data/public/images/blank_error_icon.png +0 -0
- data/public/images/blank_status_icon.png +0 -0
- data/public/images/error_error_icon.png +0 -0
- data/public/images/error_status_icon.png +0 -0
- data/public/images/good_status_icon.png +0 -0
- data/public/images/help_icon.png +0 -0
- data/public/images/twitter_icon.png +0 -0
- data/public/images/warn_error_icon.png +0 -0
- data/public/images/working_status_icon.gif +0 -0
- data/public/javascripts/application.js +56 -0
- data/public/javascripts/controls.js +963 -0
- data/public/javascripts/dragdrop.js +973 -0
- data/public/javascripts/effects.js +1128 -0
- data/public/javascripts/event.simulate.js +64 -0
- data/public/javascripts/fancybox.js +43 -0
- data/public/javascripts/forConnectionsForms.js +218 -0
- data/public/javascripts/forItemsForms.js +511 -0
- data/public/javascripts/itemCreatePopup.js +115 -0
- data/public/javascripts/itemTitleToName.js +119 -0
- data/public/javascripts/jquery.js +4376 -0
- data/public/javascripts/modalbox.js +502 -0
- data/public/javascripts/prototype.js +4320 -0
- data/public/javascripts/reconcileJQueryAndPrototype.js +19 -0
- data/public/robots.txt +7 -0
- data/public/stylesheets/blank.gif +0 -0
- data/public/stylesheets/fancy_close.png +0 -0
- data/public/stylesheets/fancy_loading.png +0 -0
- data/public/stylesheets/fancy_nav_left.png +0 -0
- data/public/stylesheets/fancy_nav_right.png +0 -0
- data/public/stylesheets/fancy_shadow_e.png +0 -0
- data/public/stylesheets/fancy_shadow_n.png +0 -0
- data/public/stylesheets/fancy_shadow_ne.png +0 -0
- data/public/stylesheets/fancy_shadow_nw.png +0 -0
- data/public/stylesheets/fancy_shadow_s.png +0 -0
- data/public/stylesheets/fancy_shadow_se.png +0 -0
- data/public/stylesheets/fancy_shadow_sw.png +0 -0
- data/public/stylesheets/fancy_shadow_w.png +0 -0
- data/public/stylesheets/fancy_title_left.png +0 -0
- data/public/stylesheets/fancy_title_main.png +0 -0
- data/public/stylesheets/fancy_title_over.png +0 -0
- data/public/stylesheets/fancy_title_right.png +0 -0
- data/public/stylesheets/fancybox.css +333 -0
- data/public/stylesheets/modalbox.css +110 -0
- data/public/stylesheets/scaffold.css +36 -0
- data/public/stylesheets/spinner.gif +0 -0
- data/script/about +4 -0
- data/script/console +3 -0
- data/script/cucumber +10 -0
- data/script/dbconsole +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/performance/request +3 -0
- data/script/plugin +3 -0
- data/script/process/inspector +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/vendor/plugins/asset_packager/CHANGELOG +122 -0
- data/vendor/plugins/asset_packager/README +178 -0
- data/vendor/plugins/asset_packager/Rakefile +22 -0
- data/vendor/plugins/asset_packager/about.yml +8 -0
- data/vendor/plugins/asset_packager/init.rb +2 -0
- data/vendor/plugins/asset_packager/install.rb +1 -0
- data/vendor/plugins/asset_packager/lib/jsmin.rb +205 -0
- data/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb +212 -0
- data/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb +39 -0
- data/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake +23 -0
- data/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb +100 -0
- data/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb +140 -0
- data/vendor/plugins/asset_packager/test/asset_packager_test.rb +92 -0
- data/vendor/plugins/asset_packager/test/asset_packages.yml +20 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/application.js +2 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/bar.js +4 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/controls.js +815 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js +913 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/effects.js +958 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/foo.js +4 -0
- data/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js +2006 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css +16 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css +16 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/header.css +16 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css +16 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css +16 -0
- data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css +16 -0
- metadata +265 -0
@@ -0,0 +1,365 @@
|
|
1
|
+
#--
|
2
|
+
# WontoMedia - a wontology web application
|
3
|
+
# Copyright (C) 2010 - Glen E. Ivey
|
4
|
+
# www.wontology.com
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License version
|
8
|
+
# 3 as published by the Free Software Foundation.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program in the file COPYING and/or LICENSE. If not,
|
17
|
+
# see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
#### I've got no idea why this 'require' is necessary. Without it, all
|
22
|
+
# the unit tests pass, but the ItemHelper.nouns call below fails when
|
23
|
+
# run in production. Even more odd, if run in 'development' (so that
|
24
|
+
# each Ruby file is reloaded at each request, this 'require' only has
|
25
|
+
# to be present for the _first_ request serviced after the server
|
26
|
+
# starts. It can be deleted, this file reloaded, and then ItemHelper
|
27
|
+
# references will work normally. Go figure. -- gei 2010/2/24
|
28
|
+
require Rails.root.join( 'lib', 'helpers', 'item_helper')
|
29
|
+
require 'yaml'
|
30
|
+
|
31
|
+
# See also the matching model Item
|
32
|
+
class ItemsController < ApplicationController
|
33
|
+
# GET /
|
34
|
+
def home
|
35
|
+
@nouns = ItemHelper.nouns
|
36
|
+
render :layout => "home"
|
37
|
+
end
|
38
|
+
|
39
|
+
# GET /items
|
40
|
+
#
|
41
|
+
# Note that +index+ is capable of rendering in multiple
|
42
|
+
# formats. <tt>/items</tt> and <tt>/items.html</tt> yield a
|
43
|
+
# human-readable page in HTML markup. <tt>/items.yaml</tt> renders
|
44
|
+
# all fields from all Items in the database as YAML-format text,
|
45
|
+
# with no additional prose or links intended for users.
|
46
|
+
def index
|
47
|
+
@items = Item.all.reverse
|
48
|
+
@not_in_use_hash = {}
|
49
|
+
@items.each do |item|
|
50
|
+
@not_in_use_hash[item.id] =
|
51
|
+
Connection.all( :conditions =>
|
52
|
+
[ "subject_id = ? OR predicate_id = ? OR obj_id = ?",
|
53
|
+
item.id, item.id, item.id ]).
|
54
|
+
empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
respond_to do |wants|
|
58
|
+
wants.html
|
59
|
+
wants.yaml do
|
60
|
+
render :text =>
|
61
|
+
@items.reject { |item|
|
62
|
+
(item.flags & Item::DATA_IS_UNALTERABLE) != 0 }.
|
63
|
+
to_yaml
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# GET /items/new
|
69
|
+
def new
|
70
|
+
@this_is_non_information_page = true
|
71
|
+
@item = Item.new
|
72
|
+
end
|
73
|
+
|
74
|
+
# GET /items/new-pop
|
75
|
+
#
|
76
|
+
# This operation is intended to provide a version of
|
77
|
+
# <tt>/items/new</tt> suitable for Ajax fetching fromm and display
|
78
|
+
# in a pop-up <tt><div></tt> in an already-rendered page. Correct
|
79
|
+
# operation of the page fragment rendered by this action depends on
|
80
|
+
# the surrounding page having already loaded the form's JavaScript
|
81
|
+
# and style dependencies. Implementing this behavior depends on the
|
82
|
+
# <tt>popup_flag</tt> field passed between Items +actions+ and
|
83
|
+
# +views+; see their source for additional details.
|
84
|
+
def newpop
|
85
|
+
@item = Item.new
|
86
|
+
@type = params[:type]
|
87
|
+
render :layout => "popup"
|
88
|
+
end
|
89
|
+
|
90
|
+
# POST /items
|
91
|
+
def create
|
92
|
+
type_string = params[:item][:sti_type]
|
93
|
+
params[:item].delete :sti_type # don't mass-assign protected blah, blah
|
94
|
+
@item = ItemHelper.new_typed_item(type_string, params[:item])
|
95
|
+
@popup_flag = true if params[:popup_flag]
|
96
|
+
|
97
|
+
if @item.nil?
|
98
|
+
flash.now[:error] =
|
99
|
+
'Could not create. Item must have a type of either "Category" or "Individual".'
|
100
|
+
@item = Item.new(params[:item]) # keep info already entered
|
101
|
+
@item.sti_type = type_string
|
102
|
+
@this_is_non_information_page = true
|
103
|
+
render :action => (@popup_flag ? "newpop" : "new" )
|
104
|
+
elsif @item.name =~ /[:.]/ || !@item.save
|
105
|
+
@item.errors.add :name, "cannot contain a period (.) or a colon (:)."
|
106
|
+
@this_is_non_information_page = true
|
107
|
+
render :action => (@popup_flag ? "newpop" : "new" )
|
108
|
+
else
|
109
|
+
if @popup_flag
|
110
|
+
@connection_list = []; @item_hash = {}; @connection_hash = {}
|
111
|
+
flash.now[:notice] = 'Item was successfully created.'
|
112
|
+
render :action => "show", :layout => "popup"
|
113
|
+
else
|
114
|
+
flash[:notice] = 'Item was successfully created.'
|
115
|
+
redirect_to item_path(@item)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# GET /items/1
|
121
|
+
#
|
122
|
+
# Note that +show+ is capable of rendering in multiple
|
123
|
+
# formats. <tt>/items/1</tt> and <tt>/items/1.html</tt> yield a
|
124
|
+
# human-readable page in HTML markup. <tt>/items/1.json</tt>
|
125
|
+
# renders all fields from the specified Item as JSON-format text,
|
126
|
+
# with no additional prose or links intended for users. In the JSON
|
127
|
+
# case, only information about the specific Item requested is
|
128
|
+
# returned. When a full web page is generated, information is
|
129
|
+
# included about all other Items which are involved in Connections
|
130
|
+
# that directly reference the requested Item.
|
131
|
+
def show
|
132
|
+
begin
|
133
|
+
@item = Item.find(params[:id])
|
134
|
+
rescue
|
135
|
+
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
|
136
|
+
return
|
137
|
+
end
|
138
|
+
|
139
|
+
if request.format.json?
|
140
|
+
# huge kludge for testability. Need to ensure that we don't respond
|
141
|
+
# so quickly (e.g., in setups where client and server are on the same
|
142
|
+
# system) that the JavaScript and acceptance tests can't see the
|
143
|
+
# "request in progress" state of the page/system.
|
144
|
+
if (RAILS_ENV == 'test')
|
145
|
+
Kernel.sleep(0.75)
|
146
|
+
end
|
147
|
+
|
148
|
+
render :json => @item
|
149
|
+
return
|
150
|
+
end
|
151
|
+
|
152
|
+
used_as_subj = Connection.all( :conditions =>
|
153
|
+
[ "subject_id = ?", @item.id ])
|
154
|
+
used_as_pred = Connection.all( :conditions =>
|
155
|
+
[ "predicate_id = ?", @item.id ])
|
156
|
+
used_as_obj = Connection.all( :conditions =>
|
157
|
+
[ "obj_id = ?", @item.id ])
|
158
|
+
|
159
|
+
@item_hash = {}
|
160
|
+
@connection_hash = {}
|
161
|
+
[ used_as_subj, used_as_pred, used_as_obj ].each do |connection_array|
|
162
|
+
connection_array.each do |connection|
|
163
|
+
unless @connection_hash.has_key? connection.id
|
164
|
+
@connection_hash[connection.id] = connection
|
165
|
+
[ connection.subject, connection.predicate, connection.obj ].
|
166
|
+
each do |item|
|
167
|
+
unless @item_hash.has_key? item.id
|
168
|
+
@item_hash[item.id] = item
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# now that we've got all the connections to display, order and group them
|
176
|
+
# @connection_list should be an array of arrays, each internal array is
|
177
|
+
# a "section" of the display page, containing .id's of connections
|
178
|
+
@connection_list = []
|
179
|
+
|
180
|
+
value_id = Item.find_by_name("value_relationship").id
|
181
|
+
spo_id = Item.find_by_name("sub_property_of").id
|
182
|
+
|
183
|
+
# first group, all connections *from* this item with value-type predicates
|
184
|
+
connections = []
|
185
|
+
connections_to_delete = []
|
186
|
+
used_as_subj.each do |connection|
|
187
|
+
if TrippleNavigation.check_properties(
|
188
|
+
:does => connection.predicate_id, :via => spo_id,
|
189
|
+
:inherit_from => value_id )
|
190
|
+
connections << connection.id
|
191
|
+
connections_to_delete << connection
|
192
|
+
end
|
193
|
+
end
|
194
|
+
used_as_subj -= connections_to_delete # done incrementally, breaks iterator
|
195
|
+
unless connections.empty?
|
196
|
+
@connection_list << connections
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
# next N groups: 1 group for connections *from* this item with >1 of
|
201
|
+
# same pred.
|
202
|
+
#figure out which predicates occur >1, how many they occur, sort & group
|
203
|
+
pred_counts = {}
|
204
|
+
connection_using_pred = {}
|
205
|
+
used_as_subj.each do |connection|
|
206
|
+
if pred_counts[connection.predicate_id].nil?
|
207
|
+
pred_counts[connection.predicate_id] = 1
|
208
|
+
else
|
209
|
+
pred_counts[connection.predicate_id] += 1
|
210
|
+
end
|
211
|
+
connection_using_pred[connection.predicate_id] = connection.id
|
212
|
+
end
|
213
|
+
subj_connections = pred_counts.keys
|
214
|
+
subj_connections.sort! { |a,b| pred_counts[b] <=> pred_counts[a] }
|
215
|
+
array_of_singles = []
|
216
|
+
subj_connections.each do |predicate_id|
|
217
|
+
if pred_counts[predicate_id] > 1
|
218
|
+
connections = []
|
219
|
+
used_as_subj.each do |connection|
|
220
|
+
# lazy, more hashes would eliminate rescan
|
221
|
+
if connection.predicate_id == predicate_id
|
222
|
+
connections << connection.id
|
223
|
+
end
|
224
|
+
end
|
225
|
+
unless connections.empty?
|
226
|
+
@connection_list << connections
|
227
|
+
end
|
228
|
+
else
|
229
|
+
array_of_singles << connection_using_pred[predicate_id]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# last group of connections *from* current item:
|
234
|
+
# all connections w/ used-once pred's
|
235
|
+
unless array_of_singles.empty?
|
236
|
+
@connection_list << array_of_singles
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
obj_connections = used_as_obj.map { |connection| connection.id }
|
241
|
+
obj_connections.sort! do |a,b|
|
242
|
+
if @connection_hash[a].predicate_id == @connection_hash[b].predicate_id
|
243
|
+
@connection_hash[a].obj_id <=> @connection_hash[b].obj_id
|
244
|
+
else
|
245
|
+
@connection_hash[a].predicate_id <=> @connection_hash[b].predicate_id
|
246
|
+
end
|
247
|
+
end
|
248
|
+
unless obj_connections.empty?
|
249
|
+
@connection_list << obj_connections
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
pred_connections = used_as_pred.map { |connection| connection.id }
|
254
|
+
unless pred_connections.empty?
|
255
|
+
@connection_list << pred_connections
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# GET /items/1/edit
|
260
|
+
def edit
|
261
|
+
begin
|
262
|
+
@this_is_non_information_page = true
|
263
|
+
@item = Item.find(params[:id])
|
264
|
+
rescue
|
265
|
+
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
|
266
|
+
return
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# PUT /items/1
|
271
|
+
def update
|
272
|
+
# we want to be agnostic WRT processing item subclasses, so remap
|
273
|
+
# name of incoming parameters if we're actually handling a child
|
274
|
+
params.each do |k,v|
|
275
|
+
if k =~ /_item/
|
276
|
+
params["item"] = v
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
begin
|
281
|
+
@item = ItemHelper.find_typed_item(params[:id])
|
282
|
+
rescue
|
283
|
+
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
|
284
|
+
return
|
285
|
+
end
|
286
|
+
|
287
|
+
if (@item.flags & Item::DATA_IS_UNALTERABLE) != 0
|
288
|
+
flash[:error] = 'This Item cannot be altered.'
|
289
|
+
redirect_to item_path(@item)
|
290
|
+
elsif (!params[:item].nil? && !params[:item][:name].nil? &&
|
291
|
+
params[:item][:name] =~ /[:.]/ ) ||
|
292
|
+
!@item.update_attributes(params[:item])
|
293
|
+
@item.errors.add :name, "cannot contain a period (.) or a colon (:)."
|
294
|
+
@this_is_non_information_page = true
|
295
|
+
render :action => "edit"
|
296
|
+
else
|
297
|
+
flash[:notice] = 'Item was successfully updated.'
|
298
|
+
redirect_to item_path(@item)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
# DELETE /items/1
|
303
|
+
def destroy
|
304
|
+
begin
|
305
|
+
@item = Item.find(params[:id])
|
306
|
+
rescue
|
307
|
+
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
|
308
|
+
return
|
309
|
+
end
|
310
|
+
|
311
|
+
if (@item.flags & Item::DATA_IS_UNALTERABLE) != 0
|
312
|
+
flash[:error] = 'This Item cannot be altered.'
|
313
|
+
redirect_to item_path(@item)
|
314
|
+
elsif !(Connection.all( :conditions =>
|
315
|
+
[ "subject_id = ? OR predicate_id = ? OR obj_id = ?",
|
316
|
+
@item.id, @item.id, @item.id ]).empty?)
|
317
|
+
flash[:error] = 'This Item is in use by 1+ Connections. ' +
|
318
|
+
'Those must be modified or deleted first.'
|
319
|
+
redirect_to item_path(@item)
|
320
|
+
else
|
321
|
+
@item.destroy
|
322
|
+
redirect_to items_url
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# GET /items/lookup?name=anItemName
|
327
|
+
#
|
328
|
+
# This operation is similar to an abbreviated +show+. It always
|
329
|
+
# sends an HTML fragment (not a complete/valid page) to the
|
330
|
+
# requester, either an error message (plus <tt>:status => 404</tt>,
|
331
|
+
# if the requested item doesn't exist) or a string representation of
|
332
|
+
# the Item's +id+ field (plus <tt>:status => 200</tt>). While this
|
333
|
+
# is technically a RESTful request, it uses a string (rather than a
|
334
|
+
# database ID number as is the default for Rails requests) as the
|
335
|
+
# request parameter, and the parameter is encoded in the query
|
336
|
+
# string portion of the URL (rather than the path portion, in order
|
337
|
+
# to simplify creation of the matching route).
|
338
|
+
#
|
339
|
+
# This request is primarily intended to be used by Ajax code
|
340
|
+
# executing within another page that has already been served by
|
341
|
+
# WontoMedia.
|
342
|
+
def lookup
|
343
|
+
# huge kludge for testability. Need to ensure that we don't respond
|
344
|
+
# so quickly (e.g., in setups where client and server are on the same
|
345
|
+
# system) that the JavaScript and acceptance tests can't see the
|
346
|
+
# "request in progress" state of the page/system.
|
347
|
+
if (RAILS_ENV == 'test')
|
348
|
+
Kernel.sleep(0.75)
|
349
|
+
end
|
350
|
+
|
351
|
+
begin
|
352
|
+
item = Item.find_by_name(params[:name])
|
353
|
+
if item.nil?
|
354
|
+
render :text => "<p>Didn't find Item</p>\n", :status => 404
|
355
|
+
return
|
356
|
+
end
|
357
|
+
id = item.id
|
358
|
+
rescue
|
359
|
+
render :text => "<p>Didn't find Item</p>\n", :status => 404
|
360
|
+
return
|
361
|
+
end
|
362
|
+
|
363
|
+
render :text => ("<id>" + id.to_s + "</id>\n")
|
364
|
+
end
|
365
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#--
|
2
|
+
# WontoMedia - a wontology web application
|
3
|
+
# Copyright (C) 2010 - Glen E. Ivey
|
4
|
+
# www.wontology.com
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License version
|
8
|
+
# 3 as published by the Free Software Foundation.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program in the file COPYING and/or LICENSE. If not,
|
17
|
+
# see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
# Helpers for app/views/connections/* pages
|
22
|
+
module ConnectionsHelper
|
23
|
+
|
24
|
+
# This method appends its output directly to the page being built.
|
25
|
+
# It takes a Connection model instance, and generates a set of HTML
|
26
|
+
# links to that connection. It generates a "Show" link to the
|
27
|
+
# Connection's <tt>connections/show</tt> page. Unless the
|
28
|
+
# Connection is flagged as <tt>DATA_IS_UNALTERABLE</tt>, it also
|
29
|
+
# generates an "Edit..." link to +con+'s <tt>connections/edit</tt>
|
30
|
+
# page and a "Delete" link that will invoke
|
31
|
+
# <tt>connections/destroy</tt>. The links are generated with a
|
32
|
+
# "help" icon linking to a popup (see
|
33
|
+
# FormatHelper.link_with_help_icon) _if_ the link being generated is
|
34
|
+
# the first occurrance of that link in the current view. An instance
|
35
|
+
# variable is created within the current view object to flag the
|
36
|
+
# generation of each type of link.
|
37
|
+
def generate_connection_links(con)
|
38
|
+
concat(
|
39
|
+
link_with_help_icon({
|
40
|
+
:destination => link_to( 'Show', connection_path(con) ),
|
41
|
+
:already_generated => @show_help_icon_used,
|
42
|
+
:help_alt => 'Help show connection',
|
43
|
+
:which_help => 'ConnectionShow' }) )
|
44
|
+
@show_help_icon_used = true
|
45
|
+
|
46
|
+
if (con.flags & Connection::DATA_IS_UNALTERABLE) == 0
|
47
|
+
concat(
|
48
|
+
link_with_help_icon({
|
49
|
+
:destination => link_to(
|
50
|
+
'Edit…', edit_connection_path(con), :rel => 'nofollow' ),
|
51
|
+
:already_generated => @edit_help_icon_used,
|
52
|
+
:help_alt => 'Help edit connection',
|
53
|
+
:which_help => 'ConnectionEdit' }) )
|
54
|
+
@edit_help_icon_used = true
|
55
|
+
|
56
|
+
concat(
|
57
|
+
link_with_help_icon({
|
58
|
+
:destination => link_to(
|
59
|
+
'Delete', connection_path(con), :rel => 'nofollow',
|
60
|
+
:confirm => 'Are you sure?', :method => :delete ),
|
61
|
+
:already_generated => @delete_help_icon_used,
|
62
|
+
:help_alt => 'Help delete connection',
|
63
|
+
:which_help =>'ConnectionDelete' }) )
|
64
|
+
@delete_help_icon_used = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
#--
|
2
|
+
# WontoMedia - a wontology web application
|
3
|
+
# Copyright (C) 2010 - Glen E. Ivey
|
4
|
+
# www.wontology.com
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License version
|
8
|
+
# 3 as published by the Free Software Foundation.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program in the file COPYING and/or LICENSE. If not,
|
17
|
+
# see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
# This module contains a collection of page- and model-independent
|
22
|
+
# formatting methods. All return a string suitable for including
|
23
|
+
# directly in a page.
|
24
|
+
module FormatHelper
|
25
|
+
|
26
|
+
# This method takes in a string, and returns a version of it
|
27
|
+
# excluding any sub-strings enclosed in parentheticals. Nested and
|
28
|
+
# multiple parentheticals are supported. This method is intended to
|
29
|
+
# support the WontoMedia behavior where sometimes an Item.title
|
30
|
+
# string is displayed in its entirety, and sometimes it is
|
31
|
+
# abbreviated (for space) by stripping any parentheticals it contains.
|
32
|
+
def filter_parenthetical(title_in)
|
33
|
+
local_copy = title_in
|
34
|
+
begin
|
35
|
+
title_out = local_copy
|
36
|
+
local_copy = local_copy.sub(/\s*\([^()]*\)/, "")
|
37
|
+
end until local_copy == title_out
|
38
|
+
title_out
|
39
|
+
end
|
40
|
+
|
41
|
+
# This method is used to wrap long strings that don't contain spaces
|
42
|
+
# (which would allow the browser to wrap them), such as an
|
43
|
+
# <tt>Item.name</tt> string. The +len+ parameter is a length in
|
44
|
+
# _characters_, and the default is tuned to produce reasonably good
|
45
|
+
# results in the table in the items/index page. The return value is
|
46
|
+
# an HTML snippet including a marker to indicate that wrapping has
|
47
|
+
# occurred.
|
48
|
+
#--
|
49
|
+
# TODO: It would be better if wrapping were done
|
50
|
+
# dynamically in JavaScript as the page is resized, as sometimes
|
51
|
+
# wrapping the string statically doesn't produce a really great
|
52
|
+
# result. Of course, to really do it right, we'd rewrap any time
|
53
|
+
# the page width is adjusted, and use the actual width of the text
|
54
|
+
# (rather than character count) as the basis for wrapping.
|
55
|
+
def wrap_item_name(name, len = 30)
|
56
|
+
wrapped = ''
|
57
|
+
[ len, len*2, len*3, len*4 ].each do |wrap_at|
|
58
|
+
wrapped += name[wrap_at - len, len].to_s
|
59
|
+
if name.length > wrap_at
|
60
|
+
wrapped += '<span class="wrapper"> >>></span><br />'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
wrapped
|
64
|
+
end
|
65
|
+
|
66
|
+
# This method generates an HTML snipet for an icon that will cause a
|
67
|
+
# pop-up help box to be displayed when clicked. This helper is tied
|
68
|
+
# very tightly to WontoMedia's style sheet, included JavaScript
|
69
|
+
# libraries, and image assets. The parameters are used as follows:
|
70
|
+
#
|
71
|
+
# [alt] This string is used as the 'alt' attribute for the <img> tag that is generated, and allows each help image/link generated by this helper to have unique alt text that describes the kind of help the link points to.
|
72
|
+
# [target] This string specifies the source of the help page that should be rendered into the popup <iframe>. A complete URL is created by appending the value of +target+ to the configuration value <tt>WontoMedia.popup_url_prefix</tt> from the file <tt>config/initializers/wontomedia.rb</tt>.
|
73
|
+
# [text] The content of this string, if any, is placed immediately _before_ the popup help icon (the <img> tag) that this helper generates. This text is not part of the link that will cause the help popup to be opened. When present, the value is packaged along with the help icon in a <span> with the <tt>nowrap</tt> style. This will prevent the browser from separating the help icon from the label that precedes it due to text wrapping. If this argument is <tt>nil</tt>, then no span is generated. An empty string will produce a span with no content aside from the generated link.
|
74
|
+
def popup_help_icon( alt, target, text = nil )
|
75
|
+
content = ''
|
76
|
+
if text
|
77
|
+
content += '<span style="white-space: nowrap;">' + text
|
78
|
+
end
|
79
|
+
content += link_to(
|
80
|
+
(
|
81
|
+
image_tag( 'help_icon.png', :alt=>alt, :class=>'image-in-text' ) +
|
82
|
+
'<span class="tip">Help</span>'
|
83
|
+
),
|
84
|
+
WontoMedia.popup_url_prefix + target, :tabindex => '0',
|
85
|
+
:class => 'iframeBox linkhastip' )
|
86
|
+
if text
|
87
|
+
content += '</span>'
|
88
|
+
end
|
89
|
+
content
|
90
|
+
end
|
91
|
+
|
92
|
+
# This method wraps a block of text in HTML markup that provides it
|
93
|
+
# with a (CSS-based) 'tooltip'-like popup on mouse-over. The
|
94
|
+
# arguments are:
|
95
|
+
#
|
96
|
+
# [text] The text string to wrap and make sensitive to mouse-over. It may contain additional HTML markup, but cannot contain outbound links (e.g., <tt><a href=...></tt>).
|
97
|
+
# [tip] The content for the popup 'tooltip'. This may also contain HTML markup, but links should be avoided because of both usability considerations (moving the mouse within the tooltip can be challenging because it could go away if the cursors path strays outside the union of the text's and tip's bounding boxes) and the fact that some browsers will confuse links in the tooltip with the dummy link tag that this helper creates.
|
98
|
+
# [id] This helper creates a <tt><span></tt> tag around the supplied +text+. If +id+ is non-+nil+, its value will be used to create an +id+ attribute for the span.
|
99
|
+
def text_with_tooltip( text, tip, id = nil )
|
100
|
+
span = id.nil? ? '<span>' : "<span id='#{id}'>"
|
101
|
+
inner = "#{span}#{text}</span>" +
|
102
|
+
"<span class='tip' style='white-space: nowrap;'>#{tip}</span>"
|
103
|
+
link_to inner, "#", :class=>'texthastip', :tabindex=>'0'
|
104
|
+
end
|
105
|
+
|
106
|
+
# This method creates a link wraped in HTML markup that provides it
|
107
|
+
# with a (CSS-based) 'tooltip'-like popup on mouse-over. The
|
108
|
+
# arguments are:
|
109
|
+
#
|
110
|
+
# [text] The content for the link (anchor tag) generated. It may be any HTML string that would be valid within a link.
|
111
|
+
# [tip] The content for the popup 'tooltip'. This may also contain HTML markup, but links should be avoided because of both usability considerations (moving the mouse within the tooltip can be challenging because it could go away if the cursors path strays outside the union of the text's and tip's bounding boxes) and the fact that some browsers will confuse links in the tooltip with the link that causes the tooltip to be displayed.
|
112
|
+
# [href] The value of this argument will be used to generate the +href+ attribute of the link created. It is passed directly to Rails' <tt>link_to</tt> helper, so any string, or Rails object or route that can be converted to a URL can be used.
|
113
|
+
# [id] This helper creates a <tt><span></tt> tag around the content of the +text+ argument. If +id+ is non-+nil+, its value will be used to create an +id+ attribute for the span.
|
114
|
+
def link_with_tooltip( text, tip, href, id = nil )
|
115
|
+
span = id.nil? ? '<span>' : "<span id='#{id}'>"
|
116
|
+
inner = "#{span}#{text}</span>" +
|
117
|
+
"<span class='tip' style='white-space: nowrap;'>#{tip}</span>"
|
118
|
+
link_to inner, href, :class=>'linkhastip', :tabindex=>'0'
|
119
|
+
end
|
120
|
+
|
121
|
+
# This helper constructs a text link optionally followed by an image
|
122
|
+
# link which, when clicked, will open a popup box in the window
|
123
|
+
# populated by a page from the installation's help wiki. The markup
|
124
|
+
# generated ensures that word-wrap in the browser will not separate
|
125
|
+
# the help icon from the link that precedes it. The helper's
|
126
|
+
# parameters are packaged in a single hash argument. The symbols
|
127
|
+
# used to index the argument hash are:
|
128
|
+
#
|
129
|
+
# [:destination] The value in the hash associated with <tt>:destination</tt> should be a complete HTML link, such as the return value from the Rails' helper <tt>link_to</tt>.
|
130
|
+
# [:already_generated] The value in the hash associated with <tt>:already_generated</tt> will be evaluated as a boolean to determine whether a popup help icon (image link) should be generated by this call to link_with_help_icon. When it evaluates to false/nil (including simply not being present in the argument hash at all), HTML for a help icon _is_ generated/returned.
|
131
|
+
# [:help_alt] The string in the hash associated with <tt>:help_alt</tt> will be used as the value for the +alt+ attribute of the anchor tag for the help icon/link (if generated). (The +alt+ tag, if any, for <tt>:destination</tt> should be incorporated in the link's markup before it is passed to this helper.)
|
132
|
+
# [:which_help] The string in the hash associated with <tt>:which_help</tt> is used as a component in the URL to the desired page from the installation's help wiki. It is combined with the installation's popup_url_prefix configuration value (see popup_help_icon) after being prefixed with <tt>Help:Popup/</tt>. That is, this helper assumes that within the help wiki, the content for all help displayed in a popup box in the page is stored as a <em>sub-page</em> of the help wiki's page +Popup+ within the wiki's namespace +Help+.
|
133
|
+
# [:text] The _optional_ value in the hash associated with <tt>:text</tt> will, if present, be included in the generated HTML between the content of <tt>:destination</tt> and the generated help icon. See the +text+ argument to popup_help_icon.
|
134
|
+
def link_with_help_icon( params )
|
135
|
+
help_link = ''
|
136
|
+
unless params[:already_generated]
|
137
|
+
unless params.has_key?(:help_alt)
|
138
|
+
raise ArgumentError, "Missing :help_alt entry from parameter hash"
|
139
|
+
end
|
140
|
+
unless params.has_key?(:which_help)
|
141
|
+
raise ArgumentError, "Missing :which_help entry from parameter hash"
|
142
|
+
end
|
143
|
+
|
144
|
+
help_link = popup_help_icon params[:help_alt],
|
145
|
+
("Help:Popup/" + params[:which_help]), params[:text]
|
146
|
+
end
|
147
|
+
|
148
|
+
unless params.has_key?(:destination)
|
149
|
+
raise ArgumentError, "Missing :destination entry from parameter hash"
|
150
|
+
end
|
151
|
+
return content_tag( 'span', params[:destination] + help_link,
|
152
|
+
:style => "white-space: nowrap;" ) + " "
|
153
|
+
end
|
154
|
+
end
|