document_file 0.0.4 → 0.0.5
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/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
|