document_file 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +18 -24
- data/lib/document_file.rb +74 -1
- data/lib/document_file/collection.rb +1 -1
- data/lib/document_file/version.rb +1 -1
- data/test/document_file_test.rb +4 -4
- data/test/test_base.rb +3 -1
- metadata +3 -7
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -16
- data/Rakefile +0 -5
- data/lib/document_file/base.rb +0 -71
data/README.textile
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
h1. Document File
|
2
2
|
|
3
|
-
|
3
|
+
Document file is an object mapper for plain text documents. The documents look like the ones used in "jekyll":http://github.com/mojombo/jekyll. They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile.
|
4
4
|
|
5
5
|
|
6
6
|
h2. Example
|
7
7
|
|
8
8
|
As an example let's assume we have a directory called "documents" containing the following files:
|
9
9
|
|
10
|
-
<pre><code>
|
11
|
-
documents/
|
10
|
+
<pre><code>documents/
|
12
11
|
|-foo.textile
|
13
12
|
|-bar.textile
|
14
13
|
</code></pre>
|
15
14
|
|
16
15
|
Documents look somehow like this. The part between the @---@s is the YAML front matter. After the second @---@, there is one blank line, followed by the content of the file. All items in the YAML front matter and the content are accessible by Document File.
|
17
16
|
|
18
|
-
<pre><code
|
19
|
-
---
|
17
|
+
<pre><code>---
|
20
18
|
id: 1
|
21
19
|
title: The shizzle!
|
22
20
|
tags: [tag]
|
@@ -30,8 +28,8 @@ I like the flowers.
|
|
30
28
|
|
31
29
|
In order to access the documents in the folder, you have to create a document class that inherits from @DocumentFile::Base@. Inside the class definition, you must set the @documents_dir@ class variable in order to tell Document File where to look for files. In our little example, we will do the following:
|
32
30
|
|
33
|
-
<pre><code>
|
34
|
-
|
31
|
+
<pre><code>class MyDocument
|
32
|
+
include DocumentFile
|
35
33
|
self.documents_dir = './documents'
|
36
34
|
end
|
37
35
|
</code></pre>
|
@@ -41,36 +39,34 @@ h2. Available functionality
|
|
41
39
|
|
42
40
|
h3. Dynamic finders
|
43
41
|
|
44
|
-
<pre><code>
|
45
|
-
doc = MyDocument.find_by_title("The shizzle!") # => returns the document
|
42
|
+
<pre><code>doc = MyDocument.find_by_title("The shizzle!") # => returns the document
|
46
43
|
doc = MyDocument.find_by_number_of_foos(42) # => returns the document
|
47
44
|
doc = MyDocument.find_by_file_name("foo.textile") # => returns the document
|
48
45
|
|
49
|
-
docs = MyDocument.find_all_by_status("published") # => [doc_1,
|
50
|
-
docs = MyDocument.find_all_by_tag("tag") # => [doc_1,
|
46
|
+
docs = MyDocument.find_all_by_status("published") # => [doc_1, doc_2, ...]
|
47
|
+
docs = MyDocument.find_all_by_tag("tag") # => [doc_1, doc_2, ...]
|
51
48
|
</code></pre>
|
52
49
|
|
50
|
+
|
53
51
|
h3. Listing documents by Array attributes
|
54
52
|
|
55
|
-
<pre><code>
|
56
|
-
|
57
|
-
# => Returns {"tag" => [doc_1, doc2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
|
53
|
+
<pre><code>docs = MyDocument.by_tags
|
54
|
+
# => Returns {"tag" => [doc_1, doc_2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
|
58
55
|
</code></pre>
|
59
56
|
|
57
|
+
|
60
58
|
h3. Chaining
|
61
59
|
|
62
|
-
<pre><code>
|
63
|
-
|
64
|
-
# => Returns {"tag" => [doc_1, doc2, ...], ...}
|
60
|
+
<pre><code>docs = MyDocument.find_all_by_status("published").by_tags
|
61
|
+
# => Returns {"tag" => [doc_1, doc_2, ...], ...}
|
65
62
|
docs = MyDocument.find_all_by_status("published").find_all_by_tag("tag")
|
66
|
-
# => Returns [doc_1,
|
63
|
+
# => Returns [doc_1, doc_2, ...]
|
67
64
|
</code></pre>
|
68
65
|
|
69
66
|
|
70
67
|
h3. Accessing the attributes of single documents
|
71
68
|
|
72
|
-
<pre><code>
|
73
|
-
doc.title # => "The shizzle!"
|
69
|
+
<pre><code>doc.title # => "The shizzle!"
|
74
70
|
doc.tags # => ["tag"]
|
75
71
|
doc.content # => "I like the flowers."
|
76
72
|
doc.filename # => "foo"
|
@@ -82,15 +78,13 @@ h3. Initializing single documents
|
|
82
78
|
|
83
79
|
This will even work without setting the @documents_dir@ class variable.
|
84
80
|
|
85
|
-
<pre><code>
|
86
|
-
doc = MyDocument.new('./documents/document-file.textile')
|
81
|
+
<pre><code>doc = MyDocument.new('./documents/document-file.textile')
|
87
82
|
</code></pre>
|
88
83
|
|
89
84
|
h3. Reloading
|
90
85
|
|
91
86
|
If any of the files change, you must manually reload them:
|
92
|
-
<pre><code>
|
93
|
-
MyDocument.reload!
|
87
|
+
<pre><code>MyDocument.reload!
|
94
88
|
</code></pre>
|
95
89
|
|
96
90
|
|
data/lib/document_file.rb
CHANGED
@@ -1,3 +1,76 @@
|
|
1
|
-
require '
|
1
|
+
require 'active_support/core_ext/class'
|
2
|
+
require 'active_support/concern.rb'
|
2
3
|
require 'document_file/collection'
|
3
4
|
require 'document_file/version'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module DocumentFile
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
class_inheritable_accessor :documents_dir
|
12
|
+
self.documents_dir = './documents'
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :content, :file_path, :data
|
16
|
+
|
17
|
+
def initialize(new_file_path)
|
18
|
+
@file_path = new_file_path
|
19
|
+
read_yaml
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_name
|
23
|
+
File.basename file_name_with_extension, file_extension
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_name_with_extension
|
27
|
+
self.file_path.split('/').last
|
28
|
+
end
|
29
|
+
|
30
|
+
def file_extension
|
31
|
+
File.extname file_name_with_extension
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def read_yaml
|
36
|
+
@content = File.read(@file_path)
|
37
|
+
|
38
|
+
if @content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
39
|
+
@content = @content[($1.size + $2.size)..-1]
|
40
|
+
@data = YAML.load($1)
|
41
|
+
end
|
42
|
+
@data ||= {}
|
43
|
+
define_dynamic_methods
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_dynamic_methods
|
47
|
+
@data.each do |attribute_name, value|
|
48
|
+
attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
|
49
|
+
self.class.module_eval attribute_reader
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module ClassMethods
|
54
|
+
@@documents = nil
|
55
|
+
|
56
|
+
def all
|
57
|
+
return @@documents if @@documents
|
58
|
+
reload!
|
59
|
+
end
|
60
|
+
|
61
|
+
def reload!
|
62
|
+
if File.directory?(documents_dir)
|
63
|
+
file_paths = Dir.glob("#{documents_dir}/*.*")
|
64
|
+
@@documents = Collection.new file_paths.map { |file_path| self.new file_path }
|
65
|
+
else
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def method_missing(method_name, *args)
|
72
|
+
all.respond_to?(method_name) ? self.all.send(method_name, *args) : super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/test/document_file_test.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
require './test/test_base'
|
2
2
|
|
3
3
|
describe MyDocument do
|
4
|
-
before do
|
5
|
-
MyDocument.documents_dir = TEST_DIR + '/documents'
|
6
|
-
end
|
7
|
-
|
8
4
|
describe 'when finding all document_files' do
|
9
5
|
before do
|
10
6
|
@document_files = MyDocument.all
|
@@ -26,6 +22,10 @@ describe MyDocument do
|
|
26
22
|
)
|
27
23
|
end
|
28
24
|
|
25
|
+
it 'should know the documents_dir' do
|
26
|
+
assert_equal MyDocument.documents_dir, @document_file.documents_dir
|
27
|
+
end
|
28
|
+
|
29
29
|
it 'should initialize the content' do
|
30
30
|
assert_equal "I like the flowers.\n", @document_file.content
|
31
31
|
end
|
data/test/test_base.rb
CHANGED
@@ -8,5 +8,7 @@ $LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include?(lib_dir)
|
|
8
8
|
require 'document_file'
|
9
9
|
TEST_DIR = File.dirname(__FILE__)
|
10
10
|
|
11
|
-
class MyDocument
|
11
|
+
class MyDocument
|
12
|
+
include DocumentFile
|
13
|
+
self.documents_dir = (TEST_DIR + '/documents')
|
12
14
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 5
|
9
|
+
version: 0.0.5
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ralph von der Heyden
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-09-01 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,12 +41,8 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
|
43
43
|
files:
|
44
|
-
- Gemfile
|
45
|
-
- Gemfile.lock
|
46
44
|
- LICENSE
|
47
45
|
- README.textile
|
48
|
-
- Rakefile
|
49
|
-
- lib/document_file/base.rb
|
50
46
|
- lib/document_file/collection.rb
|
51
47
|
- lib/document_file/version.rb
|
52
48
|
- lib/document_file.rb
|
data/Gemfile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
gemspec :path => '.'
|
data/Gemfile.lock
DELETED
data/Rakefile
DELETED
data/lib/document_file/base.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module DocumentFile
|
4
|
-
class Base
|
5
|
-
@@documents_dir = './documents'
|
6
|
-
@@documents = nil
|
7
|
-
attr_reader :content, :file_path, :data
|
8
|
-
|
9
|
-
def initialize(new_file_path)
|
10
|
-
@file_path = new_file_path
|
11
|
-
read_yaml
|
12
|
-
end
|
13
|
-
|
14
|
-
def file_name
|
15
|
-
File.basename file_name_with_extension, file_extension
|
16
|
-
end
|
17
|
-
|
18
|
-
def file_name_with_extension
|
19
|
-
self.file_path.split('/').last
|
20
|
-
end
|
21
|
-
|
22
|
-
def file_extension
|
23
|
-
File.extname file_name_with_extension
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.all
|
27
|
-
return @@documents if @@documents
|
28
|
-
self.reload!
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.reload!
|
32
|
-
if File.directory?(@@documents_dir)
|
33
|
-
file_paths = Dir.glob("#{@@documents_dir}/*.*")
|
34
|
-
@@documents = Collection.new file_paths.map { |file_path| self.new file_path }
|
35
|
-
else
|
36
|
-
[]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.documents_dir
|
41
|
-
@@documents_dir
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.documents_dir=(new_dir)
|
45
|
-
@@documents_dir = new_dir
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
def read_yaml
|
50
|
-
@content = File.read(@file_path)
|
51
|
-
|
52
|
-
if @content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
53
|
-
@content = @content[($1.size + $2.size)..-1]
|
54
|
-
@data = YAML.load($1)
|
55
|
-
end
|
56
|
-
@data ||= {}
|
57
|
-
define_dynamic_methods
|
58
|
-
end
|
59
|
-
|
60
|
-
def define_dynamic_methods
|
61
|
-
@data.each do |attribute_name, value|
|
62
|
-
attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
|
63
|
-
self.class.module_eval attribute_reader
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.method_missing(method_name, *args)
|
68
|
-
self.all.respond_to?(method_name) ? self.all.send(method_name, *args) : super
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|