Class: Zen::Package

Inherits:
Object
  • Object
show all
Includes:
Validation
Defined in:
lib/zen/package.rb,
lib/zen/package/menu.rb

Overview

Zen::Package allows developers to register so called "packages". Packages are collections of controllers, models, views and pretty much anything else that goes in a typical Ramaze application. In fact, you can actually distribute entire Ramaze applications as a package (though it would most likely require some modifications).

A package is registered by calling Zen::Package.add and passing a block to it. This block will be yielded on a new instance of Zen::Package:

Zen::Package.add do |p|

end

When adding a package you must always set the following attributes:

  • name: the name of the package, should be a symbol
  • title: the title of the package. This should be a language key such as "users.titles.index" as this allows users to view the package name in their chosen language.
  • author: the name of the package's author.
  • about: a description of the package, just like the title attribute this should be a language key, "users.description" is an example of such a key.
  • root: the root directory of the package, this path should point to the directory containing your helper/ and language/ directories as well as any public/ directories.

Setting these (and other) attributes is very easy:

Zen::Package.add do |p|
  p.name   = :some_package
  p.title  = 'some_package.titles.index'
  p.author = 'John Doe'
  p.root   = __DIR__('some_package')
end

Besides the required attributes listed above you can also set the following ones:

  • url: a URL that points to the website of the package.
  • migrations: a directory containing all Sequel migrations.

Package Structure

Packages should have the same structure as generic Rubygems. In it's most basic form this means you'll end up with a structure that looks like the following:

root/
|
|__ lib/
   |__ package.rb
   |__ package/
      |__ controller/
      |__ helper/

There's no requirement for the location of your migrations but it's recommended to place it in the same directory as the lib/ directory as this is the convention followed by Zen itself.

The advantage of this structure is that when a package is shipped via Rubygems it can be loaded in exactly the same way as a normal gem. Say the "some_package" example described earlier would be distributed via Rubygems, all a developer would have to do to load the package is the following:

require 'some_package'

It's not recommended to place packages or gems in the Zen namespace unless they modify or add core features such as more validation methods for Zen::Validation.

Menu Management

Menus can be added by calling the method menu() on the object passed to the block. This method takes a URL, a title/label and a hash of options. Note that just like the name attribute the title/label should be a language key.

Zen::Package.add do |p|
  p.menu('some_package.titles.index', '/admin/some-packages')
end

For more information see Zen::Package#menu() and Zen::Package::Menu.

Permissions

When creating a package you can add a number of permissions. These permissions can be assigned to a user or user group in the admin interface. Permissions allow you to restrict access to certain actions to specific users/user groups. A permission can be added by calling permission() on the object passed to the block. Again the title of the permission should be a langauge key so it can be displayed in a custom language:

Zen::Package.add do |p|
  p.permission(:show_some_package, 'packages.titles.index')
end

For more information on how to specify permission requirements in your controllers see Ramaze::Helper::ACL.

Migrations

Zen comes with two tasks that allow users and developers to update their database, rake db:migrate and rake package:migrate. For these tasks to work there of course have to be migrations. When registering a package you can set the migrations attribute. This attribute should contain a path to a directory containing a group of timestamp based migrations such as "1316770622_hello_world.rb".

Since:

Defined Under Namespace

Classes: Menu

Constant Summary

REGISTERED =

Hash containing all the registered packages. The keys of this hash are the names of all packages and the values the instances of Zen::Package::Base.

Since:

  • 0.1

{}

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Validation

#validates_filepath, #validates_format, #validates_length, #validates_presence

Instance Attribute Details

- (Object) author

The author of the package.

Since:

  • 0.1



127
128
129
# File 'lib/zen/package.rb', line 127

def author
  @author
end

- (Object) migrations

The directory to all migrations.

Since:

  • 0.1



136
137
138
# File 'lib/zen/package.rb', line 136

def migrations
  @migrations
end

- (Object) name

The name of the package.

Since:

  • 0.1



124
125
126
# File 'lib/zen/package.rb', line 124

def name
  @name
end

- (Object) root

The root directory of the package.

Since:

  • 0.1



133
134
135
# File 'lib/zen/package.rb', line 133

def root
  @root
end

- (Object) url

The URL of the package.

Since:

  • 0.1



130
131
132
# File 'lib/zen/package.rb', line 130

def url
  @url
end

Class Method Details

+ (Object) [](name)

Retrieves the package for the given name.

Examples:

Zen::Package[:users]

Since:

  • 0.1



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/zen/package.rb', line 168

def [](name)
  name = name.to_sym

  if REGISTERED.empty?
    raise(PackageError, "No packages have been added yet.")
  end

  if !REGISTERED.key?(name)
    raise(PackageError, "The package \"#{name}\" doesn't exist.")
  end

  return REGISTERED[name]
end

+ (Object) add {|package| ... }

