Merge pull request #453 from Growstuff/dev

Production push: planting reminders, crop details, harvest photos, finished plantings, etc
This commit is contained in:
Skud
2014-11-19 16:53:55 +11:00
155 changed files with 2526 additions and 994 deletions

View File

@@ -1 +1 @@
2.1.1
2.1.2

View File

@@ -4,7 +4,7 @@ language: ruby
env: GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
bundler_args: --without development production staging
rvm:
- 2.1.1
- 2.1.2
before_script:
- psql -c 'create database growstuff_test;' -U postgres
script:

View File

@@ -45,3 +45,7 @@ submit the change with your pull request.
- Marlena Compton / [Marlena](https://github.com/marlena)
- Elizabeth A. Kari / [catfriend](https://github.com/catfriend)
- Cheri Allen / [cherimarie](https://github.com/cherimarie)
- Maki Sugita / [macckii](https:://github.com/macckii)
- Shiho Takagi / [oshiho3](https://github.com/oshiho3)
- Emma Winston / [emmawinston](https://github.com/emmawinston)
- Kevin Rio / [krio](https://github.com/krio)

13
Gemfile
View File

@@ -1,6 +1,6 @@
source 'https://rubygems.org'
ruby "2.1.1"
ruby "2.1.2"
gem 'bundler', '>=1.1.5'
@@ -78,11 +78,11 @@ gem 'flickraw'
# Use unicorn as the app server
# gem 'unicorn'
# To use debugger
group :development do
# Installation of the debugger gem fails on Travis CI,
# so we don't use it in the test environment
gem 'debugger'
# A debugger and irb alternative. Pry doesn't play nice
# with unicorn, so start a Webrick server when debugging
# with Pry
gem 'pry'
gem 'better_errors'
gem 'binding_of_caller'
gem 'letter_opener'
@@ -119,6 +119,7 @@ gem 'omniauth-flickr', '>= 0.0.15'
gem 'rake', '>= 10.0.0'
group :development, :test do
gem 'byebug' # debugging
gem 'haml-rails' # HTML templating language
gem 'rspec-rails', '~> 2.12.1' # unit testing framework
gem 'database_cleaner', '~> 1.3.0'
@@ -126,5 +127,7 @@ group :development, :test do
gem 'factory_girl_rails', '~> 4.0' # for creating test data
gem 'coveralls', require: false # coverage analysis
gem 'capybara' # integration tests
gem 'capybara-email' # integration tests for email
gem 'poltergeist', '~> 1.5.1' # for headless JS testing
gem 'i18n-tasks' # adds tests for finding missing and unused translations
end

View File

@@ -49,7 +49,7 @@ GEM
multi_json (~> 1.0)
addressable (2.3.6)
arel (3.0.3)
bcrypt (3.1.7)
bcrypt (3.1.9)
better_errors (2.0.0)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
@@ -60,14 +60,21 @@ GEM
bootstrap-datepicker-rails (1.3.0.2)
railties (>= 3.0)
builder (3.0.4)
byebug (3.5.1)
columnize (~> 0.8)
debugger-linecache (~> 1.2)
slop (~> 3.6)
cancan (1.6.10)
capybara (2.4.1)
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
chunky_png (1.3.1)
capybara-email (2.4.0)
capybara (~> 2.4)
mail
chunky_png (1.3.3)
cliver (0.3.2)
coderay (1.1.0)
coffee-rails (3.2.2)
@@ -91,17 +98,12 @@ GEM
simplecov (>= 0.7)
term-ansicolor
thor
csv_shaper (1.0.0)
csv_shaper (1.1.1)
activesupport (>= 3.0.0)
dalli (2.7.2)
database_cleaner (1.3.0)
debug_inspector (0.0.2)
debugger (1.6.8)
columnize (>= 0.3.1)
debugger-linecache (~> 1.2.0)
debugger-ruby_core_source (~> 1.3.5)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.3.5)
devise (3.2.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -110,21 +112,24 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.1.3)
docile (1.1.5)
easy_translate (0.5.0)
json
thread
thread_safe
erubis (2.7.0)
execjs (2.2.1)
factory_girl (4.4.0)
execjs (2.2.2)
factory_girl (4.5.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.4.1)
factory_girl (~> 4.4.0)
factory_girl_rails (4.5.0)
factory_girl (~> 4.5.0)
railties (>= 3.0.0)
figaro (0.7.0)
bundler (~> 1.0)
rails (>= 3, < 5)
figaro (1.0.0)
thor (~> 0.14)
flickraw (0.9.8)
friendly_id (4.0.10.1)
activerecord (>= 3.0, < 4.0)
fssm (0.2.10)
gibbon (1.1.3)
gibbon (1.1.4)
httparty
multi_json (>= 1.3.4)
gravatar-ultimate (2.0.0)
@@ -138,13 +143,23 @@ GEM
haml (>= 3.1, < 4.1)
railties (>= 3.1, < 4.1)
hashie (3.3.1)
highline (1.6.21)
hike (1.2.3)
httparty (0.11.0)
multi_json (~> 1.0)
multi_xml (>= 0.5.2)
i18n (0.6.1)
i18n-tasks (0.7.8)
activesupport
easy_translate (>= 0.5.0)
erubis
highline
i18n
slop (>= 3.5.0)
term-ansicolor
terminal-table
journey (1.0.4)
jquery-rails (3.1.1)
jquery-rails (3.1.2)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (4.1.2)
@@ -154,11 +169,11 @@ GEM
sprockets-rails
json (1.7.7)
kgio (2.9.2)
launchy (2.4.2)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-markercluster-rails (0.7.0)
railties (>= 3.1)
leaflet-rails (0.7.3)
leaflet-rails (0.7.4)
less (2.5.1)
commonjs (~> 0.2.7)
less-rails (2.5.0)
@@ -173,14 +188,15 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
memcachier (0.0.2)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.6.0)
mini_portile (0.6.1)
multi_json (1.10.1)
multi_xml (0.5.5)
netrc (0.7.7)
newrelic_rpm (3.9.3.241)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
netrc (0.8.0)
newrelic_rpm (3.9.6.257)
nokogiri (1.6.4.1)
mini_portile (~> 0.6.0)
oauth (0.4.7)
omniauth (1.2.2)
hashie (>= 1.2, < 4)
@@ -190,7 +206,7 @@ GEM
omniauth-oauth (1.0.1)
oauth
omniauth (~> 1.0)
omniauth-twitter (1.0.1)
omniauth-twitter (1.1.0)
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
orm_adapter (0.5.0)
@@ -201,6 +217,10 @@ GEM
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
polyglot (0.3.5)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
@@ -216,7 +236,7 @@ GEM
activesupport (= 3.2.13)
bundler (~> 1.0)
railties (= 3.2.13)
rails_12factor (0.0.2)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.2)
@@ -252,12 +272,13 @@ GEM
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
simplecov (0.9.0)
simplecov (0.9.1)
docile (~> 1.1.0)
multi_json
multi_json (~> 1.0)
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
sprockets (2.2.2)
slop (3.6.0)
sprockets (2.2.3)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
@@ -266,17 +287,19 @@ GEM
sprockets (>= 1.0.2)
term-ansicolor (1.3.0)
tins (~> 1.0)
terminal-table (1.4.5)
therubyracer (0.12.1)
libv8 (~> 3.16.14.0)
ref
thor (0.19.1)
thread (0.1.4)
thread_safe (0.3.4)
tilt (1.4.1)
tins (1.3.2)
tins (1.3.3)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.41)
tzinfo (0.3.42)
uglifier (2.2.1)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
@@ -290,7 +313,7 @@ GEM
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
websocket-driver (0.3.4)
websocket-driver (0.4.0)
will_paginate (3.0.7)
xpath (2.0.0)
nokogiri (~> 1.3)
@@ -306,15 +329,16 @@ DEPENDENCIES
bluecloth
bootstrap-datepicker-rails
bundler (>= 1.1.5)
byebug
cancan
capybara
capybara-email
coffee-rails (~> 3.2.1)
compass-rails (~> 1.0.3)
coveralls
csv_shaper
dalli
database_cleaner (~> 1.3.0)
debugger
devise (~> 3.2.0)
factory_girl_rails (~> 4.0)
figaro
@@ -325,6 +349,7 @@ DEPENDENCIES
gravatar-ultimate
haml
haml-rails
i18n-tasks
jquery-rails
jquery-ui-rails
js-routes
@@ -343,6 +368,7 @@ DEPENDENCIES
omniauth-twitter
pg
poltergeist (~> 1.5.1)
pry
rack (~> 1.4.5)
rails (= 3.2.13)
rails_12factor

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,38 @@
# Displays datepicker to finished at date
# when marking a planting finished using a
# button. The button must have class 'append-date'.
jQuery ->
el = $('.append-date')
el.datepicker({'format': 'yyyy-mm-dd'})
href = el.attr('href')
originalText = el.text()
el.click (e) ->
e.stopPropagation()
e.preventDefault()
$(this).text('Confirm without date')
$(this).bind('click.confirm', (e) ->
link = $("<a href='#{href}' data-method='put'></a>")
$('body').append(link)
$(link).click()
)
$(this).blur (e) ->
$(this).text(originalText)
$(this).unbind('click.confirm')
el.one 'changeDate', ->
date = $(this).datepicker('getDate')
url = "#{href}&planting[finished_at]=#{date}"
link = $("<a href='#{url}' data-method='put'></a>")
$('body').append(link)
$(link).click()

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,19 @@
# Clears the finished at date field when
# a planting is marked unfinished, and
# repopulates the field with a cached value
# marking unfinished is undone.
jQuery ->
previousValue = ''
$('#planting_finished').on('click', ->
finished = $('#planting_finished_at')
if @checked
if previousValue.length
date = previousValue
finished.val(date)
else
finished.trigger('focus')
else
previousValue = finished.val()
finished.val('')
)

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,28 @@
if (document.getElementById("membermap") !== null) {
mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
mapbox_base_url = "https://c.tiles.mapbox.com/v3/" + mapbox_map_id + "/{z}/{x}/{y}.png";
L.Icon.Default.imagePath = '/assets'
$.getJSON(location.pathname + '.json', function(member) {
if (member.latitude && member.longitude) {
membermap = L.map('membermap').setView([member.latitude, member.longitude], 4);
L.tileLayer(mapbox_base_url, {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors under <a href="http://www.openstreetmap.org/copyright">ODbL</a> | Map imagery &copy; <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18
}).addTo(membermap);
marker = new L.Marker(new L.LatLng(member.latitude, member.longitude));
member_url = "/members/" + member.slug;
member_link = "<a href='" + member_url + "'>" + member.login_name + "</a>";
where = "<p><i>" + member.location + "</i></p>";
marker.bindPopup(member_link + where).openPopup();
marker.addTo(membermap);
}
});
}

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -36,6 +36,17 @@ h2 {
font-size: 150%;
}
/*
#subtitle {
color: lighten(@brown, 30%);
margin-top: 0px;
padding-top: 0px;
padding-left: 1em;
font-style: italic;
font-weight: normal;
}
*/
h3 {
font-size: 120%;
}
@@ -98,6 +109,10 @@ p.stats {
height: 500px;
}
#membermap {
height: 250px;
}
.member-location {
font-size: small;
font-style: italic;

View File

@@ -0,0 +1,90 @@
class AlternateNamesController < ApplicationController
load_and_authorize_resource
# GET /alternate_names
# GET /alternate_names.json
def index
@alternate_names = AlternateName.all
respond_to do |format|
format.html # index.html.haml
format.json { render json: @alternate_names }
end
end
# GET /alternate_names/1
# GET /alternate_names/1.json
def show
@alternate_name = AlternateName.find(params[:id])
respond_to do |format|
format.html # show.html.haml
format.json { render json: @alternate_name }
end
end
# GET /alternate_names/new
# GET /alternate_names/new.json
def new
@alternate_name = AlternateName.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
respond_to do |format|
format.html # new.html.haml
format.json { render json: @alternate_name }
end
end
# GET /alternate_names/1/edit
def edit
@alternate_name = AlternateName.find(params[:id])
end
# POST /alternate_names
# POST /alternate_names.json
def create
params[:alternate_name][:creator_id] = current_member.id
@alternate_name = AlternateName.new(params[:alternate_name])
respond_to do |format|
if @alternate_name.save
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully created.' }
format.json { render json: @alternate_name, status: :created, location: @alternate_name }
else
format.html { render action: "new" }
format.json { render json: @alternate_name.errors, status: :unprocessable_entity }
end
end
end
# PUT /alternate_names/1
# PUT /alternate_names/1.json
def update
@alternate_name = AlternateName.find(params[:id])
respond_to do |format|
if @alternate_name.update_attributes(params[:alternate_name])
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @alternate_name.errors, status: :unprocessable_entity }
end
end
end
# DELETE /alternate_names/1
# DELETE /alternate_names/1.json
def destroy
@alternate_name = AlternateName.find(params[:id])
@crop = @alternate_name.crop
@alternate_name.destroy
respond_to do |format|
format.html {
redirect_to @crop, notice: 'Alternate name was successfully deleted.'
}
format.json { head :no_content }
end
end
end

View File

@@ -4,6 +4,7 @@ class ApplicationController < ActionController::Base
include ApplicationHelper
after_filter :store_location
before_filter :set_locale
def store_location
if (request.path != "/members/sign_in" &&
@@ -32,5 +33,14 @@ class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
redirect_to request.referer || root_url, :alert => exception.message
end
def set_locale
I18n.locale = params[:locale] || extract_locale_from_subdomain || I18n.default_locale
end
def extract_locale_from_subdomain
parsed_locale = request.subdomains.first
I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
end
end

View File

@@ -69,6 +69,7 @@ class CropsController < ApplicationController
# GET /crops/1.json
def show
@crop = Crop.includes(:scientific_names, {:plantings => :photos}).find(params[:id])
@posts = @crop.posts.paginate(:page => params[:page])
respond_to do |format|
format.html # show.html.haml

View File

@@ -6,23 +6,21 @@ class HarvestsController < ApplicationController
# GET /harvests.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@harvests = @owner.harvests.includes(:owner, :crop).paginate(:page => params[:page])
@harvests = @owner.harvests.includes(:owner, :crop)
elsif @crop
@harvests = @crop.harvests.includes(:owner, :crop)
else
@harvests = Harvest.includes(:owner, :crop).paginate(:page => params[:page])
@harvests = Harvest.includes(:owner, :crop)
end
respond_to do |format|
format.html # index.html.erb
format.html { @harvests = @harvests.paginate(:page => params[:page]) }
format.json { render json: @harvests }
format.csv do
if @owner
@filename = "Growstuff-#{@owner}-Harvests-#{Time.zone.now.to_s(:number)}.csv"
@harvests = @owner.harvests.includes(:owner, :crop)
else
@filename = "Growstuff-Harvests-#{Time.zone.now.to_s(:number)}.csv"
@harvests = Harvest.includes(:owner, :crop)
end
specifics = (@owner ? "#{@owner.name}-" : @crop ? "#{@crop.name}-" : nil)
@filename = "Growstuff-#{specifics}Harvests-#{Time.zone.now.to_s(:number)}.csv"
render :csv => @harvests
end
end

View File

@@ -10,6 +10,7 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # index.html.haml
format.json { render :json => @members.to_json(:only => [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) }
end
end
@@ -25,6 +26,7 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # show.html.haml
format.json { render :json => @member.to_json(:only => [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) }
format.rss { render(
:layout => false,
:locals => { :member => @member }

View File

@@ -29,7 +29,8 @@ class PhotosController < ApplicationController
# GET /photos/new.json
def new
@photo = Photo.new
@planting_id = params[:planting_id]
@type = params[:type]
@id = params[:id]
page = params[:page] || 1
@@ -63,19 +64,35 @@ class PhotosController < ApplicationController
@photo.owner_id = current_member.id
@photo.set_flickr_metadata
if params[:planting_id]
planting = Planting.find_by_id(params[:planting_id])
if planting
if planting.owner.id == current_member.id
@photo.plantings << planting unless @photo.plantings.include?(planting)
# several models can have photos. we need to know what model and the id
# for the entry to attach the photo to
valid_models = ["planting", "harvest"]
if params[:type]
if valid_models.include?(params[:type])
if params[:id]
item = params[:type].camelcase.constantize.find_by_id(params[:id])
if item
if item.owner.id == current_member.id
# This syntax is weird, so just know that it means this:
# @photo.harvests << item unless @photo.harvests.include?(item)
# but with the correct many-to-many relationship automatically referenced
(@photo.send "#{params[:type]}s") << item unless (@photo.send "#{params[:type]}s").include?(item)
else
flash[:alert] = "You must own both the #{params[:type]} and the photo."
end
else
flash[:alert] = "Couldn't find #{params[:type]} to connect to photo."
end
else
flash[:alert] = "You must own both the planting and the photo."
flash[:alert] = "Missing id parameter"
end
else
flash[:alert] = "Couldn't find planting to connect to photo."
flash[:alert] = "Cannot attach photos to #{params[:type]}"
end
else
flash[:alert] = "Missing type parameter"
end
respond_to do |format|
if @photo.save
format.html { redirect_to @photo, notice: 'Photo was successfully added.' }

View File

@@ -7,24 +7,22 @@ class PlantingsController < ApplicationController
# GET /plantings.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
elsif @crop
@plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
else
@plantings = Planting.includes(:owner, :crop, :garden).paginate(:page => params[:page])
end
respond_to do |format|
format.html # index.html.erb
format.html { @plantings = @plantings.paginate(:page => params[:page]) }
format.json { render json: @plantings }
format.rss { render :layout => false } #index.rss.builder
format.csv do
if @owner
@filename = "Growstuff-#{@owner}-Plantings-#{Time.zone.now.to_s(:number)}.csv"
@plantings = @owner.plantings.includes(:owner, :crop, :garden)
else
@filename = "Growstuff-Plantings-#{Time.zone.now.to_s(:number)}.csv"
@plantings = Planting.includes(:owner, :crop, :garden)
end
specifics = (@owner ? "#{@owner.name}-" : @crop ? "#{@crop.name}-" : nil)
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
render :csv => @plantings
end
end

View File

@@ -83,7 +83,9 @@ class ScientificNamesController < ApplicationController
@scientific_name.destroy
respond_to do |format|
format.html { redirect_to @crop }
format.html {
redirect_to @crop, notice: 'Scientific name was successfully deleted.'
}
format.json { head :no_content }
end
end

View File

@@ -7,8 +7,11 @@ class SeedsController < ApplicationController
# GET /seeds.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@seeds = @owner.seeds.includes(:owner, :crop).paginate(:page => params[:page])
elsif @crop
@seeds = @crop.seeds.includes(:owner, :crop).paginate(:page => params[:page])
else
@seeds = Seed.includes(:owner, :crop).paginate(:page => params[:page])
end

View File

@@ -1,2 +0,0 @@
module PlantPartsHelper
end

View File

@@ -1,2 +0,0 @@
module SeedsHelper
end

View File

@@ -9,4 +9,17 @@ class Notifier < ActionMailer::Base
mail(:to => @notification.recipient.email,
:subject => @notification.subject)
end
def planting_reminder(member)
@member = member
@plantings = @member.plantings.reorder.last(5)
@harvests = @member.harvests.reorder.last(5)
if @member.send_planting_reminder
mail(:to => @member.email,
:subject => "What have you planted lately?")
end
end
end

View File

@@ -40,6 +40,7 @@ class Ability
can :wrangle, Crop
can :manage, Crop
can :manage, ScientificName
can :manage, AlternateName
end
# can create & destroy their own authentications against other sites.

View File

@@ -0,0 +1,5 @@
class AlternateName < ActiveRecord::Base
attr_accessible :crop_id, :name, :creator_id
belongs_to :crop
belongs_to :creator, :class_name => 'Member'
end

View File

@@ -8,6 +8,7 @@ class Crop < ActiveRecord::Base
:allow_destroy => true,
:reject_if => :all_blank
has_many :alternate_names
has_many :plantings
has_many :photos, :through => :plantings
has_many :seeds
@@ -17,6 +18,9 @@ class Crop < ActiveRecord::Base
belongs_to :parent, :class_name => 'Crop'
has_many :varieties, :class_name => 'Crop', :foreign_key => 'parent_id'
has_and_belongs_to_many :posts
before_destroy {|crop| crop.posts.clear}
default_scope order("lower(name) asc")
scope :recent, reorder("created_at desc")
@@ -30,11 +34,6 @@ class Crop < ActiveRecord::Base
:message => 'is not a valid English Wikipedia URL'
}
def Crop.random
@crop = Crop.offset(rand(Crop.count)).first
return @crop
end
def to_s
return name
end
@@ -127,52 +126,55 @@ class Crop < ActiveRecord::Base
# - en_wikipedia_url (required)
# - parent (name, optional)
def Crop.create_from_csv(row, definitely_new=false)
def Crop.create_from_csv(row)
name,scientific_name,en_wikipedia_url,parent = row
@cropbot = Member.find_by_login_name('cropbot')
raise "cropbot account not found: run rake db:seed" unless @cropbot
cropbot = Member.find_by_login_name('cropbot')
raise "cropbot account not found: run rake db:seed" unless cropbot
crop = Crop.find_or_create_by_name(name)
crop.update_attributes(
:en_wikipedia_url => en_wikipedia_url,
:creator_id => cropbot.id
)
if definitely_new then
@crop = Crop.create(
:name => name,
:en_wikipedia_url => en_wikipedia_url,
:creator_id => @cropbot.id
)
else
@crop = Crop.find_or_create_by_name(name)
@crop.update_attributes(
:en_wikipedia_url => en_wikipedia_url,
:creator_id => @cropbot.id
)
end
if parent
@parent = Crop.find_by_name(parent)
if @parent
@crop.update_attributes(:parent_id => @parent.id)
parent = Crop.find_by_name(parent)
if parent
crop.update_attributes(:parent_id => parent.id)
else
logger.warn("Warning: parent crop #{parent} not found")
end
end
unless @crop.scientific_names.exists?(:scientific_name => scientific_name)
@sn = ''
if scientific_name
@sn = scientific_name
elsif @crop.parent
@sn = @crop.parent.scientific_names.first.scientific_name
end
crop.add_scientific_name_from_csv(scientific_name)
if @sn
@crop.scientific_names.create(
:scientific_name => @sn,
:creator_id => @cropbot.id
)
else
logger.warn("Warning: no scientific name (not even on parent crop) for #{@crop}")
end
end
def add_scientific_name_from_csv(scientific_name)
name_to_add = nil
if ! scientific_name.blank? # i.e. we actually passed one in, which isn't a given
name_to_add = scientific_name
elsif parent && parent.default_scientific_name
name_to_add = parent.default_scientific_name
else
logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
end
if name_to_add
if scientific_names.exists?(:scientific_name => name_to_add)
logger.warn("Warning: skipping duplicate scientific name #{name_to_add} for #{self}")
else
cropbot = Member.find_by_login_name('cropbot')
raise "cropbot account not found: run rake db:seed" unless cropbot
scientific_names.create(
:scientific_name => name_to_add,
:creator_id => cropbot.id
)
end
end
end
# Crop.search(string)

View File

@@ -1,4 +1,5 @@
class Harvest < ActiveRecord::Base
include ActionView::Helpers::NumberHelper
extend FriendlyId
friendly_id :harvest_slug, use: :slugged
@@ -9,6 +10,17 @@ class Harvest < ActiveRecord::Base
belongs_to :owner, :class_name => 'Member'
belongs_to :plant_part
has_and_belongs_to_many :photos
before_destroy do |harvest|
photolist = harvest.photos.to_a # save a temp copy of the photo list
harvest.photos.clear # clear relationship b/w harvest and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
default_scope order('created_at DESC')
validates :crop, :presence => {:message => "must be present and exist in our database"}
@@ -72,4 +84,41 @@ class Harvest < ActiveRecord::Base
"#{owner.login_name}-#{crop}".downcase.gsub(' ', '-')
end
# stringify as "beet in Skud's backyard" or similar
def to_s
# 50 individual apples, weighing 3lb
# 2 buckets of apricots, weighing 10kg
string = ''
if self.quantity
string += "#{number_to_human(self.quantity.to_s, :strip_insignificant_zeros => true)} "
if self.unit == 'individual'
string += 'individual '
else
if self.quantity == 1
string += "#{self.unit} of "
else
string += "#{self.unit.pluralize} of "
end
end
end
if self.unit != 'individual' # buckets of apricot*s*
string += "#{self.crop.name.pluralize}"
elsif self.quantity == 1
string += "#{self.crop.name}"
else
string += "#{self.crop.name.pluralize}"
end
if self.weight_quantity
string += " weighing #{number_to_human(self.weight_quantity, :strip_insignificant_zeros => true)} #{self.weight_unit}"
end
return string
end
def default_photo
return photos.first
end
end

View File

@@ -42,8 +42,13 @@ class Member < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
attr_accessible :login_name, :email, :password, :password_confirmation,
:remember_me, :login, :tos_agreement, :show_email, :newsletter,
:location, :latitude, :longitude, :send_notification_email, :bio
:remember_me, :login,
# terms of service
:tos_agreement,
# profile stuff
:bio, :location, :latitude, :longitude,
# email settings
:show_email, :newsletter, :send_notification_email, :send_planting_reminder
# set up geocoding
geocoded_by :location

View File

@@ -4,10 +4,21 @@ class Photo < ActiveRecord::Base
belongs_to :owner, :class_name => 'Member'
has_and_belongs_to_many :plantings
before_destroy {|photo| photo.plantings.clear}
has_and_belongs_to_many :harvests
before_destroy do |photo|
photo.plantings.clear
photo.harvests.clear
end
default_scope order("created_at desc")
# remove photos that aren't used by anything
def destroy_if_unused
unless plantings.size > 0 or harvests.size > 0
self.destroy
end
end
# This is split into a side-effect free method and a side-effecting method
# for easier stubbing and testing.
def flickr_metadata

View File

@@ -11,7 +11,15 @@ class Planting < ActiveRecord::Base
belongs_to :crop, :counter_cache => true
has_and_belongs_to_many :photos
before_destroy {|planting| planting.photos.clear}
before_destroy do |planting|
photolist = planting.photos.to_a # save a temp copy of the photo list
planting.photos.clear # clear relationship b/w planting and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
default_scope order("created_at desc")
scope :finished, where(:finished => true)
@@ -89,15 +97,15 @@ class Planting < ActiveRecord::Base
# return a list of interesting plantings, for the homepage etc.
# we can't do this via a scope (as far as we know) so sadly we have to
# do it this way.
def Planting.interesting
howmany = 12 # max amount to collect
def Planting.interesting(howmany=12, require_photo=true)
interesting_plantings = Array.new
seen_owners = Hash.new(false) # keep track of which owners we've seen already
Planting.all.each do |p|
break if interesting_plantings.count == howmany # got enough yet?
next unless p.interesting? # skip those that don't have photos
if require_photo
next unless p.photos.present? # skip those without photos, if required
end
next if seen_owners[p.owner] # skip if we already have one from this owner
seen_owners[p.owner] = true # we've seen this owner
interesting_plantings.push(p)

View File

@@ -5,6 +5,9 @@ class Post < ActiveRecord::Base
belongs_to :author, :class_name => 'Member'
belongs_to :forum
has_many :comments, :dependent => :destroy
has_and_belongs_to_many :crops
before_destroy {|post| post.crops.clear}
after_save :update_crops_posts_association
# also has_many notifications, but kinda meaningless to get at them
# from this direction, so we won't set up an association for now.
@@ -39,4 +42,15 @@ class Post < ActiveRecord::Base
end
end
private
def update_crops_posts_association
self.crops.destroy_all
# look for crops mentioned in the post. eg. [tomato](crop)
self.body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |m|
# find crop case-insensitively
crop = Crop.where('lower(name) = ?', $1.downcase).first
# create association
self.crops << crop if crop and not self.crops.include?(crop)
end
end
end

View File

@@ -1,4 +1,4 @@
%h1 Editing account_type
-content_for :title, "Editing account type"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing account_types
- content_for :title, "Listing account types"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New account_type
- content_for :title, "New account type"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Editing account
- content_for :title, "Editing account"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing accounts
- content_for :title, "Listing accounts"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New account
- content_for :title, "New account"
= render 'form'

View File

@@ -0,0 +1,25 @@
= form_for @alternate_name, :html => {:class => 'form-horizontal', :role => "form"} do |f|
- if @alternate_name.errors.any?
#error_explanation
%h2= "#{pluralize(@alternate_name.errors.count, "error")} prohibited this alternate_name from being saved:"
%ul
- @alternate_name.errors.full_messages.each do |msg|
%li= msg
%p
%span.help-block
For detailed crop wrangling guidelines, please consult the
=link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
on the Growstuff wiki.
.form-group
= f.label :crop_id, :class => 'control-label col-md-2'
.col-md-8
= collection_select(:alternate_name, :crop_id, Crop.all, :id, :name, { :selected => @alternate_name.crop_id || @crop.id }, :class => 'form-control')
.form-group
= f.label :name, :class => 'control-label col-md-2'
.col-md-8
= f.text_field :name, :class => 'form-control'
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', :class => 'btn btn-primary'

View File

@@ -0,0 +1,9 @@
- content_for :title, "Edit alternate name"
%p
Added by
= @alternate_name.creator
= distance_of_time_in_words(@alternate_name.created_at, Time.zone.now)
ago.
= render 'form'

View File

@@ -0,0 +1,23 @@
- content_for :title, "Listing alternate names"
- if can? :create, AlternateName
%p= link_to 'New alternate name', new_alternate_name_path, :class => 'btn btn-primary'
%table
%tr
%th Alternate name
%th Crop
%th
%th
- @alternate_names.each do |alternate_name|
%tr
%td= link_to alternate_name.name, alternate_name
%td= alternate_name.crop
%td= link_to 'Show', alternate_name
%td
- if can? :edit, alternate_name
= link_to 'Edit', edit_alternate_name_path(alternate_name), :class => 'btn btn-default btn-xs'
%td
- if can? :destroy, alternate_name
= link_to 'Delete', alternate_name, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

@@ -0,0 +1,3 @@
- content_for :title, "New alternate name"
= render 'form'

View File

@@ -0,0 +1,13 @@
%p#notice= notice
%p
%b Alternate name:
= @alternate_name.name
%p
%b Crop:
= link_to @alternate_name.crop, @alternate_name.crop
- if can? :edit, @alternate_name
= link_to 'Edit', edit_alternate_name_path(@alternate_name), :class => 'btn btn-default btn-xs'
\|
= link_to 'Back', alternate_names_path

View File

@@ -1,4 +1,4 @@
%h1 Linked accounts on other sites
- content_for :title, "Linked accounts on other sites"
- if @authentications
- unless @authentications.empty?

View File

@@ -8,7 +8,9 @@
%li
= link_to "#{seed.owner} will trade #{seed.tradable_to}.", seed_path(seed)
= render :partial => 'members/location', :locals => { :member => seed.owner }
%p
= link_to "View all #{crop.name} seeds", seeds_by_crop_path(crop)
- if current_member
= link_to "List your seeds to trade.", new_seed_path()
= link_to "List achiote seeds to trade", new_seed_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'list your seeds to trade' }

View File

@@ -4,16 +4,18 @@
Nobody has harvested this crop yet.
- else
%ul
- crop.harvests.each do |harvest|
- crop.harvests.take(3).each do |harvest|
%li
= link_to "#{harvest.owner} harvested #{display_quantity(harvest)}.", harvest_path(harvest)
= render :partial => 'members/location', :locals => { :member => harvest.owner }
%small
= distance_of_time_in_words(harvest.created_at, Time.zone.now)
ago.
%p
= link_to "View all #{crop.name} harvests", harvests_by_crop_path(crop)
- if current_member
= link_to "Track your #{crop.name} harvests.", new_harvest_path()
%p
= link_to "Harvest #{crop.name}", new_harvest_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} harvests" }

View File

@@ -0,0 +1,21 @@
%h4 Plantings
- if crop.plantings.empty?
%p
Nobody has planted this crop yet.
- else
%ul
- crop.plantings.take(3).each do |planting|
%li
= link_to "#{planting.owner} planted #{planting.quantity} #{planting.planted_from}.", planting_path(planting)
= render :partial => 'members/location', :locals => { :member => planting.owner }
%small
= distance_of_time_in_words(planting.created_at, Time.zone.now)
ago.
%p
= link_to "View all #{crop.name} plantings", plantings_by_crop_path(crop)
- if current_member
%p
= link_to "Plant #{crop.name}", new_planting_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} plantings" }

View File

@@ -1,18 +1,18 @@
- content_for :title, @crop.name
- content_for :subtitle, @crop.default_scientific_name
- content_for :buttonbar do
- if can? :create, Planting
= link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-default'
- if can? :create, Harvest
= link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-default'
- if can? :create, Seed
= link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-default'
.row
.col-md-9
%p
- if can? :create, Planting
= link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-primary'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'plant this crop' }
- if can? :create, Harvest
= link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-primary'
- if can? :create, Seed
= link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-primary'
= render :partial => 'photos', :locals => { :crop => @crop }
@@ -33,12 +33,18 @@
%div#cropmap
- if @crop.plantings.size > 0
%a{:name => 'posts'}
%div.pagination
= page_entries_info @posts, :model => "posts"
= will_paginate @posts, :params => {:anchor => "posts"}
%h2 All plantings
- unless @posts.empty?
- @posts.each do |post|
= render :partial => "posts/single", :locals => { :post => post, :subject => true }
- @crop.plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :title => 'owner' }
%div.pagination
= page_entries_info @posts, :model => "posts"
= will_paginate @posts, :params => {:anchor => "posts"}
.col-md-3
- if can? :edit, @crop or can? :destroy, @crop
@@ -53,18 +59,33 @@
- if can? :destroy, @crop
= link_to 'Delete crop', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%h4 Scientific names
%ul
- @crop.scientific_names.each do |sn|
%li
= sn.scientific_name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, sn
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
.scientific_names
%h4 Scientific names
%ul
- @crop.scientific_names.each do |sn|
%li
= sn.scientific_name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, sn
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
.alternate_names
%h4 Alternate names
%ul
- @crop.alternate_names.each do |an|
%li
= an.name
- if can? :edit, an
= link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, an
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_alternate_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
= render :partial => 'varieties', :locals => { :crop => @crop }
@@ -76,5 +97,6 @@
%ul
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
= render :partial => 'plantings', :locals => { :crop => @crop }
= render :partial => 'harvests', :locals => { :crop => @crop }
= render :partial => 'find_seeds', :locals => { :crop => @crop }

View File

@@ -11,12 +11,17 @@
.form-group
.col-md-offset-2.col-md-8
= f.check_box :show_email
Show email publicly on your profile page
Show email publicly on your profile page.
.form-group
.col-md-offset-2.col-md-8
= f.check_box :send_notification_email
Receive emailed copies of Inbox notifications.
Receive emailed copies of Inbox notifications (eg. private messages).
.form-group
.col-md-offset-2.col-md-8
= f.check_box :send_planting_reminder
Receive regular reminders to track your planting and harvesting.
.form-group
.col-md-offset-2.col-md-8

View File

@@ -1,3 +1,3 @@
%h1 New garden
- content_for :title, "New garden"
= render 'form'

View File

@@ -1,4 +1,4 @@
- content_for :title, @owner ? "#{@owner}'s harvests" : "Everyone's harvests"
- content_for :title, @owner ? "#{@owner}'s harvests" : @crop ? "Everyone's #{@crop.name} harvests" : "Everyone's harvests"
%p
#{ENV['GROWSTUFF_SITE_NAME']} helps you track what you're
@@ -10,11 +10,11 @@
%p
- if @owner == current_member
= link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary'
= link_to "View everyone's harvests", harvests_path, :class => 'btn'
= link_to "View everyone's harvests", harvests_path, :class => 'btn btn-default'
- else # everyone's harvests
= link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your harvests', harvests_by_owner_path(:owner => current_member.slug), :class => 'btn'
= link_to 'View your harvests', harvests_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'track your harvests' }

View File

@@ -34,3 +34,16 @@
:growstuff_markdown
#{ @harvest.description != "" ? @harvest.description : "No description given." }
- if @harvest.photos.count > 0 or (can? :edit, @harvest and can? :create, Photo)
%h2 Pictures
%ul.thumbnails
- @harvest.photos.each do |p|
.col-md-2.six-across
= render :partial => 'photos/thumbnail', :locals => { :photo => p }
- if can? :create, Photo and can? :edit, @harvest
.col-md-2
.thumbnail(style='height: 220px')
%p{:style => 'text-align: center; padding-top: 50px'}
= link_to "Add photo", new_photo_path(:type => "harvest", :id => @harvest.id), :class => 'btn btn-primary'

View File

@@ -4,19 +4,13 @@
.row
.col-md-8.info
%p
#{ENV['GROWSTUFF_SITE_NAME']} is a community of food gardeners.
We're building an open source platform to help you learn about
growing food, track what you plant and harvest, and swap
seeds and produce with other gardeners near you.
%p= t('.intro', site_name: ENV['GROWSTUFF_SITE_NAME'])
= render :partial => 'stats'
.col-md-4.signup
%p Join now for your free garden journal, seed sharing, forums, and more.
%p= link_to 'Sign up', new_member_registration_path, :class => 'btn btn-primary btn-lg'
%p= t('.perks')
%p= link_to(t('.sign_up'), new_member_registration_path, :class => 'btn btn-primary btn-lg')
%p
%small
Or
= link_to "sign in", new_member_session_path
if you already have an account.
= t('.already_html', sign_in: link_to(t('.sign_in_linktext'), new_member_session_path))

View File

@@ -1,14 +1,14 @@
.row
.col-md-6.hidden-xs
- cache "interesting_crops", :expires_in => 1.day do
%h2 Some of our crops
%h2= t('.our_crops')
- Crop.interesting.each do |c|
.col-md-3{:style => 'margin:0px; padding: 3px'}
= render :partial => 'crops/image_with_popover', :locals => { :crop => c }
.col-md-6
- cache "interesting_plantings" do
%h2 Recently planted
%h2= t('.recently_planted')
= render :partial => 'plantings/list', :locals => { :plantings => Planting.interesting.first(4) }
.row
@@ -16,8 +16,8 @@
- cache "recent_crops" do
%p{ :style => 'margin-top: 11.25px' }
%strong
Recently added crops:
#{t('.recently_added')}:
!= Crop.recent.limit(12).map {|c| link_to(c, c) }.join(", ")
%p.text-right
=link_to "View all crops »", crops_path
=link_to "#{t('.view_all')} »", crops_path

View File

@@ -1,4 +1,4 @@
%h2 Discussion
%h2= t('.discussion')
- cache "recent_posts" do
- posts = Post.limit(6)
@@ -10,9 +10,9 @@
- if forums
%ul.list-inline
%li
%strong Forums:
%strong #{t('.forums')}:
- forums.each do |f|
%li= link_to f.name, f
%p.text-right
= link_to "View all posts »", posts_path
= link_to "#{t('.view_all')} »", posts_path

View File

@@ -1,17 +1,14 @@
%h2 Keep in touch
%h2= t('.keep_in_touch')
%p
=image_tag("twitter_32.png", :alt => '')
Follow
=link_to '@growstufforg', 'http://twitter.com/growstufforg'
on Twitter.
= t('.twitter_html', link: link_to(t('.twitter_linktext'), 'http://twitter.com/growstufforg'))
%p
=image_tag("blog_32.png", :alt => '')
Subscribe to the
=link_to 'Growstuff Blog', 'http://blog.growstuff.org/'
= t('.blog_html', link: link_to(t('.blog_linktext'), 'http://blog.growstuff.org/'))
%p
=image_tag("email_32.png", :alt => '')
Subscribe to our
=link_to 'email newsletter', 'http://blog.growstuff.org/newsletter'
= t('.newsletter_html', link: link_to(t('.newsletter_linktext'), 'http://blog.growstuff.org/newsletter'))

View File

@@ -2,7 +2,7 @@
.hidden-xs
- members = Member.interesting.first(6)
- if members.present?
%h2 Some of our members
%h2= t('.title')
.row
- members.each do |m|
@@ -10,4 +10,4 @@
= render :partial => "members/thumbnail", :locals => { :member => m }
%p.text-right
= link_to "View all members »", members_path
= link_to "#{t('.view_all')} »", members_path

View File

@@ -1,50 +1,29 @@
%h2 Open Source
%h2= t('.open_source_title')
%p
#{ENV['GROWSTUFF_SITE_NAME']} is open source software,
which means that we share this website's code for free with our
community and the world. We believe that openness,
sustainability, and social good go hand in hand. You can read more
about
=link_to "why Growstuff is open source", "http://blog.growstuff.org/2013/02/20/why-growstuff-is-open-source/"
or check out our code on
=succeed '.' do
= link_to 'Github', 'http://github.com/Growstuff/growstuff'
= t('.open_source_body_html', why: link_to(t('.why_linktext'), 'http://blog.growstuff.org/2013/02/20/why-growstuff-is-open-source/'),
github: link_to(t('.github_linktext'), 'http://github.com/Growstuff/growstuff'),
site_name: ENV['GROWSTUFF_SITE_NAME'] )
%h2 Open Data and APIs
%h2= t('.open_data_title')
%p
We're building a database
of crops, planting advice, seed sources, and other information
that anyone can use for free, under a
= succeed '.' do
= link_to 'Creative Commons license', 'http://creativecommons.org/licenses/by-sa/3.0/'
You can use this data for research, to build apps, or for any
purpose at all. Read more about our
= t('.open_data_body_html', creative_commons_link: link_to(t('.creative_commons_linktext'), 'http://creativecommons.org/licenses/by-sa/3.0/'),
wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/index.php/Open_data'),
api_docs_link: link_to(t('.api_docs_linktext'), 'http://wiki.growstuff.org/index.php/API'))
= link_to 'open data', 'http://wiki.growstuff.org/index.php/Open_data'
and
= succeed '.' do
= link_to 'API documentation', 'http://wiki.growstuff.org/index.php/API'
%h2 Get Involved
%h2= t('.get_involved_title')
%p
We believe in collaboration, and work closely with our members
and the wider food-growing community.
Our team includes volunteers from all walks of life
and all skill levels. To get involved, visit
= link_to 'Growstuff Talk', 'http://talk.growstuff.org/'
or find more information on the
= succeed "." do
= link_to 'Growstuff Wiki', 'http://wiki.growstuff.org/'
= t('.get_involved_body_html', talk_link: link_to(t('.talk_linktext'), 'http://talk.growstuff.org/'),
wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/'))
%h2 Support Growstuff
%h2= t('.support_title')
%p
Growstuff is independent,
=succeed "," do
=link_to 'ad-free', 'http://wiki.growstuff.org/index.php/Why_no_ads%3F'
and we have no outside investment. You can support our work by
=succeed "." do
=link_to 'buying a paid account', shop_path
= t('.support_body_html', ad_free: link_to(t('.ad_free_linktext'), 'http://wiki.growstuff.org/index.php/Why_no_ads%3F'),
buy_account: link_to(t('.buy_account_linktext'), shop_path))

View File

@@ -1,18 +1,18 @@
- seeds = Seed.interesting.first(6)
- if seeds.present?
%h2 Seeds available to trade
%h2= t('.title')
- cache "interesting_seeds" do
- if seeds.length > 0
%table.table.table-striped
%tr
%th Owner
%th Crop
%th.hidden-xs.hidden-sm Description
%th Will trade to
%th From location
%th= t('.owner')
%th= t('.crop')
%th.hidden-xs.hidden-sm= t('.description')
%th= t('.trade_to')
%th= t('.from')
%th
- seeds.each do |seed|
@@ -23,8 +23,8 @@
%td= seed.tradable? ? seed.tradable_to : ''
%td
- if seed.tradable?
= seed.owner.location.blank? ? "unspecified" : truncate(seed.owner.location, :length => 25, :separator => ', ')
%td= link_to 'Details', seed, :class => 'btn btn-default btn-xs'
= seed.owner.location.blank? ? t('.unspecified') : truncate(seed.owner.location, :length => 25, :separator => ', ')
%td= link_to t('.details'), seed, :class => 'btn btn-default btn-xs'
%p.text-right
= link_to "View all seeds »", seeds_path
= link_to "#{t('.view_all')} »", seeds_path

View File

@@ -1,10 +1,8 @@
- cache("homepage_stats") do
%p.stats
So far,
= link_to "#{Member.confirmed.count.to_i} members", members_path
have planted
= link_to "#{Crop.count.to_i} crops", crops_path
= link_to "#{Planting.count.to_i} times", plantings_path
in
= succeed "." do
= link_to "#{Garden.count.to_i} gardens", gardens_path
= t('.message_html', { member: link_to(t('.member_linktext', count: Member.confirmed.count.to_i), members_path),
number_crops: link_to(t('.number_crops_linktext', count: Crop.count.to_i), crops_path),
number_plantings: link_to(t('.number_plantings_linktext', count: Planting.count.to_i), plantings_path),
number_gardens: link_to(t('.number_gardens_linktext', count: Garden.count.to_i), gardens_path) })

View File

@@ -1,19 +1,16 @@
.row
.col-md-12
- if member_signed_in?
%h1
Welcome to
= succeed "," do
= ENV['GROWSTUFF_SITE_NAME']
= current_member
%h1= t('.welcome', site_name: ENV['GROWSTUFF_SITE_NAME'], member_name: current_member)
= render :partial => 'stats'
%p
.btn-group
= link_to "Plant", new_planting_path, :class => 'btn btn-default'
= link_to "Harvest", new_harvest_path, :class => 'btn btn-default'
= link_to "Add seeds", new_seed_path, :class => 'btn btn-default'
= link_to "Post", new_post_path, :class => 'btn btn-default'
= link_to "Edit profile", edit_member_registration_path, :class => 'btn btn-default'
= link_to t('.plant'), new_planting_path, :class => 'btn btn-default'
= link_to t('.harvest'), new_harvest_path, :class => 'btn btn-default'
= link_to t('.add_seeds'), new_seed_path, :class => 'btn btn-default'
= link_to t('.post'), new_post_path, :class => 'btn btn-default'
= link_to t('.edit_profile'), edit_member_registration_path, :class => 'btn btn-default'
- else
.hidden-xs

View File

@@ -9,7 +9,15 @@
.row
.col-md-12
- if content_for?(:title)
%h1= yield(:title)
%h1#title
= yield(:title)
- if content_for?(:subtitle)
%small= yield(:subtitle)
- if content_for?(:buttonbar)
%p
.btn-group
= yield(:buttonbar)
- if notice
.alert.alert-success
= notice

View File

@@ -0,0 +1,12 @@
%h3 Account details
%p
%strong Member since:
= member.created_at.to_s(:date)
%p
%strong Account type:
= member.account_type
account

View File

@@ -5,5 +5,5 @@
:size => defined?(size) ? size : 150, |
:default => :identicon }), |
:alt => '', |
:class => 'img-rounded img-responsive' ), |
:class => 'img-rounded img-responsive avatar' ), |
member_path(member)

