utopia 1.8.3 → 1.9.0

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/documentation/.bowerrc +4 -0
  4. data/documentation/.rspec +4 -0
  5. data/documentation/Gemfile +27 -0
  6. data/documentation/Rakefile +5 -0
  7. data/documentation/config.ru +50 -0
  8. data/documentation/config/README.md +7 -0
  9. data/documentation/config/environment.rb +10 -0
  10. data/documentation/lib/readme.txt +1 -0
  11. data/documentation/pages/_heading.xnode +2 -0
  12. data/documentation/pages/_page.xnode +28 -0
  13. data/documentation/pages/errors/exception.xnode +5 -0
  14. data/documentation/pages/errors/file-not-found.xnode +5 -0
  15. data/documentation/pages/links.yaml +2 -0
  16. data/documentation/pages/welcome/index.xnode +41 -0
  17. data/documentation/pages/wiki/content.md +7 -0
  18. data/{setup/examples → documentation/pages}/wiki/controller.rb +8 -6
  19. data/documentation/pages/wiki/development-environment-setup/content.md +14 -0
  20. data/{setup/examples → documentation/pages}/wiki/edit.xnode +1 -1
  21. data/documentation/pages/wiki/server-setup/content.md +40 -0
  22. data/documentation/pages/wiki/show.xnode +12 -0
  23. data/documentation/pages/wiki/your-first-page/content.md +31 -0
  24. data/documentation/public +1 -0
  25. data/documentation/spec/website_context.rb +11 -0
  26. data/documentation/spec/website_spec.rb +15 -0
  27. data/documentation/tasks/test.rake +10 -0
  28. data/documentation/tasks/utopia.rake +38 -0
  29. data/lib/utopia/content.rb +2 -2
  30. data/lib/utopia/content/link.rb +5 -1
  31. data/lib/utopia/content/markup.rb +86 -66
  32. data/lib/utopia/content/tag.rb +28 -45
  33. data/lib/utopia/content/transaction.rb +31 -25
  34. data/lib/utopia/controller/actions.rb +1 -0
  35. data/lib/utopia/redirection.rb +4 -4
  36. data/lib/utopia/version.rb +1 -1
  37. data/setup/site/public/_static/site.css +20 -8
  38. data/spec/utopia/content/markup_spec.rb +10 -10
  39. data/spec/utopia/content/tag_spec.rb +36 -0
  40. data/spec/utopia/controller/middleware_spec.ru +4 -1
  41. data/spec/utopia/controller/middleware_spec/controller/controller.rb +2 -0
  42. data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +2 -0
  43. data/spec/utopia/controller/middleware_spec/redirect/controller.rb +2 -0
  44. data/spec/utopia/controller/middleware_spec/redirect/test/controller.rb +2 -0
  45. data/spec/utopia/controller/respond_spec.ru +5 -2
  46. data/spec/utopia/exceptions/handler_spec.ru +3 -1
  47. data/spec/utopia/exceptions/handler_spec/controller.rb +2 -0
  48. data/spec/utopia/exceptions/mailer_spec.ru +6 -2
  49. data/spec/utopia/localization_spec.rb +2 -2
  50. data/spec/utopia/localization_spec.ru +2 -1
  51. data/spec/utopia/localization_spec/controller.rb +2 -0
  52. data/spec/utopia/performance_spec/config.ru +1 -0
  53. data/spec/utopia/performance_spec/pages/api/controller.rb +1 -1
  54. data/utopia.gemspec +3 -3
  55. metadata +36 -14
  56. data/ext/utopia/xnode/fast_scanner/extconf.rb +0 -6
  57. data/ext/utopia/xnode/fast_scanner/parser.c +0 -289
  58. data/setup/examples/wiki/index.xnode +0 -10
  59. data/setup/examples/wiki/welcome/content.md +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5095d35222a513f2daa3c4b93e1a03490fa89654
4
- data.tar.gz: 6d71788ce9d2d1cd24e65ccb1314946e3d2c692f
3
+ metadata.gz: 92b8e6466b0a5eea4cb1e6009734e9cea5c76160
4
+ data.tar.gz: 9854cb98bf4f4ac5794fe19370c3af2e28aec456
5
5
  SHA512:
