MuckProfiles¶ ↑
Muck profiles adds profiles to muck users. This implements a photo for users as well as an easy way to add any number of properties to enable total customization of the user’s profile information including privacy settings.
Installation¶ ↑
Muck profile relies upon the muck-engine and muck-users gems as well as paperclip. Add the following lines to your Gemfile:
gem 'paperclip' gem 'muck-engine' gem 'muck-users' gem 'muck-profiles' gem 'geokit' # Only needed if you want to add location to your profiles. MuckProfiles uses geokit to determine a users # location and to make it possible to find users that are within a given proximity.
Install the GeoKit Rails Plugin:
script/plugin install git://github.com/andre/geokit-rails.git
Be sure to get api keys from Google an Yahoo. Instructions for doing so can be found in config/initializers/geokit_config.rb after installing the plugin.
We recommend moving the keys into secrets.yml:
google_geo_key: 'some key' # API key for Google. Get it here: http://www.google.com/apis/maps/signup.html yahoo_geo_key: 'some key' # API key for Yahoo. Get it here: http://developer.yahoo.com/faq/index.html#appid
Then change the lines in config/initializers/geokit_config.rb to:
Geokit::Geocoders::yahoo = Secrets.yahoo_geo_key Geokit::Geocoders::google = Secrets.google_geo_key
If you used the muck template to create your rails application you will have a secrets.yml file. If not then you will need to create a secrets.yml file and then add the following to environment.rb right above Rails::Initializer.run do |config|
require 'ostruct' require 'yaml' ::Secrets = OpenStruct.new(YAML.load_file(File.expand_path('../secrets.yml', __FILE__))[Rails.env])
Omit secrets.yml from your version control system and use it to keep sensitive data like email server credentials
email_user_name: 'TODO_admin@#{domain_name}' # Email server username email_password = 'TODO_password' # Email server password production: <<: *DEFAULT # Add production only secrets staging: <<: *DEFAULT # Add staging only secrets development: <<: *DEFAULT # Development specific test: <<: *DEFAULT # Test specific
Usage¶ ↑
Create a model called profile.rb as show below. This mixes in the muck profile functionality but also permits further customization of the profile in your application.
class Profile < ActiveRecord::Base include MuckProfiles::Models::MuckProfile end
Modify your user model so that it has a profile:
class User < ActiveRecord::Base acts_as_authentic do |c| c.crypto_provider = Authlogic::CryptoProviders::BCrypt end include MuckUsers::Models::MuckUser include MuckProfiles::Models::MuckUser end
Your user model will now appear to have a ‘photo’ which is delegated to the profile model:
@user.photo # returns a photo object from paperclip
Configuration¶ ↑
Create an initializer to configure muck profiles:
MuckProfiles.configure do |config| config.enable_sunspot = false # This enables or disables sunspot for profiles. Only use acts_as_solr or sunspot not both. Sunspot does not include multicore support. config.enable_solr = true # This enables or disables acts as solr for profiles. config.enable_guess_location = true # If true the profile system will attempt to determine the user's location via IP and populated with the location, lat and lon fields. end
Acts as Solr¶ ↑
Muck Profiles works with solr to allow searching users.
If you enable acts_as_solr or sunspot you’ll also want to specify a default policy in your configuration. This policy is used to determine which fields are public and private. The default policy looks like this:
MuckProfiles.configure do |config| config.enable_sunspot = false # This enables or disables sunspot for profiles. Only use acts_as_solr or sunspot not both. Sunspot does not include multicore support. config.enable_solr = false # This enables or disables acts as solr for profiles. You will need to include muck-solr in your gemfile. config.enable_geokit = false # Turn geokit functionality on/off. You will need to include geokit in your gemfile. config.enable_guess_location = true # If true the profile system will attempt to determine the user's location via IP and populated with the location, lat and lon fields. config.policy => { :public => [:login, :first_name, :last_name, :about], :authenticated => [:location, :city, :state_id, :country_id, :language_id], :friends => [:email], :private => [] } end
If you add attributes to the profile as show below then you will want to specify which fields fall into each privacy setting. Note that it is also possible to add new privacy levels simply by adding new values to the hash. For example:
MuckProfiles.configure do |config| config.enable_sunspot = false # This enables or disables sunspot for profiles. Only use acts_as_solr or sunspot not both. Sunspot does not include multicore support. config.enable_solr = true # This enables or disables acts as solr for profiles. config.enable_guess_location = true # If true the profile system will attempt to determine the user's location via IP and populated with the location, lat and lon fields. config.policy => { :public => [:login, :first_name, :last_name, :about], :authenticated => [:location, :city, :state_id, :country_id, :language_id], :friends => [:email], :private => [] , :instructors => [:grades]} end
For each top level key a method will be auto generated that returns the values from each attribute concatenated together. Assuming we have a profile with fields populated calling each method might return something like this:
@profile.public_fields # returns 'testguy test guy I am the test guy' @profile.authenticated_fields # returns 'somewhere USA English' @profile.friends_fields # returns 'test@example.com' @profile.private_fields # returns ' '
Solr will index these fields and then permit you to search based on each privacy level.
Profile Attributes¶ ↑
The profile comes preconfigured with a basic set of common profile options. It is easy to add new fields. Simply add the fields to the profile using a migration:
class AddMoreFieldsToProfiles < ActiveRecord::Migration def self.up add_column :profiles, :occupation, :string add_column :profiles, :gender, :string add_column :profiles, :birthday, :datetime add_column :profiles, :company, :string add_column :profiles, :zip, :string add_column :profiles, :mobile_phone, :string add_column :profiles, :home_phone, :string add_column :profiles, :alumni_of, :string add_column :profiles, :relationship_status, :string end def self.down add_column :profiles, :occupation add_column :profiles, :gender add_column :profiles, :birthday add_column :profiles, :company add_column :profiles, :zip add_column :profiles, :mobile_phone add_column :profiles, :home_phone add_column :profiles, :alumni_of add_column :profiles, :relationship_status end end
Next create a new views/profiles/edit.html.erb file. The built in file is very basic and makes it easy to add additional fields. The ‘profile_form’ method will create form elements for the built in fields. Add extra fields after that.
<div id="edit_content" class="span-24 colborder column"> <%= output_errors(t('muck.profiles.problem_editing_profile'), {:class => 'help-box'}, @user) %> <%= profile_form(@user) do |f| -%> <%# can add form fields as desired here -%> <% end -%> </div>
Last create view/profiles/show.html.erb. There is a built in show page however it is assumed that most applications will implement a custom show page to hightlight the focus of the system.
<div class="span-24 colborder column"> <%= icon @user, :thumb %> <p><%= @user.full_name %></p> <p><%= link_to t('muck.profiles.edit_profile'), edit_user_profile_path(@user) if @profile.can_edit?(current_user) %></p> <!-- Add more fields and customize the profile. --> </div>
It’s important to sanitize user input. If you add fields to the profile then be sure to prevent cross site scripting. Override the ‘sanitize_attributes’ method in your model and add your new fields. Note that you can also override ‘sanitize_level’ to determine how sanitization occurs.
# Sanitize content before saving. This prevents XSS attacks and other malicious html. def sanitize_attributes if self.sanitize_level self.about = Sanitize.clean(self.about, self.sanitize_level) self.location = Sanitize.clean(self.location, self.sanitize_level) # add your fields end end # Override this method to control sanitization levels. # Currently a user who is an admin will not have their content sanitized. A user # in any role 'editor', 'manager', or 'contributor' will be given the 'RELAXED' settings # while all other users will get 'BASIC'. # # Options are from sanitze: # nil - no sanitize # Sanitize::Config::RELAXED # Sanitize::Config::BASIC # Sanitize::Config::RESTRICTED # for more details see: http://rgrove.github.com/sanitize/ def sanitize_level return Sanitize::Config::BASIC if self.user.nil? return nil if self.user.admin? return Sanitize::Config::RELAXED if self.user.any_role?('editor', 'manager', 'contributor') Sanitize::Config::BASIC end
Copyright © 2009-2010 Tatemae, released under the MIT license