View File

@@ -0,0 +1,9 @@
%h2 All about #{member.login_name}
- if member.bio.blank?
- if can? :edit, member
= link_to "Add a bio to complete your profile."
- else
#{member.login_name} hasn't written a bio yet.
- else
:growstuff_markdown
#{ strip_tags member.bio }

View File

@@ -0,0 +1,17 @@
- if twitter_auth || flickr_auth || member.show_email
%h4 Contact
- if twitter_auth
%p
= image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo'
=link_to twitter_auth.name, "http://twitter.com/#{twitter_auth.name}"
- if flickr_auth
%p
= image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo'
=link_to flickr_auth.name, "http://flickr.com/photos/#{flickr_auth.uid}"
- if member.show_email
%p
Email:
= mail_to member.email

View File

@@ -0,0 +1,27 @@
%h2 #{member.login_name}'s gardens
.tabbable
%ul.nav.nav-tabs
- first_garden = true
- member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == member
%li= link_to 'New Garden', new_garden_path
.tab-content
- first_garden = true
- member.gardens.each do |g|
%div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"}
- first_garden = false
%div
:growstuff_markdown
#{ strip_tags g.description }
%h3 What's planted here?
- g.featured_plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true }
%p
= link_to "More about this garden...", url_for(g)

View File

