Ubiquo planet http://planet.ubiquo.me Most recent posts at Ubiquo planet posterous.com Tue, 24 Jan 2012 04:57:00 -0800 Many To Many associations with multiple databases http://planet.ubiquo.me/many-to-many-associations-with-multiple-datab http://planet.ubiquo.me/many-to-many-associations-with-multiple-datab

Sometimes you need to use multiple databases in your Rails projects. Usually when some data must be shared between different applications. When this happens you usually have some models in a shared database, and some other models in the specific application database. This can be easily done using the establish_connection method in the shared models to tell them they have to connect to a different database.

However, when you need some interaction between those shared models and the models of your specific application, like a has_many, :through association, some problems arise. The typical Many To Many association uses an intermediate database table that links the relation between two models, and allows you to add some extra information on that relation. When navigating through the association, Rails tries to make an SQL query that joins the model with this intermediate table. For example, imagine you have a Team model, which has many Players, but a player can also be on more than one team. We use an intermediate model TeamPlayers (and we can also use it to save the role of that player into that team, for example). You would have those three tables:

  • teams
  • players
  • teams_players

When asking for the players of a given Team, Rails would do something similar to this:

SELECT "players".* FROM "players" INNER JOIN teams_players" ON "players".id = "teams_players".player_id WHERE "players".team_id = 1

Where 1 is the id of the team you asked for. This [obviously] works perfectly fine when everything is in the same database, and it's as efficient as the SQL database manager you're using. What happens, however, when we have the Player model in another database? It will miserably fail because Rails will try to join with a table that doesn't exist.

 

Unfortunately, there's no efficient way to solve this problem, that is, using SQL, as you can't work with tables from different databases. However, there's a rather elegant solution that Brian Doll cared to implement as a gem a while ago. As indicated in the GitHub readme, you just have to use a has_many_elsewhere relation instead of the usual one, and make sure that the model referenced has the connection established to the shared database. And that's all.

The magic donde behind the scenes is pretty simple: this gem just replicates the same methods that the ActiveRecord::Base class does in the has_many method call, changing the failing unique SQL calls to double SQL calls, one for each database, fetching the intermediate models first, and then fetching the remote models using those ids.

This method is not perfect, as probably not all the goodness of the original association can be done with it, but for simple scenarios is more than enough.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1667985/download_reasonably_small.jpg http://posterous.com/users/cO52ZAIcWnNk6 Bernat Ràfales brafales Bernat Ràfales
Mon, 23 Jan 2012 23:45:00 -0800 Reprocessing all the assets of your Ubiquo Application http://planet.ubiquo.me/reprocessing-all-the-assets-of-your-ubiquo-ap http://planet.ubiquo.me/reprocessing-all-the-assets-of-your-ubiquo-ap

When in your project you have defined custom formats for your images in config/initializers/ubiquo_config.rb file, if you modify any of these formats, you must reprocess all the assets you have uploaded. If you don't do it, they won't be in the correct formats.

If you don't have a huge amount of assets, you can create a migration adding this line to its "up" method:

        Asset.all.each { |a| a.resource.reprocess! }

On the other hand, if you have lots of assets, you should do it as a job, not a migration.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1768599/lionel_messi_avatar_by_pahasusi-d3fhv87.png http://posterous.com/users/cQdbgdR2tlS6m davidrr davidrr davidrr
Mon, 05 Dec 2011 01:20:30 -0800 Setting up the locales of your Ubiquo Application http://planet.ubiquo.me/setting-up-the-locales-of-your-ubiquo-applica http://planet.ubiquo.me/setting-up-the-locales-of-your-ubiquo-applica

It's sometimes required to build a multilanguage web application. For those cases, Ubiquo provides a plugin that uses the Rails I18n infrastructure to do so. In this post I'll explain you how to set up the default locale for your application and how to tell Ubiquo how many languages you want to have support for.