6
- metadata.gz: 6ba7fadd9730016d29fdefb2ff26ca2911867daa811290bd40a76f7cd640af4ea534e3ab8f040f97fc75b1f445bb81cf133295a77d9bf4a5c519014c077299a4
7
- data.tar.gz: cc97dcf681d73a609e2adfd1d6422403340a2708e0763f1229ec34d4bc7ddd67e1491932da42c9df801f719ada966432068092a5437a8c0a51eca122847dcd4b
6
+ metadata.gz: fdc050063c8b3b7ece0d94ee388fec013f52adc0cc2f63f92a7e4bb94eb849a8ecbfb41664a183047475adc88f5959b019077edc5cdbb9061eb8b8a8057a2a60
7
+ data.tar.gz: 781fe07c015abd3d777f2b4cd0340d43deee4846ca05ec2171c882569bd56add14604cc54ae5276b414dc778be77d2be7c86e90835a4793abb1df52b462b4117
data/Gemfile CHANGED
@@ -7,6 +7,8 @@ group :development do
7
7
  gem 'pry'
8
8
  gem 'pry-coolline'
9
9
 
10
+ gem 'kramdown'
11
+
10
12
  gem 'json'
11
13
  end
12
14
 
@@ -0,0 +1,4 @@
1
+ {
2
+ "directory" : "public/_static/components"
3
+ }
4
+
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
4
+ --warnings
@@ -0,0 +1,27 @@
1
+
2
+ source "https://rubygems.org"
3
+
4
+ gem "utopia", path: File.expand_path("../", __dir__)
5
+
6
+ gem "rake"
7
+ gem "bundler"
8
+
9
+ gem "kramdown"
10
+
11
+ group :development do
12
+ # For `rake server`:
13
+ gem "puma"
14
+
15
+ # For `rake console`:
16
+ gem "pry"
17
+ gem "rack-test"
18
+
19
+ # For `rspec` testing:
20
+ gem "rspec"
21
+ gem "simplecov"
22
+ end
23
+
24
+ group :production do
25
+ # Used for passenger-config to restart server after deployment:
26
+ gem "passenger"
27
+ end
@@ -0,0 +1,5 @@
1
+
2
+ # Load all rake tasks:
3
+ import(*Dir.glob('tasks/*.rake'))
4
+
5
+ task :default => :server
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env rackup
2
+
3
+ require_relative 'config/environment'
4
+
5
+ if RACK_ENV == :production
6
+ # Handle exceptions in production with a error page and send an email notification:
7
+ use Utopia::Exceptions::Handler
8
+ use Utopia::Exceptions::Mailer
9
+ else
10
+ # We want to propate exceptions up when running tests:
11
+ use Rack::ShowExceptions unless RACK_ENV == :test
12
+
13
+ # Serve the public directory in a similar way to the web server:
14
+ use Utopia::Static, root: 'public'
15
+ end
16
+
17
+ use Rack::Sendfile
18
+
19
+ use Utopia::ContentLength
20
+
21
+ use Utopia::Redirection::Rewrite,
22
+ '/' => '/welcome/index'
23
+
24
+ use Utopia::Redirection::DirectoryIndex
25
+
26
+ use Utopia::Redirection::Errors,
27
+ 404 => '/errors/file-not-found'
28
+
29
+ use Utopia::Localization,
30
+ :default_locale => 'en',
31
+ :locales => ['en', 'de', 'ja', 'zh'],
32
+ :nonlocalized => ['/_static/', '/_cache/']
33
+
34
+ use Utopia::Controller,
35
+ cache_controllers: (RACK_ENV == :production),
36
+ base: Utopia::Controller::Base
37
+
38
+ use Utopia::Static
39
+
40
+ # Serve dynamic content
41
+ use Utopia::Content,
42
+ cache_templates: (RACK_ENV == :production),
43
+ tags: {
44
+ 'deferred' => Utopia::Tags::Deferred,
45
+ 'override' => Utopia::Tags::Override,
46
+ 'node' => Utopia::Tags::Node,
47
+ 'environment' => Utopia::Tags::Environment.for(RACK_ENV)
48
+ }
49
+
50
+ run lambda { |env| [404, {}, []] }
@@ -0,0 +1,7 @@
1
+ # Utopia Config
2
+
3
+ This directory contains `environment.rb` which is used to initialize the running environment for tasks and servers.
4
+
5
+ ## Setting Environment Variables
6
+
7
+ If you wish to set environment variables on a per-deployment basis, you can do so by creating an `config/environment.yaml` and populating it with key-value pairs.
@@ -0,0 +1,10 @@
1
+
2
+ require 'bundler/setup'
3
+ Bundler.setup
4
+
5
+ require 'utopia/setup'
6
+ Utopia.setup
7
+
8
+ RACK_ENV = ENV.fetch('RACK_ENV', :development).to_sym unless defined? RACK_ENV
9
+
10
+ require 'kramdown'
@@ -0,0 +1 @@
1
+ You can add additional code for your application in this directory, and require it directly from the config.ru.
@@ -0,0 +1,2 @@
1
+ <?r transaction.attributes[:title] ||= content ?>
2
+ <h1><content/></h1>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <?r response.content_type = "text/html; charset=utf-8" ?>
5
+ <?r response.cache! ?>
6
+
7
+ <?r if title = self[:title] ?>
8
+ <title>#{title.gsub(/<.*?>/, "")} - Utopia</title>
9
+ <?r else ?>
10
+ <title>Utopia</title>
11
+ <?r end ?>
12
+
13
+ <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
14
+
15
+ <link rel="icon" type="image/png" href="/_static/icon.png" />
16
+ <link rel="stylesheet" href="/_static/site.css" type="text/css" media="screen" />
17
+ </head>
18
+
19
+ <body class="#{attributes[:class]}">
20
+ <header>
21
+ <img src="/_static/utopia.svg" />
22
+ </header>
23
+
24
+ <div id="page">
25
+ <content />
26
+ </div>
27
+ </body>
28
+ </html>
@@ -0,0 +1,5 @@
1
+ <page>
2
+ <heading>Exception</heading>
3
+
4
+ <p>It seems like something didn't quite work out as expected!</p>
5
+ </page>
@@ -0,0 +1,5 @@
1
+ <page>
2
+ <heading>File Not Found</heading>
3
+
4
+ <p>The file you requested is unfortunately not available at this time!</p>
5
+ </page>
@@ -0,0 +1,2 @@
1
+ errors:
2
+ display: false
@@ -0,0 +1,41 @@
1
+ <page class="front">
2
+ <heading>Welcome to Utopia...</heading>
3
+
4
+ <section class="features">
5
+ <div>
6
+ <i class="fa fa-bolt"></i>
7
+ <h2>Low latency and high throughput</h2>
8
+ <p>Utopia has been carefully tuned for low-latency and algorithmic efficiency. During development, requests reload the entire stack, while in production everything is cached using <a href="http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Map.html">thread-safe data-structures</a>. Serve thousands of requests per second with ease.</p>
9
+ </div>
10
+
11
+ <div>
12
+ <i class="fa fa-cubes"></i>
13
+ <h2>Modular code and structure</h2>
14
+ <p>Utopia provides independently useful <a href="https://github.com/rack/rack">Rack</a> middleware and has been designed with simplicify in mind. Several fully-featured webapps and a ton of commercial websites have guided the development of the Utopia stack. It is capable of handling a diverse range of requirements.</p>
15
+ </div>
16
+
17
+ <div>
18
+ <i class="fa fa-code"></i>
19
+ <h2>Well tested and maintained</h2>
20
+ <p>Utopia comprises a <a href="https://github.com/ioquatix/utopia">core gem</a> and several supporting libraries, the main ones being <a href="https://github.com/ioquatix/trenni">trenni</a> for templates and parsing, and <a href="https://github.com/ioquatix/http-accept">http-accept</a> for HTTP header processing. Together, these gems have over 90% test coverage.</p>
21
+ </div>
22
+
23
+ <div>
24
+ <i class="fa fa-server"></i>
25
+ <h2>Batteries included</h2>
26
+ <p>Utopia includes both a recommended development model and a server deployment model out of the box. This is exposed via the <code>utopia</code> command. We recommend use of <a href="https://www.nginx.com">Nginx</a> and <a href="https://www.phusionpassenger.com">Passenger</a> for server side deployment.</p>
27
+ </div>
28
+
29
+ <div>
30
+ <i class="fa fa-globe"></i>
31
+ <h2>Standards compliant localization</h2>
32
+ <p>Utopia supports the <code>Accept-Language</code> header and transparently selects the correct view to render. Build multi-lingual websites and webapps easily: translate content incrementally as required, or not at all.</p>
33
+ </div>
34
+ </section>
35
+
36
+ <section>
37
+ <h2>Documentation</h2>
38
+
39
+ <p>For up-to-date documentation, please browse the included <a href="/wiki/">wiki</a>. Feel free to improve it and submit a PR :)</p>
40
+ </section>
41
+ </page>
@@ -0,0 +1,7 @@
1
+ # Welcome to Utopia
2
+
3
+ This wiki includes documentation and examples showing how to use Utopia.
4
+
5
+ - [Development Environment Setup](development-environment-setup/)
6
+ - [Server Setup](server-setup/)
7
+ - [Your first page](your-first-page/)
@@ -4,18 +4,20 @@ prepend Actions
4
4
  on '**' do |request, path|