@@ -0,0 +1,5 @@
- if member.latitude and member.longitude
%div#membermap
%p
See other members near
= link_to member.location, place_path(member.location)

View File

@@ -0,0 +1,23 @@
%h3 Activity
%ul
%li
- if member.plantings.count > 0
= link_to pluralize(member.plantings.count, "planting"), plantings_by_owner_path(:owner => member)
- else
0 plantings
%li
- if member.harvests.count > 0
= link_to pluralize(member.harvests.count, "harvest"), harvests_by_owner_path(:owner => member)
- else
0 harvests
%li
- if member.seeds.count > 0
= link_to pluralize(member.seeds.count, "seeds"), seeds_by_owner_path(:owner => member)
- else
0 seeds
%li
- if member.posts.count > 0
= link_to pluralize(member.posts.count, "post"), posts_by_author_path(:author => member)
- else
0 posts

View File

@@ -1,105 +1,26 @@
- content_for :title, "#{@member.login_name}"
- content_for :member_rss_login_name, "#{@member.login_name}"
- content_for :member_rss_slug, "#{@member.slug}"
- content_for :title, @member.login_name
- content_for :subtitle, @member.location
- content_for :buttonbar do
- if can? :update, @member
= link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default'
- if @member == current_member && !@member.is_paid?
= link_to "Upgrade account", shop_path, :class => 'btn btn-default'
-if can? :create, Notification and current_member != @member
=link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default'
- content_for :member_rss_login_name, @member.login_name
- content_for :member_rss_slug, @member.slug
.row
.col-md-3
= render :partial => "members/avatar", :locals => { :member => @member }
-if can? :create, Notification and current_member != @member
%p
%br/
=link_to 'Send Message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-primary'
%p
%strong Member since:
= @member.created_at.to_s(:date)
%p
%strong Account type:
= @member.account_type
account
- if @member == current_member && !@member.is_paid?
= link_to "Upgrade", shop_path, :class => 'btn btn-primary btn-xs'
- if @twitter_auth || @flickr_auth || @member.show_email
%h4 Contact
- if @twitter_auth
%p
= image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo'
=link_to @twitter_auth.name, "http://twitter.com/#{@twitter_auth.name}"
- if @flickr_auth
%p
= image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo'
=link_to @flickr_auth.name, "http://flickr.com/photos/#{@flickr_auth.uid}"
- if @member.show_email
%p
Email:
= mail_to @member.email
- if @member.location.to_s != ''
%h4 Location
%p
= link_to image_tag("http://maps.google.com/maps/api/staticmap?size=200x200&maptype=roadmap&sensor=false&markers=color:green|label:A|#{@member.latitude},#{@member.longitude}&zoom=12", :alt => "Map showing #{@member.location}", :width => 200, :height => 200 ), place_path(@member.location)
%br/
= link_to @member.location, place_path(@member.location)
.col-md-9
%p
- if can? :update, @member
%p
= link_to 'Edit your profile', "edit", :class => 'btn btn-primary'
- if @member.bio
%h2 Bio
:growstuff_markdown
#{ strip_tags @member.bio }
%h2 Gardens
.tabbable
%ul.nav.nav-tabs
- first_garden = true
- @member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == @member
%li= link_to 'New Garden', '#garden_new', 'data-toggle' => 'tab'
.tab-content
- first_garden = true
- @member.gardens.each do |g|
%div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"}
- first_garden = false
= render :partial => "map", :locals => { :member => @member }
= render :partial => "bio", :locals => { :member => @member }
= render :partial => "gardens", :locals => { :member => @member }
%div
:growstuff_markdown
#{ strip_tags g.description }
%h3 What's planted here?
- g.featured_plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true }
%p
= link_to "More about this garden...", url_for(g)
- if current_member == @member
%div{:class => 'tab-pane', :id => "garden_new"}
%h3 Create a new garden
= render 'gardens/form'
%h3 Seeds
%p
- if @member.seeds.count > 0
= link_to pluralize(@member.seeds.count, "variety"), seeds_path(:owner_id => @member.id)
- else
No seeds yet.
%h3 Posts
- if @member.posts.count > 0
- @member.posts.each do |post|
= render :partial => "posts/single", :locals => { :post => post, :subject => true }
- else
%p Nothing posted yet.
.col-md-3
= render :partial => "avatar", :locals => { :member => @member }
= render :partial => "account", :locals => { :member => @member }
= render :partial => "stats", :locals => { :member => @member }
= render :partial => "contact", :locals => { :member => @member, :twitter_auth => @twitter_auth, :flickr_auth => @flickr_auth }