Adds a new package along with all it's details such as the name, author, version and so on. Extensions can be added using a simple block as following:

Zen::Package.add do |ext|
  extrans.name   = "name"
  ext.author = "Author"
end

Yields:

  • (package)

Since:

  • 0.1



151
152
153
154
155
156
157
158
# File 'lib/zen/package.rb', line 151

def add
  package = self.new

  yield(package)
  package.validate

  REGISTERED[package.name] = package
end

+ (String) build_menu(html_class = 'navigation', permissions = [])

Builds the entire navigation menu for all packages.

Examples:

Zen::Package.build_menu('left', [:edit_user, :show_user, :show_setting])

Parameters:

  • html_class (String) (defaults to: 'navigation')

    An HTML class to apply to the

      element.

  • permissions (Array) (defaults to: [])

    An array of permissions for the current user.

Returns:

  • (String)

Since:

  • 0.3



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/zen/package.rb', line 194

def build_menu(html_class = 'navigation', permissions = [])
  g = Ramaze::Gestalt.new

  g.ul(:class => html_class) do
    # Sort the hash
    keys = REGISTERED.keys.sort

    keys.each do |key|
      unless REGISTERED[key].menu.nil?
        g.out << REGISTERED[key].menu.html(permissions)
      end
    end
  end

  return g.to_s
end

Instance Method Details

- (String) about

Tries to translate the description and returns it.

Returns:

  • (String)

Since:

  • 0.3



279
280
281
282
283
284
285
# File 'lib/zen/package.rb', line 279

def about
  begin
    return lang(@about)
  rescue
    return @about
  end
end

- (Object) about=(about)

Sets the description of the package.

Parameters:

  • about (String)

    The description of the package.

Since:

  • 0.3



269
270
271
# File 'lib/zen/package.rb', line 269

def about=(about)
  @about = about
end

- (String) formatted_title

Returns the title as either an <a> tag or plain text depending on whether or not the package has a URL set.

Returns:

  • (String)

Since:

  • 19-11-2011



255
256
257
258
259
260
261
# File 'lib/zen/package.rb', line 255

def formatted_title
  if url
    return '<a href="%s" title="%s">%s</a>' % [url, title, title]
  else
    return title
  end
end

Sets all the navigation items for the package. Sub items can be specified by calling this method and passing a block to it.

Examples:

Zen::Package.add do |p|
  p.menu('Hello,' ,'/admin/hello') do |sub|
    sub.menu('Sub menu', '/admin/hello/sub')
  end
end

Returns:

See Also:

  • Zen::Package::Menu#initialize()

Since:

  • 0.3



327
328
329
330
331
332
333
# File 'lib/zen/package.rb', line 327

def menu(title = nil, url = nil, options = {}, &block)
  if title.nil? and url.nil? and !block_given?
    return @menu
  end

  @menu = Zen::Package::Menu.new(title, url, options, &block)
end

- (Object) permission(permission, title)

Adds a new permission along with it's title or language key.

Examples:

Zen::Package.add do |p|
  p.permission :show_user, 'users.titles.index'
  p.permission :edit_user, 'users.titles.edit'
end

Parameters:

  • permission (#to_sym)

    The name of the permission.

  • title (String)

    The title or language key of the permission, shown in the admin interface.

Since:

  • 0.3



349
350
351
352
# File 'lib/zen/package.rb', line 349

def permission(permission, title)
  @permissions                  ||= {}
  @permissions[permission.to_sym] = title
end

- (Hash) permissions

Returns the permissions for the current package. This method will automatically try to translate the titles using the current language.

Returns:

  • (Hash)

Since:

  • 0.3



361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/zen/package.rb', line 361

def permissions
  perms = {}

  @permissions.each do |perm, title|
    begin
      perms[perm] = lang(title)
    rescue
      perms[perm] = title
    end
  end

  return perms
end

- (String) title

Returns the title of the package. This method will try to translate it and fall back to the original value in case the language key doesn't exist.

Returns:

  • (String)

Since:

  • 0.3



240
241
242
243
244
245
246
# File 'lib/zen/package.rb', line 240

def title
  begin
    return lang(@title)
  rescue
    return @title
  end
end

- (Object) title=(title)

Sets the title of the package.

Parameters:

  • title (String)

    The title or language key of the package.

Since:

  • 0.3



229
230
231
# File 'lib/zen/package.rb', line 229

def title=(title)
  @title = title
end

- (Object) validate

Validates all the attributes.

Since:

  • 0.2.5



380
381
382
383
384
385
386
387
388
389
390
# File 'lib/zen/package.rb', line 380

def validate
  validates_presence([:name, :title, :author, :about, :root])

  validates_filepath(:root)
  validates_filepath(:migrations) unless migrations.nil?

  # Check if the package hasn't been registered yet
  if Zen::Package::REGISTERED.key?(name.to_sym)
    raise(Zen::ValidationError, "The package #{name} already exists.")
  end
end