Sinatra Variable Scope

2019-04-06 09:02发布

Take the following code:

### Dependencies
require 'rubygems'
require 'sinatra'
require 'datamapper'

### Configuration
config = YAML::load(File.read('config.yml'))

name = config['config']['name']
description = config['config']['description']
username = config['config']['username']
password = config['config']['password']
theme = config['config']['theme']

set :public, 'views/themes/#{theme}/static'

### Models
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/marvin.db")

class Post
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  property :body, Text
  property :created_at, DateTime
  property :slug, String
end

class Page
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  property :body, Text
  property :slug, String
end

DataMapper.auto_migrate!

### Controllers
get '/' do
  @posts = Post.get(:order => [ :id_desc ])
  haml :"themes/#{theme}/index"
end

get '/:year/:month/:day/:slug' do
  year = params[:year]
  month = params[:month]
  day = params[:day]
  slug = params[:slug]

  haml :"themes/#{theme}/post.haml"
end

get '/:slug' do
  haml :"themes/#{theme}/page.haml"
end

get '/admin' do
  haml :"admin/index.haml"
end

I want to make name, and all those variables available to the entire script, as well as the views. I tried making them global variables, but no dice.

4条回答
ゆ 、 Hurt°
2楼-- · 2019-04-06 09:46

Might not be the "cleanest" way to do it, but setting them as options should work:
--> http://www.sinatrarb.com/configuration.html :)

setting:

set :foo, 'bar'

getting:

"foo is set to " + settings.foo
查看更多
一夜七次
3楼-- · 2019-04-06 09:57

Make them constants. They should be anyway shouldn't they? They're not going to change.

Make a constant by writing it in all caps.

Read this article on Ruby Variable Scopes if you have any more issues. http://www.techotopia.com/index.php/Ruby_Variable_Scope

Another clean option may be a config class, where the init method loads the YAML and then sets up the variables.

Have fun. @reply me when you've finished your new blog (I'm guessing this is what this is for).

查看更多
forever°为你锁心
4楼-- · 2019-04-06 10:01

From the Sinatra README:


Accessing Variables in Templates

Templates are evaluated within the same context as route handlers. Instance variables set in route handlers are direcly accessible by templates:

get '/:id' do
  @foo = Foo.find(params[:id])
   haml '%h1= @foo.name'
end

Or, specify an explicit Hash of local variables:

get '/:id' do
  foo = Foo.find(params[:id])
  haml '%h1= foo.name', :locals => { :foo => foo }
end

This is typically used when rendering templates as partials from within other templates.


A third option would be to set up accessors for them as helper methods. (Which are also available throughout the application and views.)

查看更多
一夜七次
5楼-- · 2019-04-06 10:02

what also works:

@@foo = "bar"

But don't forget to restart the server after this change

查看更多
登录 后发表回答