View File

@@ -0,0 +1,71 @@
- site_name = ENV['GROWSTUFF_SITE_NAME']
%p Hello #{@member.login_name},
%h2 What's new in your garden?
%p
- if @member.plantings.size == 0
%p
#{site_name} lets you track what food you're growing
in your garden and see what other people near you are planting too.
%p
= link_to "Get started now", new_planting_url
by planting your first crop.
- else
%p
The most recent plantings you've told us about are:
%ul
- @plantings.each do |p|
%li
= link_to p, planting_url(p)
planted
= distance_of_time_in_words(p.created_at, Time.zone.now)
ago.
%p
= link_to "Plant something new", new_planting_url
to keep your garden records up to date.
%h2 Your recent harvests
- if @member.harvests.size == 0
%p
#{site_name} helps you keep track of what you
harvest from your garden. Record what food you've grown
and see what other people near you are harvesting, too.
%p
= link_to "Get started now", new_harvest_url
by tracking your first harvest.
- else
According to our records, the last few things you harvested were:
%ul
- @harvests.each do |h|
%li
= link_to h, harvest_url(h)
harvested
= distance_of_time_in_words(h.created_at, Time.zone.now)
ago.
%p
Harvested anything else lately?
= link_to "Track your harvests here.", new_harvest_url
%h2
See you soon on #{site_name}!
%p
The #{site_name} team.
%br/
=link_to root_url, root_url
%hr/
%p
Don't want to get these emails any more?
= link_to "Turn off these notifications", edit_member_registration_url

