refinerycms-map 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/admin/map_locations_controller.rb +5 -0
- data/app/controllers/map_locations_controller.rb +25 -0
- data/app/models/map_location.rb +59 -0
- data/app/views/admin/map_locations/_form.html.erb +54 -0
- data/app/views/admin/map_locations/_map_location.html.erb +16 -0
- data/app/views/admin/map_locations/edit.html.erb +1 -0
- data/app/views/admin/map_locations/index.html.erb +28 -0
- data/app/views/admin/map_locations/new.html.erb +1 -0
- data/app/views/map_locations/index.html.erb +10 -0
- data/app/views/map_locations/show.html.erb +9 -0
- data/config/locales/en.yml +31 -0
- data/config/routes.rb +7 -0
- data/generators/map/map_generator.rb +37 -0
- data/generators/map/templates/jquery.jmapping.min.js +20 -0
- data/generators/map/templates/jquery.metadata.js +148 -0
- data/generators/map/templates/mapiconmaker.js +227 -0
- data/generators/map/templates/migration.rb +44 -0
- data/lib/gemspec.rb +30 -0
- data/lib/map.rb +9 -0
- data/license.md +21 -0
- data/rails/init.rb +13 -0
- data/readme.md +39 -0
- data/test/unit/map_location_test.rb +4 -0
- metadata +89 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
class MapLocationsController < ApplicationController
|
2
|
+
|
3
|
+
before_filter :find_locations, :find_page
|
4
|
+
before_filter :find_location, :only => [:show]
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def find_locations
|
9
|
+
if params[:q]
|
10
|
+
coords = Geocode.find_address(params[:q])
|
11
|
+
@map_locations = MapLocation.nearest_to(coords.latitude, coords.longitude, 50)
|
12
|
+
else
|
13
|
+
@map_locations = MapLocation.all
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_location
|
18
|
+
@map_location = MapLocation.find(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_page
|
22
|
+
@page = Page.find_by_link_url("/map")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class MapLocation < ActiveRecord::Base
|
2
|
+
|
3
|
+
validates_presence_of :title, :address, :city, :state, :zipcode
|
4
|
+
|
5
|
+
has_friendly_id :title, :use_slug => true
|
6
|
+
|
7
|
+
acts_as_indexed :fields => [:title, :address, :city, :state, :zipcode]
|
8
|
+
|
9
|
+
default_scope :order => "state, city, title"
|
10
|
+
|
11
|
+
before_save :set_lat_and_lng
|
12
|
+
|
13
|
+
# for will_paginate
|
14
|
+
def self.per_page
|
15
|
+
20
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Returns a scope which queries for the nearest locations to the requested
|
20
|
+
# coordinates (latitude and longitude in decimal format).
|
21
|
+
#
|
22
|
+
# This method uses a variation of the Haversine Formula. Conversions have
|
23
|
+
# already been made to radians and the Earth's radius (3956mi) has already
|
24
|
+
# been baked in. The variation arises where the distance is not calculated
|
25
|
+
# against every instance in the database, instead a rough box is drawn
|
26
|
+
# around the source point that encapsulates the desired radius. Only those
|
27
|
+
# objects within the box are calculated for distance.
|
28
|
+
#
|
29
|
+
def self.nearest_to(latitude, longitude, radius = 100)
|
30
|
+
latitude_delta = radius.to_f / 69.0
|
31
|
+
longitude_delta = radius.to_f / (Math.cos(latitude) * 69.0).abs
|
32
|
+
scoped({
|
33
|
+
:select => "*, 7912 * ASIN(SQRT(POWER(SIN((#{latitude} - lat) * 0.00872664626), 2) + COS(#{latitude} * 0.0174532925) * COS(#{latitude} * 0.0174532925) * POWER(SIN((#{longitude} - lng) * 0.00872664626), 2))) as distance_from_source",
|
34
|
+
:order => 'distance_from_source ASC',
|
35
|
+
:conditions => "lat BETWEEN #{latitude - latitude_delta} AND #{latitude + latitude_delta} AND lng BETWEEN #{longitude - longitude_delta} AND #{longitude + longitude_delta}"
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
def full_address
|
40
|
+
"%s, %s, %s %s" % [self.address, self.city, self.state, self.zipcode]
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
|
47
|
+
def set_lat_and_lng
|
48
|
+
if address_changed? || city_changed? || state_changed? || zipcode_changed?
|
49
|
+
Geocode.find_address(self.full_address).tap do |coordinate|
|
50
|
+
self.lat = coordinate.latitude
|
51
|
+
self.lng = coordinate.longitude
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def lat=(input); write_attribute(:lat, input); end
|
57
|
+
def lng=(input); write_attribute(:lng, input); end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<% form_for [:admin, @map_location] do |f| %>
|
2
|
+
<%= f.error_messages %>
|
3
|
+
|
4
|
+
<div class='hemisquare'>
|
5
|
+
<div class='field'>
|
6
|
+
<%= f.label :title %>
|
7
|
+
<%= f.text_field :title, :class => "larger widest" %>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class='field'>
|
11
|
+
<%= f.label :address %>
|
12
|
+
<%= f.text_field :address %>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class='field'>
|
16
|
+
<%= f.label :city %>
|
17
|
+
<%= f.text_field :city %>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<div class='field'>
|
21
|
+
<%= f.label :state %>
|
22
|
+
<%= f.text_field :state %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class='field'>
|
26
|
+
<%= f.label :zipcode %>
|
27
|
+
<%= f.text_field :zipcode %>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class='field'>
|
31
|
+
<%= f.label :phone %>
|
32
|
+
<%= f.text_field :phone %>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class='field'>
|
36
|
+
<%= f.label :url %>
|
37
|
+
<%= f.text_field :url %>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<div class='hemisquare right_side'>
|
42
|
+
<br/><br/><br/><br/><br/><br/><br/>
|
43
|
+
<%= image_tag "http://maps.google.com/maps/api/staticmap?size=400x400&markers=#{@map_location.full_address.parameterize('+')}&zoom=14&sensor=false", :class => "location_map" %>
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div class='clearfix'></div>
|
47
|
+
|
48
|
+
<%= render :partial => "/shared/admin/form_actions",
|
49
|
+
:locals => {
|
50
|
+
:f => f,
|
51
|
+
:continue_editing => false
|
52
|
+
} %>
|
53
|
+
|
54
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<li class='clearfix record <%= cycle("on", "on-hover") %>'>
|
2
|
+
<span class='title'>
|
3
|
+
<%=h map_location.title %>
|
4
|
+
<span class="preview"><%=h map_location.full_address %></span>
|
5
|
+
</span>
|
6
|
+
<span class='actions'>
|
7
|
+
<%= link_to refinery_icon_tag('application_go.png'), map_location_url(map_location),
|
8
|
+
:title => t('.view_live'),
|
9
|
+
:target => "_blank" %>
|
10
|
+
<%= link_to refinery_icon_tag('application_edit.png'), edit_admin_map_location_path(map_location),
|
11
|
+
:title => t('.edit') %>
|
12
|
+
<%= link_to refinery_icon_tag('delete.png'), admin_map_location_path(map_location),
|
13
|
+
:class => "cancel confirm-delete",
|
14
|
+
:title => t('.delete') %>
|
15
|
+
</span>
|
16
|
+
</li>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => "form" %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div id='actions'>
|
2
|
+
<ul>
|
3
|
+
<li>
|
4
|
+
<%= render :partial => "/shared/admin/search", :locals => {:url => admin_map_locations_url} %>
|
5
|
+
</li>
|
6
|
+
<li>
|
7
|
+
<%= link_to t('.create'), new_admin_map_location_url, :class => "add_icon" %>
|
8
|
+
</li>
|
9
|
+
</ul>
|
10
|
+
</div>
|
11
|
+
<div id='records'>
|
12
|
+
<%= "<h2>#{t('admin.search_results_for', :query => params[:search])}</h2>" if searching? %>
|
13
|
+
<% if @map_locations.any? %>
|
14
|
+
<%= will_paginate @map_locations, :previous_label => '«', :next_label => '»' %>
|
15
|
+
<ul>
|
16
|
+
<%= render :partial => "map_location", :collection => @map_locations %>
|
17
|
+
</ul>
|
18
|
+
<%= will_paginate @map_locations, :previous_label => '«', :next_label => '»' %>
|
19
|
+
<% else %>
|
20
|
+
<% unless searching? %>
|
21
|
+
<p>
|
22
|
+
<strong><%= t('.no_items_yet') %></strong>
|
23
|
+
</p>
|
24
|
+
<% else %>
|
25
|
+
<p><%= t('admin.search_no_results') %></p>
|
26
|
+
<% end %>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => "form" %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% content_for :body_content_left do %>
|
2
|
+
<%= @page[:body] if @map_locations.empty? %>
|
3
|
+
<%= render :partial => 'map', :locals => {:width => 500, :height => 500} %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<% content_for :body_content_right do %>
|
7
|
+
<%= render :partial => 'locations' %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= render :partial => "/shared/content_page" %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% content_for :body_content_title, "<h1>#{@map_location.title}</h1>" %>
|
2
|
+
<% content_for :body_content_left do %>
|
3
|
+
<h2>Map Goes Here</h2>
|
4
|
+
<% end %>
|
5
|
+
<% content_for :body_content_right do %>
|
6
|
+
<h3>Location Details Go Here</h3>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= render :partial => "/shared/content_page" %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
en:
|
2
|
+
plugins:
|
3
|
+
map:
|
4
|
+
title: Map
|
5
|
+
admin:
|
6
|
+
map_locations:
|
7
|
+
map_location:
|
8
|
+
view_live: "View this location live on the map<br/><em>(opens in a new window)</em>"
|
9
|
+
edit: "Edit this location"
|
10
|
+
delete: "Remove this location forever"
|
11
|
+
index:
|
12
|
+
actions: Actions
|
13
|
+
create: "Create Location"
|
14
|
+
news_item: Location
|
15
|
+
no_items: "Sorry, no results found."
|
16
|
+
no_items_yet: 'There are no locations yet. Click "Create Location" to add one.'
|
17
|
+
map_locations:
|
18
|
+
show:
|
19
|
+
back_to_index: "Back to the map"
|
20
|
+
activerecord:
|
21
|
+
attributes:
|
22
|
+
map_location:
|
23
|
+
title: Title
|
24
|
+
address: Address
|
25
|
+
city: City
|
26
|
+
state: State
|
27
|
+
zipcode: Zip Code
|
28
|
+
phone: Phone Number
|
29
|
+
url: Url
|
30
|
+
models:
|
31
|
+
map_location: Location
|
data/config/routes.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class MapGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
def initialize(*runtime_args)
|
4
|
+
# set first argument to the table's name so that the user doesn't have to pass it in.
|
5
|
+
runtime_args[0] = ["map_locations"]
|
6
|
+
super(*runtime_args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def banner
|
10
|
+
"Usage: script/generate map"
|
11
|
+
end
|
12
|
+
|
13
|
+
def manifest
|
14
|
+
record do |m|
|
15
|
+
m.migration_template 'migration.rb', 'db/migrate',
|
16
|
+
:migration_file_name => "create_structure_for_map",
|
17
|
+
:assigns => {
|
18
|
+
:migration_name => "CreateStructureForMap",
|
19
|
+
:table_name => "map_locations",
|
20
|
+
:attributes => [
|
21
|
+
Rails::Generator::GeneratedAttribute.new("title", "string"),
|
22
|
+
Rails::Generator::GeneratedAttribute.new("address", "string"),
|
23
|
+
Rails::Generator::GeneratedAttribute.new("city", "string"),
|
24
|
+
Rails::Generator::GeneratedAttribute.new("state", "string"),
|
25
|
+
Rails::Generator::GeneratedAttribute.new("zipcode", "string"),
|
26
|
+
Rails::Generator::GeneratedAttribute.new("phone", "string"),
|
27
|
+
Rails::Generator::GeneratedAttribute.new("url", "string"),
|
28
|
+
]
|
29
|
+
}
|
30
|
+
m.file "jquery.jmapping.min.js", "public/javascripts/jquery.jmapping.min.js"
|
31
|
+
m.file "jquery.metadata.js", "public/javascripts/jquery.metadata.js"
|
32
|
+
m.file "mapiconmaker.js", "public/javascripts/mapiconmaker.js"
|
33
|
+
m.file "markermanager.js", "public/javascripts/markermanager.js"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end if defined?(Rails::Generator::NamedBase)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
* jMapping v1.4.0 - jQuery plugin for creating Google Maps
|
3
|
+
*
|
4
|
+
* Copyright (c) 2009-2010 Brian Landau (Viget Labs)
|
5
|
+
* MIT License: http://www.opensource.org/licenses/mit-license.php
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
if(GMap2){GMap2.prototype.centerAndZoomOnBounds=function(bounds){this.setCenter(bounds.getCenter(),this.getBoundsZoomLevel(bounds));};}
|
9
|
+
(function($){$.jMapping=function(map_elm,options){var settings,gmarkers,mapped,map,markerManager,places,bounds,jMapper;map_elm=(typeof map_elm=="string")?$(map_elm).get(0):map_elm;if(!($(map_elm).data('jMapping'))){settings=$.extend(true,{},$.jMapping.defaults);$.extend(true,settings,options);gmarkers={};var init=function(doUpdate){var info_window_selector,min_zoom,bounds_zoom_level;info_window_selector=[settings.side_bar_selector,settings.location_selector,settings.info_window_selector].join(' ');$(info_window_selector).hide();places=getPlaces();bounds=getBounds(doUpdate);if(doUpdate){gmarkers={};markerManager.clearMarkers();map.checkResize();map.centerAndZoomOnBounds(bounds);}else{map=createMap();markerManager=new MarkerManager(map);}
|
10
|
+
places.each(function(){var marker=createMarker(this);if(!(settings.link_selector===false)){setupLink(this);}
|
11
|
+
$(document).trigger('markerCreated.jMapping',[marker]);});bounds_zoom_level=map.getBoundsZoomLevel(bounds);min_zoom=(bounds_zoom_level<7)?0:(bounds_zoom_level-7);markerManager.addMarkers(gmarkersArray(),min_zoom);markerManager.refresh();if(!(settings.link_selector===false)&&!doUpdate){attachMapsEventToLinks();}};var createMap=function(){map=new GMap2(map_elm);if($.isFunction(settings.map_config)){settings.map_config(map);}else{map.setMapType(G_NORMAL_MAP);map.addControl(new GSmallMapControl());}
|
12
|
+
map.centerAndZoomOnBounds(bounds);if(typeof settings.default_zoom_level=="number"){map.setZoom(settings.default_zoom_level);}
|
13
|
+
return map;};var getPlaces=function(){return $(settings.side_bar_selector+' '+settings.location_selector);};var getPlacesData=function(doUpdate){return places.map(function(){if(doUpdate){$(this).data('metadata',false);}
|
14
|
+
return $(this).metadata(settings.metadata_options);});};var getBounds=function(doUpdate){var places_data=getPlacesData(doUpdate);var newBounds=new GLatLngBounds($.jMapping.makeGLatLng(places_data[0].point),$.jMapping.makeGLatLng(places_data[0].point));for(var i=1,len=places_data.length;i<len;i++){newBounds.extend($.jMapping.makeGLatLng(places_data[i].point));}
|
15
|
+
return newBounds;};var setupLink=function(place_elm){var $place_elm=$(place_elm),location_data=$place_elm.metadata(settings.metadata_options),link=$place_elm.find(settings.link_selector);link.attr('href',("#"+location_data.id));};var chooseIconOptions=function(category){if(settings.category_icon_options){if($.isFunction(settings.category_icon_options)){return settings.category_icon_options(category);}else{return settings.category_icon_options[category]||settings.category_icon_options['default'];}}else{return{};}};var createMarker=function(place_elm){var $place_elm=$(place_elm),place_data,point,marker,$info_window_elm,custom_icon,icon_options;place_data=$place_elm.metadata(settings.metadata_options);point=$.jMapping.makeGLatLng(place_data.point);if(settings.category_icon_options){icon_options=chooseIconOptions(place_data.category);if(typeof icon_options==="string"){custom_icon=new GIcon(G_DEFAULT_ICON,icon_options);}else if(icon_options instanceof GIcon){custom_icon=icon_options;}else{if(!icon_options.style)icon_options.style='Marker';custom_icon=MapIconMaker['create'+icon_options.style+'Icon'](icon_options);}
|
16
|
+
marker=new GMarker(point,{icon:custom_icon});}else{marker=new GMarker(point);}
|
17
|
+
$info_window_elm=$place_elm.find(settings.info_window_selector);if($info_window_elm.length>0){marker.bindInfoWindowHtml($info_window_elm.html(),{maxWidth:settings.info_window_max_width});}
|
18
|
+
gmarkers[parseInt(place_data.id,10)]=marker;return marker;};var attachMapsEventToLinks=function(){var location_link_selector=[settings.side_bar_selector,settings.location_selector,settings.link_selector].join(' ');$(location_link_selector).live('click',function(e){e.preventDefault();var marker_index=parseInt($(this).attr('href').split('#')[1],10);GEvent.trigger(gmarkers[marker_index],"click");});};var gmarkersArray=function(){var marker_arr=[];$.each(gmarkers,function(key,value){marker_arr.push(value);});return marker_arr;};if(GBrowserIsCompatible()){if($(document).trigger('beforeMapping.jMapping',[settings])!=false){init();mapped=true;}else{mapped=false;}
|
19
|
+
jMapper={gmarkers:gmarkers,settings:settings,mapped:mapped,map:map,markerManager:markerManager,gmarkersArray:gmarkersArray,getBounds:getBounds,getPlacesData:getPlacesData,getPlaces:getPlaces,update:function(){if($(document).trigger('beforeUpdate.jMapping',[this])!=false){init(true);this.map=map;this.gmarkers=gmarkers;this.markerManager=markerManager;$(document).trigger('afterUpdate.jMapping',[this]);}}};$(document).trigger('afterMapping.jMapping',[jMapper]);return jMapper;}else{mapped=false;return null;}}else{return $(map_elm).data('jMapping');}};$.extend($.jMapping,{defaults:{side_bar_selector:'#map-side-bar:first',location_selector:'.map-location',link_selector:'a.map-link',info_window_selector:'.info-box',info_window_max_width:425,metadata_options:{type:'attr',name:'data-jmapping'}},makeGLatLng:function(place_point){return new GLatLng(place_point.lat,place_point.lng);}});$.fn.jMapping=function(options){if((options=='update')&&$(this[0]).data('jMapping')){$(this[0]).data('jMapping').update();}else{if(options=='update')options={};$(this[0]).data('jMapping',$.jMapping(this[0],options));}
|
20
|
+
return this;};})(jQuery);
|
@@ -0,0 +1,148 @@
|
|
1
|
+
/*
|
2
|
+
* Metadata - jQuery plugin for parsing metadata from elements
|
3
|
+
*
|
4
|
+
* Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan
|
5
|
+
*
|
6
|
+
* Dual licensed under the MIT and GPL licenses:
|
7
|
+
* http://www.opensource.org/licenses/mit-license.php
|
8
|
+
* http://www.gnu.org/licenses/gpl.html
|
9
|
+
*
|
10
|
+
* Revision: $Id: jquery.metadata.js 3640 2007-10-11 18:34:38Z pmclanahan $
|
11
|
+
*
|
12
|
+
*/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
|
16
|
+
* in the JSON will become a property of the element itself.
|
17
|
+
*
|
18
|
+
* There are four supported types of metadata storage:
|
19
|
+
*
|
20
|
+
* attr: Inside an attribute. The name parameter indicates *which* attribute.
|
21
|
+
*
|
22
|
+
* class: Inside the class attribute, wrapped in curly braces: { }
|
23
|
+
*
|
24
|
+
* elem: Inside a child element (e.g. a script tag). The
|
25
|
+
* name parameter indicates *which* element.
|
26
|
+
* html5: Values are stored in data-* attributes.
|
27
|
+
*
|
28
|
+
* The metadata for an element is loaded the first time the element is accessed via jQuery.
|
29
|
+
*
|
30
|
+
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
|
31
|
+
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
|
32
|
+
*
|
33
|
+
* @name $.metadata.setType
|
34
|
+
*
|
35
|
+
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
|
36
|
+
* @before $.metadata.setType("class")
|
37
|
+
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
38
|
+
* @desc Reads metadata from the class attribute
|
39
|
+
*
|
40
|
+
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
|
41
|
+
* @before $.metadata.setType("attr", "data")
|
42
|
+
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
43
|
+
* @desc Reads metadata from a "data" attribute
|
44
|
+
*
|
45
|
+
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
|
46
|
+
* @before $.metadata.setType("elem", "script")
|
47
|
+
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
48
|
+
* @desc Reads metadata from a nested script element
|
49
|
+
*
|
50
|
+
* @example <p id="one" class="some_class" data-item_id="1" data-item_label="Label">This is a p</p>
|
51
|
+
* @before $.metadata.setType("html5")
|
52
|
+
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
53
|
+
* @desc Reads metadata from a series of data-* attributes
|
54
|
+
*
|
55
|
+
* @param String type The encoding type
|
56
|
+
* @param String name The name of the attribute to be used to get metadata (optional)
|
57
|
+
* @cat Plugins/Metadata
|
58
|
+
* @descr Sets the type of encoding to be used when loading metadata for the first time
|
59
|
+
* @type undefined
|
60
|
+
* @see metadata()
|
61
|
+
*/
|
62
|
+
|
63
|
+
(function($) {
|
64
|
+
|
65
|
+
$.extend({
|
66
|
+
metadata : {
|
67
|
+
defaults : {
|
68
|
+
type: 'class',
|
69
|
+
name: 'metadata',
|
70
|
+
cre: /({.*})/,
|
71
|
+
single: 'metadata'
|
72
|
+
},
|
73
|
+
setType: function( type, name ){
|
74
|
+
this.defaults.type = type;
|
75
|
+
this.defaults.name = name;
|
76
|
+
},
|
77
|
+
get: function( elem, opts ){
|
78
|
+
var settings = $.extend({},this.defaults,opts);
|
79
|
+
// check for empty string in single property
|
80
|
+
if ( !settings.single.length ) settings.single = 'metadata';
|
81
|
+
|
82
|
+
var data = $.data(elem, settings.single);
|
83
|
+
// returned cached data if it already exists
|
84
|
+
if ( data ) return data;
|
85
|
+
|
86
|
+
data = "{}";
|
87
|
+
|
88
|
+
var getData = function(data) {
|
89
|
+
if(typeof data != "string") return data;
|
90
|
+
|
91
|
+
if( data.indexOf('{') < 0 ) {
|
92
|
+
data = eval("(" + data + ")");
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
var getObject = function(data) {
|
97
|
+
if(typeof data != "string") return data;
|
98
|
+
|
99
|
+
data = eval("(" + data + ")");
|
100
|
+
return data;
|
101
|
+
}
|
102
|
+
|
103
|
+
if ( settings.type == "html5" ) {
|
104
|
+
var object = {};
|
105
|
+
$( elem.attributes ).each(function() {
|
106
|
+
var name = this.nodeName;
|
107
|
+
if(name.match(/^data-/)) name = name.replace(/^data-/, '');
|
108
|
+
else return true;
|
109
|
+
object[name] = getObject(this.nodeValue);
|
110
|
+
});
|
111
|
+
} else {
|
112
|
+
if ( settings.type == "class" ) {
|
113
|
+
var m = settings.cre.exec( elem.className );
|
114
|
+
if ( m )
|
115
|
+
data = m[1];
|
116
|
+
} else if ( settings.type == "elem" ) {
|
117
|
+
if( !elem.getElementsByTagName ) return;
|
118
|
+
var e = elem.getElementsByTagName(settings.name);
|
119
|
+
if ( e.length )
|
120
|
+
data = $.trim(e[0].innerHTML);
|
121
|
+
} else if ( elem.getAttribute != undefined ) {
|
122
|
+
var attr = elem.getAttribute( settings.name );
|
123
|
+
if ( attr )
|
124
|
+
data = attr;
|
125
|
+
}
|
126
|
+
object = getObject(data.indexOf("{") < 0 ? "{" + data + "}" : data);
|
127
|
+
}
|
128
|
+
|
129
|
+
$.data( elem, settings.single, object );
|
130
|
+
return object;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
});
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Returns the metadata object for the first member of the jQuery object.
|
137
|
+
*
|
138
|
+
* @name metadata
|
139
|
+
* @descr Returns element's metadata object
|
140
|
+
* @param Object opts An object contianing settings to override the defaults
|
141
|
+
* @type jQuery
|
142
|
+
* @cat Plugins/Metadata
|
143
|
+
*/
|
144
|
+
$.fn.metadata = function( opts ){
|
145
|
+
return $.metadata.get( this[0], opts );
|
146
|
+
};
|
147
|
+
|
148
|
+
})(jQuery);
|
@@ -0,0 +1,227 @@
|
|
1
|
+
/**
|
2
|
+
* @name MapIconMaker
|
3
|
+
* @version 1.1
|
4
|
+
* @author Pamela Fox
|
5
|
+
* @copyright (c) 2008 Pamela Fox
|
6
|
+
* @homepage http://gmaps-utility-library.googlecode.com/svn/trunk/mapiconmaker
|
7
|
+
* @fileoverview This gives you static functions for creating dynamically
|
8
|
+
* sized and colored marker icons using the Charts API marker output.
|
9
|
+
*/
|
10
|
+
|
11
|
+
/*
|
12
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
13
|
+
* you may not use this file except in compliance with the License.
|
14
|
+
* You may obtain a copy of the License at
|
15
|
+
*
|
16
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
17
|
+
*
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
21
|
+
* See the License for the specific language governing permissions and
|
22
|
+
* limitations under the License.
|
23
|
+
*/
|
24
|
+
|
25
|
+
/**
|
26
|
+
* @name MarkerIconOptions
|
27
|
+
* @class This class represents optional arguments to {@link createMarkerIcon},
|
28
|
+
* {@link createFlatIcon}, or {@link createLabeledMarkerIcon}. Each of the
|
29
|
+
* functions use a subset of these arguments. See the function descriptions
|
30
|
+
* for the list of supported options.
|
31
|
+
* @property {Number} [width=32] Specifies, in pixels, the width of the icon.
|
32
|
+
* The width may include some blank space on the side, depending on the
|
33
|
+
* height of the icon, as the icon will scale its shape proportionately.
|
34
|
+
* @property {Number} [height=32] Specifies, in pixels, the height of the icon.
|
35
|
+
* @property {String} [primaryColor="#ff0000"] Specifies, as a hexadecimal
|
36
|
+
* string, the color used for the majority of the icon body.
|
37
|
+
* @property {String} [cornerColor="#ffffff"] Specifies, as a hexadecimal
|
38
|
+
* string, the color used for the top corner of the icon. If you'd like the
|
39
|
+
* icon to have a consistent color, make the this the same as the
|
40
|
+
* {@link primaryColor}.
|
41
|
+
* @property {String} [strokeColor="#000000"] Specifies, as a hexadecimal
|
42
|
+
* string, the color used for the outside line (stroke) of the icon.
|
43
|
+
* @property {String} [shadowColor="#000000"] Specifies, as a hexadecimal
|
44
|
+
* string, the color used for the shadow of the icon.
|
45
|
+
* @property {String} [label=""] Specifies a character or string to display
|
46
|
+
* inside the body of the icon. Generally, one or two characters looks best.
|
47
|
+
* @property {String} [labelColor="#000000"] Specifies, as a hexadecimal
|
48
|
+
* string, the color used for the label text.
|
49
|
+
* @property {Number} [labelSize=0] Specifies, in pixels, the size of the label
|
50
|
+
* text. If set to 0, the text auto-sizes to fit the icon body.
|
51
|
+
* @property {String} [shape="circle"] Specifies shape of the icon. Current
|
52
|
+
* options are "circle" for a circle or "roundrect" for a rounded rectangle.
|
53
|
+
* @property {Boolean} [addStar = false] Specifies whether to add a star to the
|
54
|
+
* edge of the icon.
|
55
|
+
* @property {String} [starPrimaryColor="#FFFF00"] Specifies, as a hexadecimal
|
56
|
+
* string, the color used for the star body.
|
57
|
+
* @property {String} [starStrokeColor="#0000FF"] Specifies, as a hexadecimal
|
58
|
+
* string, the color used for the outside line (stroke) of the star.
|
59
|
+
*/
|
60
|
+
|
61
|
+
/**
|
62
|
+
* This namespace contains functions that you can use to easily create
|
63
|
+
* dynamically sized, colored, and labeled icons.
|
64
|
+
* @namespace
|
65
|
+
*/
|
66
|
+
var MapIconMaker = {};
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Creates an icon based on the specified options in the
|
70
|
+
* {@link MarkerIconOptions} argument.
|
71
|
+
* Supported options are: width, height, primaryColor,
|
72
|
+
* strokeColor, and cornerColor.
|
73
|
+
* @param {MarkerIconOptions} [opts]
|
74
|
+
* @return {GIcon}
|
75
|
+
*/
|
76
|
+
MapIconMaker.createMarkerIcon = function (opts) {
|
77
|
+
var width = opts.width || 32;
|
78
|
+
var height = opts.height || 32;
|
79
|
+
var primaryColor = opts.primaryColor || "#ff0000";
|
80
|
+
var strokeColor = opts.strokeColor || "#000000";
|
81
|
+
var cornerColor = opts.cornerColor || "#ffffff";
|
82
|
+
|
83
|
+
var baseUrl = "http://chart.apis.google.com/chart?cht=mm";
|
84
|
+
var iconUrl = baseUrl + "&chs=" + width + "x" + height +
|
85
|
+
"&chco=" + cornerColor.replace("#", "") + "," +
|
86
|
+
primaryColor.replace("#", "") + "," +
|
87
|
+
strokeColor.replace("#", "") + "&ext=.png";
|
88
|
+
var icon = new GIcon(G_DEFAULT_ICON);
|
89
|
+
icon.image = iconUrl;
|
90
|
+
icon.iconSize = new GSize(width, height);
|
91
|
+
icon.shadowSize = new GSize(Math.floor(width * 1.6), height);
|
92
|
+
icon.iconAnchor = new GPoint(width / 2, height);
|
93
|
+
icon.infoWindowAnchor = new GPoint(width / 2, Math.floor(height / 12));
|
94
|
+
icon.printImage = iconUrl + "&chof=gif";
|
95
|
+
icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";
|
96
|
+
iconUrl = baseUrl + "&chs=" + width + "x" + height +
|
97
|
+
"&chco=" + cornerColor.replace("#", "") + "," +
|
98
|
+
primaryColor.replace("#", "") + "," +
|
99
|
+
strokeColor.replace("#", "");
|
100
|
+
icon.transparent = iconUrl + "&chf=a,s,ffffff11&ext=.png";
|
101
|
+
|
102
|
+
icon.imageMap = [
|
103
|
+
width / 2, height,
|
104
|
+
(7 / 16) * width, (5 / 8) * height,
|
105
|
+
(5 / 16) * width, (7 / 16) * height,
|
106
|
+
(7 / 32) * width, (5 / 16) * height,
|
107
|
+
(5 / 16) * width, (1 / 8) * height,
|
108
|
+
(1 / 2) * width, 0,
|
109
|
+
(11 / 16) * width, (1 / 8) * height,
|
110
|
+
(25 / 32) * width, (5 / 16) * height,
|
111
|
+
(11 / 16) * width, (7 / 16) * height,
|
112
|
+
(9 / 16) * width, (5 / 8) * height
|
113
|
+
];
|
114
|
+
for (var i = 0; i < icon.imageMap.length; i++) {
|
115
|
+
icon.imageMap[i] = parseInt(icon.imageMap[i]);
|
116
|
+
}
|
117
|
+
|
118
|
+
return icon;
|
119
|
+
};
|
120
|
+
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Creates a flat icon based on the specified options in the
|
124
|
+
* {@link MarkerIconOptions} argument.
|
125
|
+
* Supported options are: width, height, primaryColor,
|
126
|
+
* shadowColor, label, labelColor, labelSize, and shape..
|
127
|
+
* @param {MarkerIconOptions} [opts]
|
128
|
+
* @return {GIcon}
|
129
|
+
*/
|
130
|
+
MapIconMaker.createFlatIcon = function (opts) {
|
131
|
+
var width = opts.width || 32;
|
132
|
+
var height = opts.height || 32;
|
133
|
+
var primaryColor = opts.primaryColor || "#ff0000";
|
134
|
+
var shadowColor = opts.shadowColor || "#000000";
|
135
|
+
var label = MapIconMaker.escapeUserText_(opts.label) || "";
|
136
|
+
var labelColor = opts.labelColor || "#000000";
|
137
|
+
var labelSize = opts.labelSize || 0;
|
138
|
+
var shape = opts.shape || "circle";
|
139
|
+
var shapeCode = (shape === "circle") ? "it" : "itr";
|
140
|
+
|
141
|
+
var baseUrl = "http://chart.apis.google.com/chart?cht=" + shapeCode;
|
142
|
+
var iconUrl = baseUrl + "&chs=" + width + "x" + height +
|
143
|
+
"&chco=" + primaryColor.replace("#", "") + "," +
|
144
|
+
shadowColor.replace("#", "") + "ff,ffffff01" +
|
145
|
+
"&chl=" + label + "&chx=" + labelColor.replace("#", "") +
|
146
|
+
"," + labelSize;
|
147
|
+
var icon = new GIcon(G_DEFAULT_ICON);
|
148
|
+
icon.image = iconUrl + "&chf=bg,s,00000000" + "&ext=.png";
|
149
|
+
icon.iconSize = new GSize(width, height);
|
150
|
+
icon.shadowSize = new GSize(0, 0);
|
151
|
+
icon.iconAnchor = new GPoint(width / 2, height / 2);
|
152
|
+
icon.infoWindowAnchor = new GPoint(width / 2, height / 2);
|
153
|
+
icon.printImage = iconUrl + "&chof=gif";
|
154
|
+
icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";
|
155
|
+
icon.transparent = iconUrl + "&chf=a,s,ffffff01&ext=.png";
|
156
|
+
icon.imageMap = [];
|
157
|
+
if (shapeCode === "itr") {
|
158
|
+
icon.imageMap = [0, 0, width, 0, width, height, 0, height];
|
159
|
+
} else {
|
160
|
+
var polyNumSides = 8;
|
161
|
+
var polySideLength = 360 / polyNumSides;
|
162
|
+
var polyRadius = Math.min(width, height) / 2;
|
163
|
+
for (var a = 0; a < (polyNumSides + 1); a++) {
|
164
|
+
var aRad = polySideLength * a * (Math.PI / 180);
|
165
|
+
var pixelX = polyRadius + polyRadius * Math.cos(aRad);
|
166
|
+
var pixelY = polyRadius + polyRadius * Math.sin(aRad);
|
167
|
+
icon.imageMap.push(parseInt(pixelX), parseInt(pixelY));
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
return icon;
|
172
|
+
};
|
173
|
+
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Creates a labeled marker icon based on the specified options in the
|
177
|
+
* {@link MarkerIconOptions} argument.
|
178
|
+
* Supported options are: primaryColor, strokeColor,
|
179
|
+
* starPrimaryColor, starStrokeColor, label, labelColor, and addStar.
|
180
|
+
* @param {MarkerIconOptions} [opts]
|
181
|
+
* @return {GIcon}
|
182
|
+
*/
|
183
|
+
MapIconMaker.createLabeledMarkerIcon = function (opts) {
|
184
|
+
var primaryColor = opts.primaryColor || "#DA7187";
|
185
|
+
var strokeColor = opts.strokeColor || "#000000";
|
186
|
+
var starPrimaryColor = opts.starPrimaryColor || "#FFFF00";
|
187
|
+
var starStrokeColor = opts.starStrokeColor || "#0000FF";
|
188
|
+
var label = MapIconMaker.escapeUserText_(opts.label) || "";
|
189
|
+
var labelColor = opts.labelColor || "#000000";
|
190
|
+
var addStar = opts.addStar || false;
|
191
|
+
|
192
|
+
var pinProgram = (addStar) ? "pin_star" : "pin";
|
193
|
+
var baseUrl = "http://chart.apis.google.com/chart?cht=d&chdp=mapsapi&chl=";
|
194
|
+
var iconUrl = baseUrl + pinProgram + "'i\\" + "'[" + label +
|
195
|
+
"'-2'f\\" + "hv'a\\]" + "h\\]o\\" +
|
196
|
+
primaryColor.replace("#", "") + "'fC\\" +
|
197
|
+
labelColor.replace("#", "") + "'tC\\" +
|
198
|
+
strokeColor.replace("#", "") + "'eC\\";
|
199
|
+
if (addStar) {
|
200
|
+
iconUrl += starPrimaryColor.replace("#", "") + "'1C\\" +
|
201
|
+
starStrokeColor.replace("#", "") + "'0C\\";
|
202
|
+
}
|
203
|
+
iconUrl += "Lauto'f\\";
|
204
|
+
|
205
|
+
var icon = new GIcon(G_DEFAULT_ICON);
|
206
|
+
icon.image = iconUrl + "&ext=.png";
|
207
|
+
icon.iconSize = (addStar) ? new GSize(23, 39) : new GSize(21, 34);
|
208
|
+
return icon;
|
209
|
+
};
|
210
|
+
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Utility function for doing special chart API escaping first,
|
214
|
+
* and then typical URL escaping. Must be applied to user-supplied text.
|
215
|
+
* @private
|
216
|
+
*/
|
217
|
+
MapIconMaker.escapeUserText_ = function (text) {
|
218
|
+
if (text === undefined) {
|
219
|
+
return null;
|
220
|
+
}
|
221
|
+
text = text.replace(/@/, "@@");
|
222
|
+
text = text.replace(/\\/, "@\\");
|
223
|
+
text = text.replace(/'/, "@'");
|
224
|
+
text = text.replace(/\[/, "@[");
|
225
|
+
text = text.replace(/\]/, "@]");
|
226
|
+
return encodeURIComponent(text);
|
227
|
+
};
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :<%= table_name %> do |t|
|
5
|
+
<% attributes.each do |attribute| -%>
|
6
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
7
|
+
<% end -%>
|
8
|
+
t.decimal :lat, :precision => 9, :scale => 6, :default => 0.0
|
9
|
+
t.decimal :lng, :precision => 9, :scale => 6, :default => 0.0
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :<%= table_name %>, :id
|
14
|
+
|
15
|
+
User.find(:all).each do |user|
|
16
|
+
user.plugins.create(:name => "Map", :position => (user.plugins.maximum(:position) || -1) + 1)
|
17
|
+
end
|
18
|
+
|
19
|
+
page = Page.create(:title => "Map",
|
20
|
+
:link_url => "/map",
|
21
|
+
:menu_match => "^/map.*$",
|
22
|
+
:deletable => false,
|
23
|
+
:position => Page.count)
|
24
|
+
|
25
|
+
RefinerySetting.find_or_set(:default_page_parts, ["Body", "Side Body"]).each do |default_page_part|
|
26
|
+
page.parts.create(:title => default_page_part, :body => nil)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.down
|
32
|
+
UserPlugin.destroy_all({:name => "Map"})
|
33
|
+
|
34
|
+
Page.find_all_by_link_url("/map").each do |page|
|
35
|
+
page.link_url, page.menu_match = nil
|
36
|
+
page.deletable = true
|
37
|
+
page.destroy
|
38
|
+
end
|
39
|
+
Page.destroy_all({:link_url => "/map"})
|
40
|
+
|
41
|
+
drop_table :<%= table_name %>
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/gemspec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.expand_path('../map.rb', __FILE__)
|
3
|
+
version = ::Refinery::Map.version
|
4
|
+
raise "Could not get version so gemspec can not be built" if version.nil?
|
5
|
+
files = Dir.glob("**/*").flatten.reject do |file|
|
6
|
+
file =~ /\.gem(spec)?$/
|
7
|
+
end
|
8
|
+
|
9
|
+
gemspec = <<EOF
|
10
|
+
Gem::Specification.new do |s|
|
11
|
+
s.name = %q{refinerycms-map}
|
12
|
+
s.version = %q{#{version}}
|
13
|
+
s.description = %q{A RefineryCMS plugin that displays an interactive Google map with flaggable locations.}
|
14
|
+
s.date = %q{#{Time.now.strftime('%Y-%m-%d')}}
|
15
|
+
s.summary = %q{Ruby on Rails map engine for RefineryCMS.}
|
16
|
+
s.email = %q{lab@envylabs.com}
|
17
|
+
s.homepage = %q{http://github.com/envylabs/refinerycms-map}
|
18
|
+
s.authors = %w(Envy\\ Labs)
|
19
|
+
s.require_paths = %w(lib)
|
20
|
+
|
21
|
+
s.files = [
|
22
|
+
'#{files.join("',\n '")}'
|
23
|
+
]
|
24
|
+
#{"s.test_files = [
|
25
|
+
'#{Dir.glob("test/**/*.rb").join("',\n '")}'
|
26
|
+
]" if File.directory?("test")}
|
27
|
+
end
|
28
|
+
EOF
|
29
|
+
|
30
|
+
File.open(File.expand_path("../../refinerycms-map.gemspec", __FILE__), 'w').puts(gemspec)
|
data/lib/map.rb
ADDED
data/license.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2005-2010 [Resolve Digital Ltd.](http://www.resolvedigital.co.nz)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/rails/init.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Refinery::Plugin.register do |plugin|
|
2
|
+
plugin.title = "Map"
|
3
|
+
plugin.description = "Provides a Google map with location markers"
|
4
|
+
plugin.version = 1.0
|
5
|
+
plugin.menu_match = /(admin|refinery)\/map(_locations)?$/
|
6
|
+
plugin.url = '/refinery/map'
|
7
|
+
plugin.activity = {
|
8
|
+
:class => MapLocation,
|
9
|
+
:title => 'title',
|
10
|
+
:url_prefix => 'edit'
|
11
|
+
}
|
12
|
+
plugin.directory = directory
|
13
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Refinery CMS Map Plugin
|
2
|
+
|
3
|
+
## About
|
4
|
+
|
5
|
+
__This plugin adds a Google map with any number of flagged locations.__
|
6
|
+
|
7
|
+
Key features:
|
8
|
+
|
9
|
+
* Admin interface allows you to set the locations that will be displayed on the map.
|
10
|
+
* Clicking a location on the map shows address, phone number, and url for that location.
|
11
|
+
|
12
|
+
## How do I use it?
|
13
|
+
|
14
|
+
To install the map plugin, you can either include the gem or install as a plugin.
|
15
|
+
|
16
|
+
## Requirements
|
17
|
+
|
18
|
+
[RefineryCMS](http://refinerycms.com) version 0.9.7 or later.
|
19
|
+
|
20
|
+
### Gem Installation using Bundler
|
21
|
+
|
22
|
+
Include the latest [gem](http://rubygems.org/gems/refinerycms-map) into your Refinery CMS application's Gemfile:
|
23
|
+
|
24
|
+
gem "refinerycms-map", '~> 0.0.1', :require => "map"
|
25
|
+
|
26
|
+
Then type the following at command line inside your Refinery CMS application's root directory:
|
27
|
+
|
28
|
+
bundle install
|
29
|
+
script/generate map
|
30
|
+
rake db:migrate
|
31
|
+
|
32
|
+
### Rails Engine Installation
|
33
|
+
|
34
|
+
If you do not want to install the engine via bundler then you can install it as an engine inside your application's vendor directory.
|
35
|
+
Type the following at command line inside your Refinery CMS application's root directory:
|
36
|
+
|
37
|
+
script/plugin install git://github.com/envylabs/refinerycms-map.git
|
38
|
+
script/generate map
|
39
|
+
rake db:migrate
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: refinerycms-map
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Envy Labs
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-29 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: A RefineryCMS plugin that displays an interactive Google map with flaggable locations.
|
23
|
+
email: lab@envylabs.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- app/controllers/admin/map_locations_controller.rb
|
32
|
+
- app/controllers/map_locations_controller.rb
|
33
|
+
- app/models/map_location.rb
|
34
|
+
- app/views/admin/map_locations/_form.html.erb
|
35
|
+
- app/views/admin/map_locations/_map_location.html.erb
|
36
|
+
- app/views/admin/map_locations/edit.html.erb
|
37
|
+
- app/views/admin/map_locations/index.html.erb
|
38
|
+
- app/views/admin/map_locations/new.html.erb
|
39
|
+
- app/views/map_locations/index.html.erb
|
40
|
+
- app/views/map_locations/show.html.erb
|
41
|
+
- config/locales/en.yml
|
42
|
+
- config/routes.rb
|
43
|
+
- generators/map/map_generator.rb
|
44
|
+
- generators/map/templates/jquery.jmapping.min.js
|
45
|
+
- generators/map/templates/jquery.metadata.js
|
46
|
+
- generators/map/templates/mapiconmaker.js
|
47
|
+
- generators/map/templates/migration.rb
|
48
|
+
- lib/gemspec.rb
|
49
|
+
- lib/map.rb
|
50
|
+
- license.md
|
51
|
+
- rails/init.rb
|
52
|
+
- readme.md
|
53
|
+
- test/unit/map_location_test.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/envylabs/refinerycms-map
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.7
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Ruby on Rails map engine for RefineryCMS.
|
88
|
+
test_files:
|
89
|
+
- test/unit/map_location_test.rb
|