By default, new Ubiquo projects are configured to use English (default), Catalan and Spanish languages. However, you may want to support more languages, or have a different default language instead of English. Both parameters are changed in the config/environment.rb file, using the Ubiquo Config framework:

Ubiquo::Config.set(:default_locale, :ca) will use Catalan as the default locale.

Ubiquo::Config.set(:supported_locales, %w[ca]) will set the supported locales of your application.

Keep in mind that the default locale must be one of the locales set up in the supported locales array. Also, be wary on changing those parameters outside of the environment file, since it might led to strange behaviours.

Feel free to check out the Ubiquo I18n Configuration Guide for information on how to manage translatable models.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1667985/download_reasonably_small.jpg http://posterous.com/users/cO52ZAIcWnNk6 Bernat Ràfales brafales Bernat Ràfales
Fri, 02 Dec 2011 03:16:35 -0800 Creating your own Ubiquo Job Managers http://planet.ubiquo.me/creating-your-own-ubiquo-job-managers http://planet.ubiquo.me/creating-your-own-ubiquo-job-managers

Sometimes can be useful to create different managers. An example of this situation is when you want to run different kind of jobs in different circumstances.

Ubiquo Jobs provides a default manager which will get ActiveJob jobs depending on priorities and schedule times:

def self.get(runner)
  recovery(runner)
  candidate_jobs = job_class.all(
    :conditions => [
      'planified_at <= ? AND state = ?',
      Time.now.utc,
      UbiquoJobs::Jobs::Base::STATES[:waiting]
    ],
    :order => 'priority asc'
  )
  job = first_without_dependencies(candidate_jobs)
  job.update_attributes({
      :state => UbiquoJobs::Jobs::Base::STATES[:instantiated],
      :runner => runner
    }) if job
  job
end

The job_class variable defaults to UbiquoJobs::Jobs::ActiveJob. If you want to make your own manager to handle special jobs, or change the way the jobs are picked, the best way to do so is to implement your own manager. A nice rails-like way to do that is include them in the lib/ folder of your ubiquo project. The class you should inherit from is UbiquoJobs::Managers::ActiveManager. If you wanted the manager to just pick up a specific subclass of ubiquo jobs, it would suffice to reimplement the self.job_class class method to return your own kind of job:

def self.job_class
  UbiquoJobs::Jobs::YourJobClass 
end

However, there’s a better way to do this. For this special case, the default UbiquoJob class provides a special member which stores the job’s class name, allowing you to select all objects subclasses of ActiveJob by its classname. For example, imagine you have a kind of job for special tasks that you know for sure will take a long time to complete. Seems reasonable to have a different manager to handle those jobs. You would create a new job in the file app/jobs/very_long_job.rb:

class VeryLongJob < UbiquoJobs::Jobs::ActiveJob
  def do_job_work
    #Do what needs to be done here
    return 0
  end
end

Then you could create a manager that handles only those kind of jobs by implementing your own subclass of the UbiquoJobs::Managers::ActiveManager class:

module JobManagers
  class VeryLongJobManager < UbiquoJobs::Managers::ActiveManager
    def self.get(runner)
      recovery(runner)
      candidate_jobs = job_class.all(
        :conditions => [
          'planified_at <= ? AND state = ? AND type = ?', 
          Time.now.utc,
          UbiquoJobs::Jobs::Base::STATES[:waiting],
          'VeryLongJob'
        ],
        :order => 'priority asc'
      )
      job = first_without_dependencies(candidate_jobs)
      job.update_attributes({
          :state => UbiquoJobs::Jobs::Base::STATES[:instantiated],
          :runner => runner
        }) if job
      job
    end
  end
end

The code is exactly the same as the default ActiveManager class, but the finder will take an extra parameter, 'VeryLongJob', to indicate that only the ActiveJob objects that are of the subclass VerylongJob should be taken.

After that, you need to modify the task that calls the workers so it takes your manager, or create a new task that will run your manager. The default task that will start a worker looks as this:

desc "Starts a new ubiquo worker"
task :start, [:name, :interval] => [:environment] do |t, args|
  options = {
    :sleep_time => args.interval.to_f
  }.delete_if { |k,v| v.blank? }
  UbiquoWorker.init(args.name, options)
end

This uses a special configuration parameter to determine the manager to use. This configuration option is stored in Ubiquo::Config.context(:ubiquo_jobs), the name of the configuration option is :job_manager_class, and takes the manager class as a value. So in order to create a task that will use your manager, you should create a new task like this one:

desc "Starts a new ubiquo worker"
task :start_very_long_jobs, [:name, :interval] => [:environment] do |t, args|
  options = {
    :sleep_time => args.interval.to_f
  }.delete_if { |k,v| v.blank? }
  Ubiquo::Config.context(:ubiquo_jobs).set(:job_manager_class, JobManagers::VeryLongJobManager)
  UbiquoWorker.init(args.name, options)
end

Your should call this task like this (assuming it’s on the same namespace as the default task):

rake ubiquo:worker:start_very_long_jobs[name,interval]

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1667985/download_reasonably_small.jpg http://posterous.com/users/cO52ZAIcWnNk6 Bernat Ràfales brafales Bernat Ràfales
Fri, 11 Nov 2011 05:34:05 -0800 How to override an Ubiquo::Connector http://planet.ubiquo.me/79728846 http://planet.ubiquo.me/79728846