View File

@@ -13,8 +13,10 @@
- if @sets and @sets.length > 0
%p
= form_tag(new_photo_path, :method => :get, :class => 'form-inline') do
= label_tag :set, "Choose a photo set:", :class => 'control-label'
= label_tag :set, "Choose a photo album:", :class => 'control-label'
= select_tag :set, options_for_select(@sets, @current_set), :class => 'input-large'
= hidden_field_tag :type, @type
= hidden_field_tag :id, @id
= submit_tag "Search", :class => 'btn btn-primary'
%div.pagination
@@ -25,7 +27,7 @@
- @photos.each do |p|
.col-md-2.six-across
.thumbnail(style='height: 220px')
= link_to image_tag(FlickRaw.url_q(p), :alt => '', :class => 'img-rounded'), photos_path(:photo => { :flickr_photo_id => p.id }, :planting_id => @planting_id), :method => :post
= link_to image_tag(FlickRaw.url_q(p), :alt => '', :class => 'img-rounded'), photos_path(:photo => { :flickr_photo_id => p.id }, :type => @type, :id => @id), :method => :post
%p
=p.title
@@ -34,4 +36,3 @@
You must
=link_to "connect your account to Flickr", '/auth/flickr'
to add photos.

View File

@@ -1,4 +1,4 @@
%h1 Editing plant_part
- content_for :title, "Editing plant part"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 New plant_part
- content_for :title, "New plant part"
= render 'form'