5
5
  @page_path = path.components[0..-2]
6
6
 
7
- if @page_path.empty?
8
- goto! "welcome/index"
9
- end
10
-
11
7
  @page_file = File.join(BASE_PATH, @page_path, "content.md")
12
- @page_title = Trenni::Strings::to_title @page_path.last
8
+
9
+ if last_path_component = @page_path.last
10
+ @page_title = Trenni::Strings::to_title(last_path_component)
11
+ else
12
+ @page_title = "Wiki"
13
+ end
13
14
  end
14
15
 
15
16
  def read_contents
16
17
  if File.exist? @page_file
17
18
  File.read(@page_file)
18
19
  else
20
+ "\# #{@page_title}\n\n" +
19
21
  "This page is empty."
20
22
  end
21
23
  end
@@ -37,5 +39,5 @@ end
37
39
  on '**/index' do |request, path|
38
40
  @content = read_contents
39
41
 
40
- path.components = ["index"]
42
+ path.components = ["show"]
41
43
  end
@@ -0,0 +1,14 @@
1
+ # Development Environment Setup
2
+
3
+ Utopia is built on Ruby and Rack. Therefore, Ruby (suggested 2.0+) should be installed and working. Then, simply run:
4
+
5
+ $ gem install utopia
6
+
7
+ To install all required dependencies.
8
+
9
+ Utopia and it's dependencies are built on Linux and Mac by default, and therefore compatibility with Windows is not guaranteed.
10
+
11
+ ## Atom Integration
12
+
13
+ Utopia uses [Trenni](https://github.com/ioquatix/trenni) for templates and it has a syntax slightly different from ERB. However, there is a [package for Atom](https://atom.io/packages/language-trenni) which provides accurate syntax highlighting.
14
+
@@ -5,7 +5,7 @@
5
5
  <form action="#" method="post">
6
6
  <fieldset>
7
7
  <legend>Page Content</legend>
8
- <textarea name="content">#{Strings::to_html self[:content]}</textarea>
8
+ <textarea name="content">#{self[:content]}</textarea>
9
9
  </fieldset>
10
10
 
11
11
  <fieldset class="footer">
@@ -0,0 +1,40 @@
1
+ # Server Setup
2
+
3
+ The best deployment platform for Utopia is Linux. Specifically, [Arch Linux](https://www.archlinux.org/) with the following packages:
4
+
5
+ - [nginx-mainline-passenger](https://aur.archlinux.org/packages/nginx-mainline-passenger/)
6
+ - [passenger-nginx-module](https://aur.archlinux.org/packages/passenger-nginx-module/)
7
+
8
+ There have been issues with the official packages and thus these packages were developed and tested with Utopia deployment in mind.
9
+
10
+ ## Sample Nginx Configuration
11
+
12
+ Create a configuration file for your site, e.g. `/etc/nginx/sites/www.example.com`:
13
+
14
+ server {
15
+ listen 80;
16
+ server_name www.example.com;
17
+ root /srv/http/www.example.com/public;
18
+ passenger_enabled on;
19
+ }
20
+
21
+ server {
22
+ listen 80;
23
+ server_name example.com;
24
+ rewrite ^ http://www.example.com$uri permanent;
25
+ }
26
+
27
+ ## Deployment via Git
28
+
29
+ The preferred method of deployment to a production server is via git. The `utopia` command assists with setup of a remote git repository on the server. It will setup a `git` `post-update` hook which will deploy the site correctly and restart passenger for that site.
30
+
31
+ To setup a server for deployment:
32
+
33
+ $ mkdir /srv/http/www.example.com
34
+ $ cd /srv/http/www.example.com
35
+ $ sudo -u http utopia server create
36
+
37
+ On your development machine, you should setup the git remote:
38
+
39
+ $ git remote add production ssh://remote/srv/http/www.example.com
40
+ $ git push --set-upstream production master
@@ -0,0 +1,12 @@
1
+ <page>
2
+ <?r
3
+ transaction.attributes[:title] ||= @page_title
4
+ ?>
5
+
6
+ #{MarkupString.raw Kramdown::Document.new(self[:content]).to_html}
7
+
8
+ <footer>
9
+ Last Modified: #{File.mtime(self[:page_file]) rescue "N/A"} &mdash;
10
+ <a href="edit">Edit</a>
11
+ </footer>
12
+ </page>
@@ -0,0 +1,31 @@
1
+ # Your First Page
2
+
3
+ To setup the default site, simply create a directory and use the `utopia` command:
4
+
5
+ $ mkdir www.example.com
6
+ $ cd www.example.com
7
+ $ utopia site create
8
+ $ rake server
9
+
10
+ You will now have a basic template site running on http://localhost:9292.
11
+
12
+ ## Welcome Page
13
+
14
+ Utopia includes a redirection middleware to redirect all root-level requests to a given URI. The default being `/welcome/index`:
15
+
16
+ use Utopia::Redirection::Rewrite,
17
+ '/' => '/welcome/index'
18
+
19
+ This page includes a basic overview of Utopia. Most of it's standard HTML, except for the outer `<page>` tag. Utopia uses the name `page` to lookup the file-system hierarchy. First, it looks for `/welcome/_page.xnode`, and then it looks for `/_page.xnode` which it finds. This page template includes a tag `<content/>` which is replaced with the inner body of the `<page>` tag. This recursive lookup is the heart of Utopia.
20
+
21
+ ## Links
22
+
23
+ Utopia is a content-centric web application platform. It leverages the file-system to provide a mapping between logical resources and files on disk. The primary mode of mapping incoming requests to specific nodes (content) is done using the `links.yaml` file.
24
+
25
+ The links file associates metadata with node names for a given directory. This can include things like redirects, titles, descriptions, etc. You can add any metadata you like, to support your specific use-case. The primary use of the links files is to provide site structure, e.g. menus. In addition, they can function as a rudimentary data-store for static information, e.g. a list of applications (each with it's own page), a list of features, etc.
26
+
27
+ You'll notice that there is a file `/links.yaml`. This file contains important metadata relating to the `errors` subdirectory. As we don't want these nodes showing up in a top level menu, we mark them as `display: false`
28
+
29
+ errors:
30
+ display: false
31
+
@@ -0,0 +1 @@
1
+ ../setup/site/public
@@ -0,0 +1,11 @@
1
+
2
+ require 'rack/test'
3
+
4
+ RSpec.shared_context "website" do
5
+ include Rack::Test::Methods
6
+
7
+ let(:rackup_path) {File.expand_path('../config.ru', __dir__)}
8
+ let(:rackup_directory) {File.dirname(rackup_path)}
9
+
10
+ let(:app) {Rack::Builder.parse_file(rackup_path).first}
11
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require_relative 'website_context'
3
+
4
+ # Learn about best practice specs from http://betterspecs.org
5
+ RSpec.describe "my website" do
6
+ include_context "website"
7
+
8
+ it "should have an accessible front page" do
9
+ get "/"
10
+
11
+ follow_redirect!
12
+
13
+ expect(last_response.status).to be == 200
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:test) do |task|
5
+ task.rspec_opts = %w{--require simplecov} if ENV['COVERAGE']
6
+ end
7
+
8
+ task :coverage do
9
+ ENV['COVERAGE'] = 'y'
10
+ end