Suppose you want to change the way some uhooks work for one of your models. You need to override this hook so it will do something different. The way to do it is extending the default I18n connector from, say, UbiquoMedia (overriding other plugin's connectors its done in the same way) and provide a custom method. Here's how to do it:

Place an extension somewhere in lib/. In this case we will use lib/ubiquo_media/connectors/my_i18n.rb.

Inside you copy the affected method's object hierarchy so our method overrides the original one. You must use its full class hierarchy while extending from I18n cause extending with "class MyI18n < I18n" alone clashes with rails I18n module raising an "Uncaught exception: superclass must be a Class (Module given)" error.

module UbiquoMedia
  module Connectors
    class MyI18n < UbiquoMedia::Connectors::I18n
      # Custom implementation
      
      def uhook_after_update
      # do stuff...
    end
  end
end

Then you require it, usually from a ubiquo_connectors.rb in lib/ like this:

require 'ubiquo_media/connectors/my_i18n'

Finally you tell Ubiquo::Config to use your connector instead of the original one, updating the ubiquo connector configuration (in config/initializers/ubiquo_config.rb), from this:

Ubiquo::Config.context(:ubiquo_media).set(:connector, :i18n)

to this:

Ubiquo::Config.context(:ubiquo_media).set(:connector, :my_i18n)

From now on, your method will be the one running in place of the original one.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/cPuNiSLK6srl8 Dani Donisa ddonisa Dani Donisa
Wed, 24 Aug 2011 04:18:12 -0700 How to make Lighthouse recognize you as a committer http://planet.ubiquo.me/how-to-make-lighthouse-recognize-you-as-a-com http://planet.ubiquo.me/how-to-make-lighthouse-recognize-you-as-a-com

In Lighthouse, traditionally all the commits were reported under the account that created the token in Github. Although a solution was made available some time ago, I don't think it has been very publicized, so here is how to do it.

You just have to go to edit your Profile and find the Committer Names section. Here you will be able to enter a name for every project you've been added to. Notice that the name is the full name in the commit, not the email or github nickname. As a picture is worth a thousand words, here is a screenshot showing an example from my account.

 

Ubiquo_1314183866825

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/497328/35341599.jpg http://posterous.com/users/5erKGZWE4z97 Bernat Foj Capell bfcapell Bernat Foj Capell
Sun, 14 Aug 2011 08:11:34 -0700 compass watch internals and error logs http://planet.ubiquo.me/compass-watch-internals-and-error-logs http://planet.ubiquo.me/compass-watch-internals-and-error-logs

This morning I was looking for how compass internally works and didn't find a lot of information about the internals, so I'll explain some of the basics that satiated my curiosity.

When you initialize compass in a project by doing

$> compass init rails project

You will see that when you change your scss files, your css files are automatically refreshed. Both sass and compass have a watch utility, and I thought one of these was fired on background to perform the update when necessary. But looking at the running processes I could not find the one that was doing it.

In fact, this action is performed by a third mechanism: sass includes a rack middleware to do it in every petition: http://sass-lang.com/docs/yardoc/Sass/Plugin/Rack.html which in turn is initialized by Compass.

You can also see the Compass watch implementation as a File System State Monitor to verify that is "simply" an independent process, and that does not play with your requests.

In fact, everything started because, due to an error in my scss file, nothing was being rendered properly. As a Compass noob I was expecting the compile error to be shown in my rails log, or even in a separate error log file. But there was no trace of the error, and I couldn't find a reference of where it should be. Well, Firebug was telling me that the generated css had no rules, but that doesn't mean it's empty! I finally "discovered" that Sass puts your trace in the generated css, as a comment.

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/497328/35341599.jpg http://posterous.com/users/5erKGZWE4z97 Bernat Foj Capell bfcapell Bernat Foj Capell
Tue, 10 May 2011 07:11:00 -0700 Increment page view counter even if page is cached http://planet.ubiquo.me/increment-page-view-counter-even-if-page-is-c http://planet.ubiquo.me/increment-page-view-counter-even-if-page-is-c


Adding cache to web pages is usually a good practice; however, making all the content static prevents you from adding some functionalities. A common case is when you need to increment a counter every time a cached resource is viewed.

If you have a model which is being observed by a Rails Sweeper, a simple update_attributes to increment the counter by 1 will expire all the cached object. And it will do it every time it is viewed. This behavior not only makes caching obsolete, but drastically decreases the overall performance of the site on each page hit.

There are some solutions to this problem, the most efficient probably would be using an alternate system to store stats like a key/value database (Redis, MongoDB, etc), but an easier approach would be to update the database directly to bypass the observer and skip the cache expiration. This can be done with the ActiveRecord method update_counters.

There are two problems with this solution. The first is obvious, with each page view the database will be hit, reducing a bit the performance. The second is that the cache has to be expired periodically to reflect the counter increments. But for most average sites it's a good solution.

Ubiquo Widgets expiring cache policy

With ubiquo it's quite easy to expire cached data of a widget after a given time. By defining the expires_in clause in the configuration policy file ("config/initializers/design_cache.rb") we can set the time to live (in seconds) of the cached object. Each widget should have it's own expiring configuration if needed.

Another way of expiring cached data is using a system cron job.

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1000659/avatar.jpeg http://posterous.com/users/4wzAoep2xMwF Guillem Català gcatala Guillem Català
Thu, 16 Dec 2010 06:04:00 -0800 Adding new media selectors in ajax calls http://planet.ubiquo.me/adding-new-media-selectors-in-ajax-calls http://planet.ubiquo.me/adding-new-media-selectors-in-ajax-calls

To load a form (or some fields for a form) in ajax call when some media selectors will be generated, there is a instance var that we must set to prevent the rest of media selectors stop working.

We just need to set

@is_media_included = true

at controller that will attend ajax call, before the media selector routine is called

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/5AqqUwt6ITER igallego igallego
Thu, 16 Dec 2010 06:02:00 -0800 New javascript and stylesheet helpers http://planet.ubiquo.me/new-javascript-and-stylesheet-helpers http://planet.ubiquo.me/new-javascript-and-stylesheet-helpers

Few weeks ago, we did a change in helpers used by ubiquo to load stylesheet and javascript files. Our idea was to simplify the inclusion of plugin files and "railsify" the sintax of these helpers.

Here are some examples:

With ubiquo_stylesheet_link_tag :defaults the following files will be loaded: ubiquo.css, ubiquo_application.css, lightwindow.css, listing.css, red.css and special IE files, located in public/stylesheets/ubiquo/, and all the files installed by plugins located in public/stylesheets/ubiquo/plugins/.

For the basic work with ubiquo the option :defaults is essential. In addition, if we want change the color stylesheet file, we can call helper with the option :color, ex: ubiquo_stylesheet_link_tag :defaults, :color => 'blue'. With this option, we are thinking to add support for custom ubiquo themes in the future. 

If we only want to load a single file located in ubiquo folder, we can do this: ubiquo_stylesheet_link_tag 'login'. These are the basic options for the helper, any other option will be used in the internal call to the rails helper: stylesheet_link_tag.

ubiquo_javascript_include_tag works very similar of stylesheet helper. With :defaults option, the files ubiquo.js and lightwindow.js will be loaded. These files are located in public/javascripts/ubiquo. The files installed in public/javascripts/ubiquo/plugins/ are loaded too. We can also specify other files, ex: ubiquo_javascript_include_tag 'ubiquo-calendar', :defaults. And, as in the other helper, the rest of options will be used in the internal call to the rails helper: javascript_include_tag.

We hope that these changes are useful.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/536615/spaceinvader-homer.png http://posterous.com/users/5AB17EYaTlg5 Toni Reina areina Toni Reina
Wed, 24 Nov 2010 01:28:00 -0800 Allowing a blank option in the category selector http://planet.ubiquo.me/allowing-a-blank-option-in-the-category-selec http://planet.ubiquo.me/allowing-a-blank-option-in-the-category-selec

When using the category selector, you may want to allow not to fill the field. The option to do it is pretty straightforward:

1
<%= form.category_selector :color, :include_blank => true %>

As you see, it's the same syntax that the select method has, so it's intuitive if you already know this option.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/497328/35341599.jpg http://posterous.com/users/5erKGZWE4z97 Bernat Foj Capell bfcapell Bernat Foj Capell
Fri, 23 Jul 2010 06:34:00 -0700 Using the ISSUU API to upload and delete publications http://planet.ubiquo.me/using-the-issuucom-api-to-upload-and-delete-p http://planet.ubiquo.me/using-the-issuucom-api-to-upload-and-delete-p

Issuu is a document sharing and publishing service that allows users to convert any type of publication file (PDF, word, ...) to a visually appealing media viewer, which presents the content like a real book with an unique "page flip" effect.

Today I am going to explain the basics of the Issuu API to learn how to upload and delete publications in Ruby.

First of all, we need to get the public and private API keys, which can be obtained by registering at the same issuu.com site.

To exchange information with Issuu using this API we will have to sign every petition we make.

Signing data

According to Issuu API specification (July 2010), the steps involved in signing an HTTP request are as follows:

  1. Sort request parameters alphabetically
      (e.g. foo=1, bar=2 sorts to bar=2, foo=1)
  2. Concatenate in order your API secret key and request name-value pairs (e.g. SECRETbar2baz3foo1)
  3. Calculate the signature as the MD5 hash of this string
  4. Include the signature parameter in the request encoded as lowercase HEX (e.g. signature=7431d31140cf412ab5caa73586d6324a)

Here is the representation of this algorithm in Ruby:

Where params contains all the parameters defined as a key/value hash. eg {access => private, :action => issuu.document.upload, ... }, and API_SECRET is the api secret key defined somewhere as a constant.

Uploading a document

Because of the cumbersome way that binary file upload works in Net::HTTP library (you have to implement it all yourself), we decided to use a gem called "Multipart" which allowed us to mix the binary file with the rest of the parameters.

Let's take a look at the code:

To upload a publication to Issuu each request must be sent to http://upload.issuu.com/1_0? using the POST method. First we prepare the file with the Multipart's object UploadIO. 

Then we set the parameters that specifies the type of petition we will make. The most important fields are action, format and name:

  • action: the upload action. This field will change when deleting a file.
  • format: specifies the language of the response (JSON or XML).
  • name: is the unique url of our publication.

Now we can sent the POST request using another Multipart gem method joining the "file" and "signature" parameters.

After sending the request, we can easily get the response status by decoding the JSON text returned by Issuu. If all goes well, we should receive an "ok" status followed by a limited number of response parameters, with information about the document which has been created.

Now it's a good idea to store the documentID so we can delete it later on.

Deleting a publication

Deleting a publication is fairly easy, we can use GET or POST method. We will use the second.

Here it is the code:

Note that we changed the url to http://api.issuu.com/1_0? and the action to issuu.document.delete

We can set the files to be deleted in the names field.

Other considerations

Because Issuu does not support file overwriting, we will have to delete each file before trying to upload it. You may be asking we could also make a request to check if the file is uploaded, but surprisingly you cannot make a request by documentID nor document name.

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1000659/avatar.jpeg http://posterous.com/users/4wzAoep2xMwF Guillem Català gcatala Guillem Català
Fri, 09 Jul 2010 09:02:19 -0700 Changing ubiquo plugin routes http://planet.ubiquo.me/changing-ubiquo-plugin-routes http://planet.ubiquo.me/changing-ubiquo-plugin-routes
Hi all,

Today I needed to create an Ubiquo based project with something special. This project is just an ubiquo project, without public part. So, I wished to move the /ubiquo routes to / .

This is the original code provided by the ubiquo generator:

1
2
3
4
5
map.from_plugin :ubiquo_core
map.from_plugin :ubiquo_authentication
map.from_plugin :ubiquo_access_control
map.from_plugin :ubiquo_scaffold
map.from_plugin :ubiquo_categories

This generates the typical Ubiquo routes, everithing inside /ubiquo. To remove that, or to change to /admin, just do that:

1
2
3
4
5
6
7
map.with_options :path_prefix => nil do |admin|
  admin.from_plugin :ubiquo_core
  admin.from_plugin :ubiquo_authentication
  admin.from_plugin :ubiquo_access_control
  admin.from_plugin :ubiquo_scaffold
  admin.from_plugin :ubiquo_categories
end

If :path_prefix is nil then all the routes provided by the plugins will be located in /, If you need to move to /admin, replace nil with "admin" or whatever you need.

That's all, I hope it helps you.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/466678/Yo.jpg http://posterous.com/users/5ebIGAFAX7UJ Albert Callarisa Roca acroca Albert Callarisa Roca
Tue, 22 Jun 2010 00:18:00 -0700 Filtering by category in the model http://planet.ubiquo.me/filtering-by-category-in-the-model http://planet.ubiquo.me/filtering-by-category-in-the-model

In ubiquo_categories, there are mainly two ways to filter instances by the category name.

The first one is the built-in named scope. Let's say we have the following

1
2
3
class Book
  categorized_with :genres, :size => :many
end

Now we can use the automatically generated "with_genres_in" named scope to filter by this field:

1
2
3
Book.with_genres_in('Thriller')
# also with multiple parameters
Book.with_genres_in('Biography', 'Travel')

Pretty handy. The second option to filter, is to retrieve the condition hash and then use it at our discretion. For example, in ubiquo models we usually have the filtered_search method, if we want to integrate this filter it would be done with:

1
2
3
4
5
6
7
8
9
def self.filtered_search(filters = {}, options = {})
  # ...
  case filter
  when :genres
    category_conditions_for :genres, value
  end
end

Book.filtered_search(:genres => 'Thriller')

Where "value" can be a single element or an array of strings or Category instances.

Hope you find this useful!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/497328/35341599.jpg http://posterous.com/users/5erKGZWE4z97 Bernat Foj Capell bfcapell Bernat Foj Capell
Fri, 18 Jun 2010 07:56:00 -0700 Ways to implement grouped navigation tabs http://planet.ubiquo.me/ways-to-implement-grouped-navigation-tabs http://planet.ubiquo.me/ways-to-implement-grouped-navigation-tabs

Currently in ubiquo, when we have so many tabs to display all them in a single row, the approach to follow is to group them under a new group name, and then, use that name as a link to have a sub-menu with links to each single resource display. This approach is hard to maintain, because each time we add / remove / change any of that resources, we must update several files (one for each resource that appear in list).

Another approach has been taken in one of out projects. By now, is a custom change for that single project, but it can be leveraged to a template system easily.

The approach is similar to the previous one, except that we only maintain one single file (_main_navtabs) for all ubiquo navigation. The navigation now will have only two parts for each menu item:
- The first one will be the title, and it's use can be either as an informative resource and a link to one of those resources grouped under that name
- The second, will be a list (<ul> / <li>). Each row in the list will be a link to a resource.

The clever idea in this approach is the interaction between both parts of menu items:

Items list will be a hidden element in DOM, that only appear when mouse is over group name. In this way, those lists can co-exist without being displayed together at any time. The effect applied to show each list is a SlideDown effect from scripaculous.

The following snipped of code will display a group with all resources under it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul id="menu_principal" class="menu_principal">
        <li class="pare <%= pare_tab_active?(["Child 1"]) %>">
            <a title="Group 1" class="pare" href="#">Group 1</a>
            <ul id="content_tabs" class="content_tabs">
                <li title="Ir a Child1" <%= tab_active?("Child1") %>>
                    <a title="Ir a Child1" href="/ubiquo/child1">Child1</a>
                </li>
                <li title="Ir a Child2" <%= tab_active?("Child2") %>>
                    <a title="Ir a Child2" href="/ubiquo/Child2">
                        Child2
                    </a>
                </li>
                <li title="Ir a Child3" <%= tab_active?("Child3) %>>
                    <a title="Ir a Child3" href="/ubiquo/Child3">Child3</a>
                </li>
                <li title="Ir a Child4" <%= tab_active?("Child4") %>>
                    <a title="Ir a Child4" href="/ubiquo/Child4">Child4</a>
                </li>
            </ul>
        </li>

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/5AqqUwt6ITER igallego igallego
Mon, 10 May 2010 03:20:00 -0700 Ubiquo logo: The golden ratio http://planet.ubiquo.me/ubiquo-logo-the-golden-ratio http://planet.ubiquo.me/ubiquo-logo-the-golden-ratio

We are designing a new version of Ubiquo's logo.

We are working on two lines: a completely new logo and a new interpretation of the current one.

Today I'll talk a little about the completely new logo version.

In this new version we want to introduce the concept of "golden ratio".

Mathematicians, architects,... have studied the golden ratio because of its unique and interesting properties, and it seems that "golden ratio" is in the majority of elements that surround us and is considered as "the perfect proportions".
We want you to find it in Ubiquo too.

Ok, for me there is not perfection, but golden ratio approximates my own sense of good proportions.

Here I show some of the tests I've done so far. I'll upload more.

In my opinion, "golden ratio" as a logo, aesthetically is a figure too classic for what it means Ubiquo, but we are trying to re-interpret it.

What do you think about it?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/551189/P1010651_p_gris.jpg http://posterous.com/users/5AvDfAz6UXHb Carles Garcia Padrao carlesgp Carles Garcia Padrao
Sat, 08 May 2010 11:30:00 -0700 Ubiquo Planet is already in your orbit! http://planet.ubiquo.me/ubiquo-planet-is-already-in-your-orbit http://planet.ubiquo.me/ubiquo-planet-is-already-in-your-orbit

Do you work regularly with Ubiquo? How was your experience programming with Ubiquo? Do you collaborate in any way with the CMS framework?

Welcome to Ubiquo Planet! In this space you can explain anything that might be of interest to Ubiquo's community.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/551189/P1010651_p_gris.jpg http://posterous.com/users/5AvDfAz6UXHb Carles Garcia Padrao carlesgp Carles Garcia Padrao