View File

@@ -17,14 +17,6 @@
in
= link_to planting.location, planting.garden
- if planting.finished
%p
Finished:
- if planting.finished_at
= planting.finished_at
- else
Yes (no date specified)
%p
- if planting.quantity
Quantity:
@@ -37,11 +29,19 @@
:growstuff_markdown
#{ planting.description }
- if planting.finished
%p
Finished:
- if planting.finished_at
= planting.finished_at
- else
Yes (no date specified)
- if can? :edit, planting or can? :destroy, planting
%p
- if can? :edit, planting
=link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs'
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
=link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

@@ -1,4 +1,4 @@
- content_for :title, @owner ? "#{@owner}'s plantings" : "Everyone's plantings"
- content_for :title, @owner ? "#{@owner}'s plantings" : @crop ? "Everyone's #{@crop.name} plantings" : "Everyone's plantings"
%p
- if can? :create, Planting
@@ -43,7 +43,7 @@
%td= planting.planted_at
%td
- if planting.finished and planting.finished_at
= planting.planted_at
= planting.finished_at
- elsif planting.finished
Yes (no date specified)
%td= planting.sunniness
@@ -53,7 +53,7 @@
- if can? :edit, planting
=link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs'
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
=link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

@@ -11,14 +11,6 @@
%b Planted:
= @planting.planted_at ? @planting.planted_at : "not specified"
- if @planting.finished
%p
%b Finished:
- if @planting.finished_at
= @planting.finished_at
- else
Yes (no date specified)
%p
%b Where:
=link_to "#{@planting.owner}'s", @planting.owner
@@ -39,15 +31,24 @@
%b Sun or shade?
= @planting.sunniness
- if @planting.finished
%p
%b Finished:
- if @planting.finished_at
= @planting.finished_at
- else
Yes (no date specified)
- if can? :edit, @planting or can? :destroy, @planting
%p
- if can? :edit, @planting
=link_to 'Edit', edit_planting_path(@planting), :class => 'btn btn-default btn-xs'
- if ! @planting.finished
= link_to "Mark as finished", planting_path(@planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs'
- if can? :destroy, @planting
=link_to 'Delete', @planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
- if can? :edit, @planting
=link_to 'Edit', edit_planting_path(@planting), :class => 'btn btn-default btn-xs'
- if ! @planting.finished
= link_to "Mark as finished", planting_path(@planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, @planting
=link_to 'Delete', @planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.col-md-6
= render :partial => "crops/index_card", :locals => { :crop => @planting.crop}
@@ -68,4 +69,4 @@
.col-md-2
.thumbnail(style='height: 220px')
%p{:style => 'text-align: center; padding-top: 50px'}
= link_to "Add photo", new_photo_path(:planting_id => @planting.id), :class => 'btn btn-primary'
= link_to "Add photo", new_photo_path(:type => "planting", :id => @planting.id), :class => 'btn btn-primary'

View File

@@ -1,4 +1,4 @@
%h1 Editing product
- content_for :title, "Editing product"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing products
- content_for :title, "Listing products"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New product
- content_for :title, "New product"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Editing role
- content_for :title, "Editing role"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing roles
- content_for :title, "Listing roles"
- if can? :create, Role
%p= link_to 'New Role', new_role_path, :class => 'btn btn-primary'

View File

@@ -1,4 +1,4 @@
%h1 New role
- content_for :title, "New role"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing scientific_names
- content_for :title, "Listing scientific names"
- if can? :create, ScientificName
%p= link_to 'New Scientific name', new_scientific_name_path, :class => 'btn btn-primary'

View File

@@ -5,7 +5,7 @@
= @scientific_name.scientific_name
%p
%b Crop:
= @scientific_name.crop_id
= link_to @scientific_name.crop, @scientific_name.crop
= link_to 'Edit', edit_scientific_name_path(@scientific_name), :class => 'btn btn-default btn-xs'
\|

View File

@@ -1,4 +1,4 @@
- content_for :title, @owner ? "#{@owner}'s seeds" : "Everyone's seeds"
- content_for :title, @owner ? "#{@owner}'s seeds" : @crop ? "Everyone's #{@crop.name} seeds" : "Everyone's seeds"
%p
#{ENV['GROWSTUFF_SITE_NAME']} helps you track your seed
@@ -10,11 +10,11 @@
%p
- if @owner == current_member
= link_to 'Add seeds', new_seed_path, :class => 'btn btn-primary'
= link_to "View everyone's seeds", seeds_path, :class => 'btn'
= link_to "View everyone's seeds", seeds_path, :class => 'btn btn-default'
- else # everyone's seeds
= link_to 'Add seeds', new_seed_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your seeds', seeds_by_owner_path(:owner => current_member.slug), :class => 'btn'
= link_to 'View your seeds', seeds_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'add seeds to your stash' }

View File

@@ -31,8 +31,12 @@ module Growstuff
config.active_record.default_timezone = :local
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}')]
I18n.default_locale = :en
# rails will fallback to config.i18n.default_locale translation
config.i18n.fallbacks = true
# rails will fallback to en, no matter what is set as config.i18n.default_locale
config.i18n.fallbacks = [:en]
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
@@ -67,8 +71,12 @@ module Growstuff
config.assets.initialize_on_precompile = true
config.generators do |g|
g.template_engine :haml
g.stylesheets false
g.template_engine :haml
g.view_specs false
g.controller_specs false
g.helper false
g.stylesheets false
g.javascripts false
end
config.action_mailer.delivery_method = :sendmail

Some files were not shown because too many files have changed in this diff Show More