fabulator-exhibit 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/features/simple-database.feature +5 -1
- data/features/step_definitions/exhibit_steps.rb +4 -4
- data/features/step_definitions/template_steps.rb +72 -0
- data/features/step_definitions/xml_steps.rb +2 -2
- data/features/support/env.rb +2 -1
- data/features/templates.feature +82 -0
- data/lib/fabulator/exhibit/actions/item.rb +10 -9
- data/lib/fabulator/exhibit/actions/property.rb +1 -1
- data/lib/fabulator/exhibit/actions/type.rb +1 -1
- data/lib/fabulator/exhibit/actions/value.rb +2 -4
- data/lib/fabulator/exhibit/lib.rb +114 -0
- data/lib/fabulator/exhibit.rb +1 -1
- data/xslt/exhibit-html.xsl +221 -0
- metadata +11 -8
- data/lib/fabulator/exhibit/actions.rb +0 -124
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.0.4 2010-10-26
|
2
|
+
|
3
|
+
* 3 major enhancement:
|
4
|
+
* Works with Fabulator 0.0.9 and later
|
5
|
+
* Moved Fabulator::Exhibit::Actions::Lib to Fabulator::Exhibit::Lib
|
6
|
+
* Provides markup for exhibits in Fabulator views
|
7
|
+
|
1
8
|
=== 0.0.3 2010-09-07
|
2
9
|
|
3
10
|
* 1 major enhancement:
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ begin
|
|
7
7
|
gem.email = "jgsmith@tamu.edu"
|
8
8
|
gem.homepage = "http://github.com/jgsmith/ruby-fabulator-exhibit"
|
9
9
|
gem.authors = ["James Smith"]
|
10
|
-
gem.add_dependency('fabulator', '>= 0.0.
|
10
|
+
gem.add_dependency('fabulator', '>= 0.0.9')
|
11
11
|
gem.add_dependency('uuid', '>= 2.1.0')
|
12
12
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
13
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
@@ -13,6 +13,9 @@ Feature: Simple database items
|
|
13
13
|
<ex:item ex:id="'foo'" ex:type="fooType" ex:label="'fooLabel'">
|
14
14
|
<ex:value ex:name="bar" f:select="'baz'" />
|
15
15
|
</ex:item>
|
16
|
+
<ex:item ex:id="'bar'" ex:type="fooType" ex:label="'barLabel'">
|
17
|
+
<ex:value ex:name="bar" f:select="'bat'" />
|
18
|
+
</ex:item>
|
16
19
|
</ex:database>
|
17
20
|
<ex:database>
|
18
21
|
<f:value f:path="/f" f:select="ex:item('foo')" />
|
@@ -21,9 +24,10 @@ Feature: Simple database items
|
|
21
24
|
</f:application>
|
22
25
|
"""
|
23
26
|
And using the 'test' database
|
24
|
-
Then there should be
|
27
|
+
Then there should be 2 items
|
25
28
|
And the item 'foo' should have type 'fooType'
|
26
29
|
And the item 'foo' should have the label 'fooLabel'
|
27
30
|
And the item 'foo' should have the property 'bar' as 'baz'
|
28
31
|
And the expression (/f/bar) should equal ['baz']
|
29
32
|
And the expression (/g/foo/bar) should equal ['baz']
|
33
|
+
And the expression (/g/bar/bar) should equal ['bat']
|
@@ -3,22 +3,22 @@ Given /the '(.*)' database/ do |n|
|
|
3
3
|
end
|
4
4
|
|
5
5
|
Then /there should be (\d+) items?/ do |n|
|
6
|
-
db = Fabulator::Exhibit::
|
6
|
+
db = Fabulator::Exhibit::Lib.fetch_database(@exhibit_db_nom)
|
7
7
|
db[:items].size.should == n.to_i
|
8
8
|
end
|
9
9
|
|
10
10
|
Then /^the item '(.*)' should have type '(.+)'$/ do |id, type|
|
11
|
-
db = Fabulator::Exhibit::
|
11
|
+
db = Fabulator::Exhibit::Lib.fetch_database(@exhibit_db_nom)
|
12
12
|
db[:items][id]['type'].should == type
|
13
13
|
end
|
14
14
|
|
15
15
|
Then /^the item '(.*)' should have the label '(.*)'$/ do |id, label|
|
16
|
-
db = Fabulator::Exhibit::
|
16
|
+
db = Fabulator::Exhibit::Lib.fetch_database(@exhibit_db_nom)
|
17
17
|
db[:items][id]['label'].should == label
|
18
18
|
end
|
19
19
|
|
20
20
|
Then /^the item '(.*)' should have the property '(.*)' as '(.*)'$/ do |id, prop_name, prop_value|
|
21
|
-
db = Fabulator::Exhibit::
|
21
|
+
db = Fabulator::Exhibit::Lib.fetch_database(@exhibit_db_nom)
|
22
22
|
db[:items][id][prop_name].should == prop_value
|
23
23
|
end
|
24
24
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Given /^the template$/ do |doc_xml|
|
2
|
+
@template_text = doc_xml
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I render the template$/ do
|
6
|
+
parser = Fabulator::Template::Parser.new
|
7
|
+
@template_result = parser.parse(@context, @template_text)
|
8
|
+
#puts @template_result.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
When /^I set the captions to:$/ do |caption_table|
|
12
|
+
captions = { }
|
13
|
+
caption_table.hashes.each do |h|
|
14
|
+
captions[h['path']] = h['caption']
|
15
|
+
end
|
16
|
+
|
17
|
+
@template_result.add_captions(captions)
|
18
|
+
end
|
19
|
+
|
20
|
+
When /^I set the defaults to:$/ do |caption_table|
|
21
|
+
captions = { }
|
22
|
+
ctx = @context.with_root(@context.root.anon_node(nil))
|
23
|
+
caption_table.hashes.each do |h|
|
24
|
+
ctx.set_value(h['path'], Fabulator::Expr::Literal.new(h['default']))
|
25
|
+
end
|
26
|
+
|
27
|
+
@template_result.add_default_values(ctx)
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^the rendered text should equal$/ do |doc|
|
31
|
+
r = @template_result.to_s
|
32
|
+
|
33
|
+
cmd = 'xmllint --c14n --nsclean -'
|
34
|
+
IO.popen(cmd, "r+") { |x|
|
35
|
+
x << r
|
36
|
+
x.close_write
|
37
|
+
r = x.readlines.join("")
|
38
|
+
}
|
39
|
+
IO.popen(cmd, "r+") { |x|
|
40
|
+
x << doc
|
41
|
+
x.close_write
|
42
|
+
doc = x.readlines.join("")
|
43
|
+
}
|
44
|
+
|
45
|
+
#@template_result.to_s.should == doc + "\n"
|
46
|
+
r = r.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s+</, ">\n<").gsub(/id=["']id\d+["']/, 'id=""')
|
47
|
+
doc = doc.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s+</, ">\n<").gsub(/id=["']id\d+["']/, 'id=""')
|
48
|
+
r.should == doc
|
49
|
+
end
|
50
|
+
|
51
|
+
Then /^the rendered html should equal$/ do |doc|
|
52
|
+
r = @template_result.to_html
|
53
|
+
|
54
|
+
cmd = 'xmllint --html --c14n --nsclean -'
|
55
|
+
IO.popen(cmd, "r+") { |x|
|
56
|
+
x << r
|
57
|
+
x.close_write
|
58
|
+
r = x.readlines.join("")
|
59
|
+
}
|
60
|
+
IO.popen(cmd, "r+") { |x|
|
61
|
+
x << doc
|
62
|
+
x.close_write
|
63
|
+
doc = x.readlines.join("")
|
64
|
+
}
|
65
|
+
|
66
|
+
#puts "html from template: #{r}"
|
67
|
+
#puts "html from doc : #{doc}"
|
68
|
+
|
69
|
+
r = r.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<").gsub(/id=["']id\d+(-.*?)?["']/, 'id="id\1"')
|
70
|
+
doc = doc.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<").gsub(/id=["']id\d+(-.*?)?["']/, 'id="id\1"')
|
71
|
+
r.should == doc
|
72
|
+
end
|
@@ -7,11 +7,11 @@ Given /the statemachine/ do |doc_xml|
|
|
7
7
|
@roots['data'] ||= @data
|
8
8
|
@context ||= Fabulator::Expr::Context.new
|
9
9
|
@context.root = @data
|
10
|
+
@compiler ||= Fabulator::Compiler.new
|
10
11
|
|
11
12
|
@parser ||= Fabulator::Expr::Parser.new
|
12
13
|
if @sm.nil?
|
13
|
-
@sm =
|
14
|
-
@sm.compile_xml(doc, @context)
|
14
|
+
@sm = @compiler.compile(doc)
|
15
15
|
else
|
16
16
|
@sm.compile_xml(doc, @context)
|
17
17
|
end
|
data/features/support/env.rb
CHANGED
@@ -4,11 +4,12 @@ $: << File.expand_path(File.dirname(__FILE__))+'/../../lib'
|
|
4
4
|
$: << File.expand_path(File.dirname(__FILE__))+'/../../../fabulator/lib'
|
5
5
|
|
6
6
|
require 'fabulator'
|
7
|
+
require 'fabulator/template'
|
7
8
|
require 'fabulator/exhibit'
|
8
9
|
require 'spec/expectations'
|
9
10
|
require 'xml/libxml'
|
10
11
|
|
11
|
-
Fabulator::Exhibit::
|
12
|
+
Fabulator::Exhibit::Lib.class_eval do
|
12
13
|
def self.fetch_database(nom)
|
13
14
|
@@dbs ||= { }
|
14
15
|
@@dbs[nom] ||= { :types => {}, :items => {}, :properties => {} }
|
@@ -0,0 +1,82 @@
|
|
1
|
+
@tmpl
|
2
|
+
Feature: Templates
|
3
|
+
|
4
|
+
@nst
|
5
|
+
Scenario: Rendering markup with namespaces
|
6
|
+
Given a context
|
7
|
+
And the template
|
8
|
+
"""
|
9
|
+
<div xmlns="http://dh.tamu.edu/ns/fabulator/1.0#"
|
10
|
+
xmlns:ex="http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
|
11
|
+
>
|
12
|
+
<ex:exhibit ex:database="00A">
|
13
|
+
<ex:collection ex:types="Point" />
|
14
|
+
<ex:map-view
|
15
|
+
ex:center="42.4603,-71.3494"
|
16
|
+
ex:zoom-level="10"
|
17
|
+
ex:select=".pointLatLong"
|
18
|
+
/>
|
19
|
+
<ex:list-facet ex:select=".label">
|
20
|
+
<ex:caption>Names</ex:caption>
|
21
|
+
</ex:list-facet>
|
22
|
+
<ex:tile-view>
|
23
|
+
<ex:caption>Points</ex:caption>
|
24
|
+
<ex:lens ex:types="Point">
|
25
|
+
<ex:title><ex:value ex:select=".label" /></ex:title>
|
26
|
+
<ex:body>
|
27
|
+
<ex:property-list>
|
28
|
+
<ex:property ex:select=".label">
|
29
|
+
<ex:caption>Label</ex:caption>
|
30
|
+
</ex:property>
|
31
|
+
<ex:property ex:select=".pointLatLong">
|
32
|
+
<ex:caption>Lat/Long</ex:caption>
|
33
|
+
</ex:property>
|
34
|
+
<ex:property ex:select=".documents">
|
35
|
+
<ex:caption>Documents</ex:caption>
|
36
|
+
</ex:property>
|
37
|
+
</ex:property-list>
|
38
|
+
</ex:body>
|
39
|
+
</ex:lens>
|
40
|
+
</ex:tile-view>
|
41
|
+
</ex:exhibit>
|
42
|
+
</div>
|
43
|
+
"""
|
44
|
+
When I render the template
|
45
|
+
Then the rendered html should equal
|
46
|
+
"""
|
47
|
+
<div>
|
48
|
+
<div class="fabulator-exhibit" source="00A" id="id" ex:exhibitlabel="">
|
49
|
+
<div ex:role="exhibit-collection" ex:itemtypes="Point"></div>
|
50
|
+
<div class="facets">
|
51
|
+
<div ex:role="facet" id="id" ex:expression=".label" ex:facetClass="List" ex:facetlabel="Names"></div>
|
52
|
+
</div>
|
53
|
+
<div class="views" id="id-views" ex:role="viewPanel">
|
54
|
+
<div ex:role="view" ex:viewclass="Map" id="id" ex:latlng=".pointLatLong" ex:center="42.4603,-71.3494" ex:zoom="10" ex:size="" ex:type="" ex:viewlabel="">
|
55
|
+
</div>
|
56
|
+
<div ex:role="view" class="view tile-view" ex:viewclass="Tile" id="id" ex:viewlabel="Points">
|
57
|
+
<div ex:role="lens" id="id" ex:itemtypes="Point" style="display: none;">
|
58
|
+
<div class="exhibit-lens-title"><span ex:content=".label"></span></div>
|
59
|
+
<div class="exhibit-lens-body">
|
60
|
+
<table class="exhibit-lens-properties">
|
61
|
+
<tbody>
|
62
|
+
<tr class="exhibit-lens-property">
|
63
|
+
<td class="exhibit-lens-property-name">Label: </td>
|
64
|
+
<td class="exhibit-lens-property-values"><span ex:content=".label"></span></td>
|
65
|
+
</tr>
|
66
|
+
<tr class="exhibit-lens-property">
|
67
|
+
<td class="exhibit-lens-property-name">Lat/Long: </td>
|
68
|
+
<td class="exhibit-lens-property-values"><span ex:content=".pointLatLong"></span></td>
|
69
|
+
</tr>
|
70
|
+
<tr class="exhibit-lens-property">
|
71
|
+
<td class="exhibit-lens-property-name">Documents: </td>
|
72
|
+
<td class="exhibit-lens-property-values"><span ex:content=".documents"></span></td>
|
73
|
+
</tr>
|
74
|
+
</tbody>
|
75
|
+
</table>
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
"""
|
@@ -21,9 +21,10 @@ module Fabulator
|
|
21
21
|
db = @database.run(ctx).first.to_s
|
22
22
|
|
23
23
|
items.each do |item|
|
24
|
-
info
|
25
|
-
|
26
|
-
|
24
|
+
ctx.set_scoped_info('exhibit/item/info', { })
|
25
|
+
self.run_actions(ctx.with_root(item))
|
26
|
+
info = ctx.get_scoped_info('exhibit/item/info')
|
27
|
+
|
27
28
|
info['id'] = (@id.run(ctx.with_root(item)).first.to_s rescue nil)
|
28
29
|
if self.mode == 'add'
|
29
30
|
if info['id'].nil?
|
@@ -32,9 +33,9 @@ module Fabulator
|
|
32
33
|
end
|
33
34
|
info['type'] = self.type(ctx.with_root(item)).first.to_s
|
34
35
|
info['label'] = self.label(ctx.with_root(item)).first.to_s
|
35
|
-
Fabulator::Exhibit::
|
36
|
+
Fabulator::Exhibit::Lib.add_info(db, :items, info)
|
36
37
|
elsif self.mode == 'remove' && !info['id'].nil?
|
37
|
-
Fabulator::Exhibit::
|
38
|
+
Fabulator::Exhibit::Lib.remove_info(db, :items, info['id'])
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -57,7 +58,7 @@ module Fabulator
|
|
57
58
|
scopeType = (self.scope_type(ctx).first.to_s rescue nil)
|
58
59
|
db = nil
|
59
60
|
if m == 'merge' || !scopeType.nil?
|
60
|
-
db = Fabulator::Exhibit::
|
61
|
+
db = Fabulator::Exhibit::Lib.fetch_database(nom)
|
61
62
|
if !db.nil? && m == 'overwrite' # !scope_type.nil? is a consequence
|
62
63
|
# remove any items of scope_type
|
63
64
|
db[:items].delete_if{ |k,v| v['type'] == scopeType }
|
@@ -66,14 +67,14 @@ module Fabulator
|
|
66
67
|
if db.nil?
|
67
68
|
db = { :items => {}, :types => {}, :properties => {} }
|
68
69
|
end
|
69
|
-
Fabulator::Exhibit::
|
70
|
+
Fabulator::Exhibit::Lib.set_database(nom, db)
|
70
71
|
|
71
72
|
begin
|
72
73
|
ret = self.run_actions(ctx)
|
73
74
|
ensure
|
74
|
-
Fabulator::Exhibit::
|
75
|
+
Fabulator::Exhibit::Lib.store_database(
|
75
76
|
nom,
|
76
|
-
Fabulator::Exhibit::
|
77
|
+
Fabulator::Exhibit::Lib.get_database(nom)
|
77
78
|
)
|
78
79
|
end
|
79
80
|
end
|
@@ -9,7 +9,7 @@ module Fabulator
|
|
9
9
|
|
10
10
|
def run(context, autovivify = false)
|
11
11
|
@context.with(context) do |ctx|
|
12
|
-
Fabulator::Exhibit::
|
12
|
+
Fabulator::Exhibit::Lib.add_info(
|
13
13
|
self.database(ctx).first.to_s,
|
14
14
|
:properties, {
|
15
15
|
'id' => self.name(ctx).first.to_s,
|
@@ -10,10 +10,8 @@ module Fabulator
|
|
10
10
|
|
11
11
|
def run(context, autovivify = false)
|
12
12
|
@context.with(context) do |ctx|
|
13
|
-
|
14
|
-
|
15
|
-
self.select(ctx).collect{ |s| s.value }
|
16
|
-
)
|
13
|
+
value = self.select(ctx).collect{ |s| s.value }
|
14
|
+
ctx.get_scoped_info('exhibit/item/info')[self.name(ctx).first.to_s] = value.empty? ? nil : (value.size == 1 ? value.first : value)
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Fabulator
|
2
|
+
EXHIBIT_NS = "http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
|
3
|
+
|
4
|
+
require 'fabulator/exhibit/actions/item'
|
5
|
+
require 'fabulator/exhibit/actions/property'
|
6
|
+
require 'fabulator/exhibit/actions/type'
|
7
|
+
require 'fabulator/exhibit/actions/value'
|
8
|
+
|
9
|
+
module Exhibit
|
10
|
+
class Lib < Fabulator::TagLib
|
11
|
+
|
12
|
+
@@databases = { }
|
13
|
+
|
14
|
+
namespace EXHIBIT_NS
|
15
|
+
|
16
|
+
action 'database', Actions::Database
|
17
|
+
action 'item', Actions::Item
|
18
|
+
action 'value', Actions::Value
|
19
|
+
action 'property', Actions::Property
|
20
|
+
action 'type', Actions::Type
|
21
|
+
|
22
|
+
presentations do
|
23
|
+
transformations_into.html do
|
24
|
+
xslt_from_file File.join(File.dirname(__FILE__), "..", "..", "..", "xslt", "exhibit-html.xsl")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
## should set up an empty database with :items, :types, and :properties
|
30
|
+
def self.fetch_database(nom)
|
31
|
+
raise "fetch_database is not implemented by the framework."
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.store_database(nom, data)
|
35
|
+
raise "store_database is not imeplemented by the framework."
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.get_database(nom)
|
39
|
+
@@databases[nom] ||= self.fetch_database(nom)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.set_database(nom, data)
|
43
|
+
@@databases[nom] = data
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.store_databases
|
47
|
+
@@databases.keys.each do |k|
|
48
|
+
self.store_database(k, @@databases[k])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.add_info(nom, t, item)
|
53
|
+
@@databases ||= {}
|
54
|
+
@@databases[nom] ||= self.fetch_database(nom)
|
55
|
+
@@databases[nom][t][item['id']] ||= { }
|
56
|
+
@@databases[nom][t][item['id']].merge!(item)
|
57
|
+
@@databases[nom][t][item['id']].each_pair do |k,v|
|
58
|
+
if v.nil? || (v.is_a?(Array) && v.empty?) ||
|
59
|
+
v.is_a?(String) && v == ""
|
60
|
+
@@databases[nom][t][item['id']].delete(k)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
case t
|
64
|
+
when :types, :properties
|
65
|
+
@@databases[nom][t][item['id']].delete(:id)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.remove_info(nom, t, id)
|
70
|
+
@@databases[nom] ||= self.fetch_database(nom)
|
71
|
+
return if @@databases[nom][t].empty?
|
72
|
+
@@databases[nom][t].delete(id)
|
73
|
+
end
|
74
|
+
|
75
|
+
function 'item' do |ctx, args|
|
76
|
+
# need to get at the 'global' ex:database attribute
|
77
|
+
nom = ctx.attribute(EXHIBIT_NS, 'database', { :inherited => true, :static => true })
|
78
|
+
db = Fabulator::Exhibit::Lib.get_database(nom)
|
79
|
+
args.collect{ |a|
|
80
|
+
id = a.to_s
|
81
|
+
i = db[:items][id]
|
82
|
+
r = ctx.root.anon_node(nil)
|
83
|
+
r.name = id
|
84
|
+
i.each_pair do |k,v|
|
85
|
+
next if k == "id"
|
86
|
+
v = [ v ] unless v.is_a?(Array)
|
87
|
+
v.each do |vv|
|
88
|
+
r.create_child(k,vv)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
r
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
## need to make this an iterator
|
96
|
+
function 'items' do |ctx, args|
|
97
|
+
nom = ctx.attribute(EXHIBIT_NS, 'database', { :inherited => true, :static => true })
|
98
|
+
db = Fabulator::Exhibit::Lib.get_database(nom)
|
99
|
+
ret = ctx.root.anon_node(nil)
|
100
|
+
db[:items].each_pair{ |id, item|
|
101
|
+
i = ret.create_child(id, nil)
|
102
|
+
item.each_pair do |k,v|
|
103
|
+
next if k == "id"
|
104
|
+
v = [ v ] unless v.is_a?(Array)
|
105
|
+
v.each do |vv|
|
106
|
+
i.create_child(k,vv)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
}
|
110
|
+
[ ret ]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/fabulator/exhibit.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'fabulator/exhibit/
|
1
|
+
require 'fabulator/exhibit/lib'
|
2
2
|
require 'fabulator/exhibit/version'
|
@@ -0,0 +1,221 @@
|
|
1
|
+
<?xml version="1.0" ?>
|
2
|
+
<xsl:stylesheet
|
3
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
4
|
+
xmlns:ex="http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
|
5
|
+
version="1.0"
|
6
|
+
>
|
7
|
+
<xsl:output
|
8
|
+
method="html"
|
9
|
+
indent="yes"
|
10
|
+
/>
|
11
|
+
|
12
|
+
<xsl:template match="@*|node()">
|
13
|
+
<xsl:copy>
|
14
|
+
<xsl:apply-templates select="@*|node()"/>
|
15
|
+
</xsl:copy>
|
16
|
+
</xsl:template>
|
17
|
+
|
18
|
+
<xsl:template match="ex:exhibit">
|
19
|
+
<div>
|
20
|
+
<xsl:attribute name="class">fabulator-exhibit</xsl:attribute>
|
21
|
+
<xsl:attribute name="source"><xsl:value-of select="@ex:database" /></xsl:attribute>
|
22
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
23
|
+
<xsl:attribute name="ex:exhibitLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
24
|
+
<xsl:if test="ex:counters"><xsl:attribute name="ex:counters"><xsl:value-of select="ex:counters/ex:single" />:<xsl:value-of select="ex:counters/ex:plural" /></xsl:attribute></xsl:if>
|
25
|
+
<xsl:apply-templates select="ex:collection" />
|
26
|
+
<div class="facets">
|
27
|
+
<xsl:apply-templates select="*[substring(local-name(.), string-length(local-name(.))-5) = '-facet']" />
|
28
|
+
</div>
|
29
|
+
<div class="views">
|
30
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" />-views</xsl:attribute>
|
31
|
+
<xsl:if test="count(*[substring(local-name(.), string-length(local-name(.))-4) = '-view']) > 1">
|
32
|
+
<xsl:attribute name="ex:role">viewPanel</xsl:attribute>
|
33
|
+
</xsl:if>
|
34
|
+
<xsl:apply-templates select="*[substring(local-name(.), string-length(local-name(.))-4) = '-view']" />
|
35
|
+
</div>
|
36
|
+
<xsl:apply-templates select="ex:lens" />
|
37
|
+
</div>
|
38
|
+
</xsl:template>
|
39
|
+
|
40
|
+
<xsl:template match="ex:collection">
|
41
|
+
<div>
|
42
|
+
<xsl:attribute name="ex:role">exhibit-collection</xsl:attribute>
|
43
|
+
<xsl:attribute name="ex:itemTypes"><xsl:value-of select="@ex:types" /></xsl:attribute>
|
44
|
+
</div>
|
45
|
+
</xsl:template>
|
46
|
+
|
47
|
+
<xsl:template match="ex:tile-view">
|
48
|
+
<div>
|
49
|
+
<xsl:attribute name="ex:role">view</xsl:attribute>
|
50
|
+
<xsl:attribute name="class">view tile-view</xsl:attribute>
|
51
|
+
<xsl:attribute name="ex:viewClass">Tile</xsl:attribute>
|
52
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
53
|
+
<xsl:attribute name="ex:viewLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
54
|
+
<xsl:call-template name="apply-lenses" />
|
55
|
+
</div>
|
56
|
+
</xsl:template>
|
57
|
+
|
58
|
+
<xsl:template name="apply-lenses">
|
59
|
+
<xsl:choose>
|
60
|
+
<xsl:when test="ex:lens">
|
61
|
+
<xsl:apply-templates select="ex:lens" />
|
62
|
+
</xsl:when>
|
63
|
+
<xsl:otherwise>
|
64
|
+
</xsl:otherwise>
|
65
|
+
</xsl:choose>
|
66
|
+
</xsl:template>
|
67
|
+
|
68
|
+
|
69
|
+
<xsl:template match="ex:thumbnail-view">
|
70
|
+
<div>
|
71
|
+
<xsl:attribute name="ex:role">view</xsl:attribute>
|
72
|
+
<xsl:attribute name="ex:viewClass">Thumbnail</xsl:attribute>
|
73
|
+
<xsl:attribute name="ex:viewLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
74
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
75
|
+
<xsl:call-template name="apply-lenses" />
|
76
|
+
</div>
|
77
|
+
</xsl:template>
|
78
|
+
|
79
|
+
<xsl:template match="ex:map-view">
|
80
|
+
<div>
|
81
|
+
<xsl:attribute name="ex:role">view</xsl:attribute>
|
82
|
+
<xsl:attribute name="ex:viewClass">Map</xsl:attribute>
|
83
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
84
|
+
<xsl:attribute name="ex:latlng"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
85
|
+
<xsl:attribute name="ex:center"><xsl:value-of select="@ex:center" /></xsl:attribute>
|
86
|
+
<xsl:attribute name="ex:zoom"><xsl:value-of select="@ex:zoom-level" /></xsl:attribute>
|
87
|
+
<xsl:attribute name="ex:size"><xsl:value-of select="@ex:controls-size" /></xsl:attribute>
|
88
|
+
<xsl:attribute name="ex:type"><xsl:value-of select="@ex:map-type" /></xsl:attribute>
|
89
|
+
<xsl:attribute name="ex:viewLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
90
|
+
<xsl:call-template name="apply-lenses" />
|
91
|
+
</div>
|
92
|
+
</xsl:template>
|
93
|
+
|
94
|
+
<xsl:template match="ex:timeline-view">
|
95
|
+
<div>
|
96
|
+
<xsl:attribute name="ex:role">view</xsl:attribute>
|
97
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
98
|
+
<xsl:attribute name="ex:viewClass">Timeline</xsl:attribute>
|
99
|
+
<xsl:attribute name="ex:start"><xsl:value-of select="@ex:select-start" /></xsl:attribute>
|
100
|
+
<xsl:attribute name="ex:end"><xsl:value-of select="@ex:select-end" /></xsl:attribute>
|
101
|
+
<xsl:attribute name="ex:viewLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
102
|
+
<xsl:call-template name="apply-lenses" />
|
103
|
+
</div>
|
104
|
+
</xsl:template>
|
105
|
+
|
106
|
+
<xsl:template match="ex:tabular-view">
|
107
|
+
<div>
|
108
|
+
<xsl:attribute name="ex:role">view</xsl:attribute>
|
109
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
110
|
+
<xsl:attribute name="ex:viewClass">Tabular</xsl:attribute>
|
111
|
+
<xsl:attribute name="ex:viewLabel"><xsl:value-of select="ex:caption"/></xsl:attribute>
|
112
|
+
<xsl:attribute name="ex:columns"><xsl:for-each select="ex:column/@ex:select"><xsl:value-of select="."/><xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if></xsl:for-each></xsl:attribute>
|
113
|
+
<xsl:attribute name="ex:columnLabels"><xsl:for-each select="ex:column/ex:caption"><xsl:value-of select="."/><xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if></xsl:for-each></xsl:attribute>
|
114
|
+
<xsl:call-template name="apply-lenses" />
|
115
|
+
</div>
|
116
|
+
</xsl:template>
|
117
|
+
|
118
|
+
<xsl:template match="ex:lens">
|
119
|
+
<div>
|
120
|
+
<xsl:attribute name="ex:role">lens</xsl:attribute>
|
121
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
122
|
+
<xsl:attribute name="ex:itemTypes"><xsl:value-of select="@ex:types" /></xsl:attribute>
|
123
|
+
<xsl:attribute name="style">display: none;</xsl:attribute>
|
124
|
+
<xsl:apply-templates select="ex:title" />
|
125
|
+
<xsl:apply-templates select="ex:body" />
|
126
|
+
<xsl:if test="not(ex:title | ex:body)">
|
127
|
+
</xsl:if>
|
128
|
+
</div>
|
129
|
+
</xsl:template>
|
130
|
+
|
131
|
+
<xsl:template match="ex:list-facet">
|
132
|
+
<div>
|
133
|
+
<xsl:attribute name="ex:role">facet</xsl:attribute>
|
134
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
135
|
+
<xsl:attribute name="ex:expression"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
136
|
+
<xsl:attribute name="ex:facetClass">List</xsl:attribute>
|
137
|
+
<xsl:attribute name="ex:facetLabel"><xsl:value-of select="ex:caption" /></xsl:attribute>
|
138
|
+
</div>
|
139
|
+
</xsl:template>
|
140
|
+
|
141
|
+
<xsl:template match="ex:search-facet">
|
142
|
+
<div>
|
143
|
+
<xsl:attribute name="ex:role">facet</xsl:attribute>
|
144
|
+
<xsl:attribute name="id"><xsl:value-of select="generate-id(.)" /></xsl:attribute>
|
145
|
+
<xsl:attribute name="ex:facetClass">TextSearch</xsl:attribute>
|
146
|
+
<xsl:attribute name="ex:expression"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
147
|
+
</div>
|
148
|
+
</xsl:template>
|
149
|
+
|
150
|
+
<xsl:template match="ex:title">
|
151
|
+
<div class="exhibit-lens-title">
|
152
|
+
<xsl:apply-templates />
|
153
|
+
</div>
|
154
|
+
</xsl:template>
|
155
|
+
|
156
|
+
<xsl:template match="ex:value">
|
157
|
+
<span>
|
158
|
+
<xsl:attribute name="ex:content"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
159
|
+
</span>
|
160
|
+
</xsl:template>
|
161
|
+
|
162
|
+
<xsl:template match="ex:body">
|
163
|
+
<div class="exhibit-lens-body">
|
164
|
+
<xsl:apply-templates />
|
165
|
+
</div>
|
166
|
+
</xsl:template>
|
167
|
+
|
168
|
+
<xsl:template match="ex:property-list">
|
169
|
+
<table class="exhibit-lens-properties">
|
170
|
+
<tbody>
|
171
|
+
<xsl:apply-templates select="ex:property" />
|
172
|
+
</tbody>
|
173
|
+
</table>
|
174
|
+
</xsl:template>
|
175
|
+
|
176
|
+
<xsl:template match="ex:property-list/ex:property">
|
177
|
+
<tr class="exhibit-lens-property">
|
178
|
+
<td class="exhibit-lens-property-name"><xsl:value-of select="ex:caption" /><xsl:text>: </xsl:text></td>
|
179
|
+
<td class="exhibit-lens-property-values"><span>
|
180
|
+
<xsl:attribute xsl:name="ex:content"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
181
|
+
</span></td>
|
182
|
+
</tr>
|
183
|
+
</xsl:template>
|
184
|
+
|
185
|
+
<xsl:template match="ex:property">
|
186
|
+
<xsl:if test="ex:caption">
|
187
|
+
<span class="exhibit-lens-property-name"><xsl:value-of select="ex:caption" /></span>
|
188
|
+
</xsl:if>
|
189
|
+
<span class="exhibit-lens-property-values">
|
190
|
+
<span>
|
191
|
+
<xsl:attribute xsl:name="ex:content"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
192
|
+
</span>
|
193
|
+
</span>
|
194
|
+
</xsl:template>
|
195
|
+
|
196
|
+
<xsl:template match="ex:caption">
|
197
|
+
<xsl:apply-templates />
|
198
|
+
</xsl:template>
|
199
|
+
|
200
|
+
<xsl:template match="ex:section">
|
201
|
+
<div>
|
202
|
+
<xsl:attribute name="ex:section"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
203
|
+
<xsl:apply-templates />
|
204
|
+
</div>
|
205
|
+
</xsl:template>
|
206
|
+
|
207
|
+
<xsl:template match="ex:otherwise">
|
208
|
+
<div>
|
209
|
+
<xsl:attribute name="class">exhibit-otherwise</xsl:attribute>
|
210
|
+
<xsl:apply-templates />
|
211
|
+
</div>
|
212
|
+
</xsl:template>
|
213
|
+
|
214
|
+
<xsl:template match="ex:repeated">
|
215
|
+
<div>
|
216
|
+
<xsl:attribute name="ex:repeated"><xsl:value-of select="@ex:select" /></xsl:attribute>
|
217
|
+
<xsl:apply-templates />
|
218
|
+
</div>
|
219
|
+
</xsl:template>
|
220
|
+
|
221
|
+
</xsl:stylesheet>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fabulator-exhibit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-26 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -26,12 +26,12 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 13
|
30
30
|
segments:
|
31
31
|
- 0
|
32
32
|
- 0
|
33
|
-
-
|
34
|
-
version: 0.0.
|
33
|
+
- 9
|
34
|
+
version: 0.0.9
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -66,16 +66,19 @@ files:
|
|
66
66
|
- features/simple-database.feature
|
67
67
|
- features/step_definitions/exhibit_steps.rb
|
68
68
|
- features/step_definitions/expression_steps.rb
|
69
|
+
- features/step_definitions/template_steps.rb
|
69
70
|
- features/step_definitions/xml_steps.rb
|
70
71
|
- features/support/env.rb
|
72
|
+
- features/templates.feature
|
71
73
|
- lib/fabulator-exhibit.rb
|
72
74
|
- lib/fabulator/exhibit.rb
|
73
|
-
- lib/fabulator/exhibit/actions.rb
|
74
75
|
- lib/fabulator/exhibit/actions/item.rb
|
75
76
|
- lib/fabulator/exhibit/actions/property.rb
|
76
77
|
- lib/fabulator/exhibit/actions/type.rb
|
77
78
|
- lib/fabulator/exhibit/actions/value.rb
|
79
|
+
- lib/fabulator/exhibit/lib.rb
|
78
80
|
- lib/fabulator/exhibit/version.rb
|
81
|
+
- xslt/exhibit-html.xsl
|
79
82
|
- test/test_helper.rb
|
80
83
|
- test/test_fabulator-xml.rb
|
81
84
|
has_rdoc: true
|
@@ -1,124 +0,0 @@
|
|
1
|
-
module Fabulator
|
2
|
-
EXHIBIT_NS = "http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
|
3
|
-
|
4
|
-
require 'fabulator/exhibit/actions/item'
|
5
|
-
require 'fabulator/exhibit/actions/property'
|
6
|
-
require 'fabulator/exhibit/actions/type'
|
7
|
-
require 'fabulator/exhibit/actions/value'
|
8
|
-
|
9
|
-
module Exhibit
|
10
|
-
module Actions
|
11
|
-
class Lib < Fabulator::TagLib
|
12
|
-
|
13
|
-
@@databases = { }
|
14
|
-
|
15
|
-
namespace EXHIBIT_NS
|
16
|
-
|
17
|
-
action 'database', Database
|
18
|
-
action 'item', Item
|
19
|
-
action 'value', Value
|
20
|
-
action 'property', Property
|
21
|
-
action 'type', Type
|
22
|
-
|
23
|
-
## should set up an empty database with :items, :types, and :properties
|
24
|
-
def self.fetch_database(nom)
|
25
|
-
raise "fetch_database is not implemented by the framework."
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.store_database(nom, data)
|
29
|
-
raise "store_database is not imeplemented by the framework."
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.get_database(nom)
|
33
|
-
@@databases[nom] ||= self.fetch_database(nom)
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.set_database(nom, data)
|
37
|
-
@@databases[nom] = data
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.store_databases
|
41
|
-
@@databases.keys.each do |k|
|
42
|
-
self.store_database(k, @@databases[k])
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.accumulate_item_info(&block)
|
47
|
-
@@item ||=[]
|
48
|
-
@@item.unshift({})
|
49
|
-
yield
|
50
|
-
@@item.shift
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.add_item_to_accumulator(k,v)
|
54
|
-
return if @@item.empty?
|
55
|
-
if v.is_a?(Array) && v.size == 1
|
56
|
-
v = v[0]
|
57
|
-
end
|
58
|
-
@@item[0][k] = v
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.add_info(nom, t, item)
|
62
|
-
@@databases ||= {}
|
63
|
-
@@databases[nom] ||= self.fetch_database(nom)
|
64
|
-
@@databases[nom][t][item['id']] ||= { }
|
65
|
-
@@databases[nom][t][item['id']].merge!(item)
|
66
|
-
@@databases[nom][t][item['id']].each_pair do |k,v|
|
67
|
-
if v.nil? || (v.is_a?(Array) && v.empty?) ||
|
68
|
-
v.is_a?(String) && v == ""
|
69
|
-
@@databases[nom][t][item['id']].delete(k)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
case t
|
73
|
-
when :types, :properties
|
74
|
-
@@databases[nom][t][item['id']].delete(:id)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.remove_info(nom, t, id)
|
79
|
-
@@databases[nom] ||= self.fetch_database(nom)
|
80
|
-
return if @@databases[nom][t].empty?
|
81
|
-
@@databases[nom][t].delete(id)
|
82
|
-
end
|
83
|
-
|
84
|
-
function 'item' do |ctx, args|
|
85
|
-
# need to get at the 'global' ex:database attribute
|
86
|
-
nom = ctx.attribute(EXHIBIT_NS, 'database', { :inherited => true, :static => true })
|
87
|
-
db = Fabulator::Exhibit::Actions::Lib.get_database(nom)
|
88
|
-
args.collect{ |a|
|
89
|
-
id = a.to_s
|
90
|
-
i = db[:items][id]
|
91
|
-
r = ctx.root.anon_node(nil)
|
92
|
-
r.name = id
|
93
|
-
i.each_pair do |k,v|
|
94
|
-
next if k == "id"
|
95
|
-
v = [ v ] unless v.is_a?(Array)
|
96
|
-
v.each do |vv|
|
97
|
-
r.create_child(k,vv)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
r
|
101
|
-
}
|
102
|
-
end
|
103
|
-
|
104
|
-
## need to make this an iterator
|
105
|
-
function 'items' do |ctx, args|
|
106
|
-
nom = ctx.attribute(EXHIBIT_NS, 'database', { :inherited => true, :static => true })
|
107
|
-
db = Fabulator::Exhibit::Actions::Lib.get_database(nom)
|
108
|
-
ret = ctx.root.anon_node(nil)
|
109
|
-
db[:items].each_pair{ |id, item|
|
110
|
-
i = ret.create_child(id, nil)
|
111
|
-
item.each_pair do |k,v|
|
112
|
-
next if k == "id"
|
113
|
-
v = [ v ] unless v.is_a?(Array)
|
114
|
-
v.each do |vv|
|
115
|
-
i.create_child(k,vv)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
}
|
119
|
-
[ ret ]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|