mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-03-30 20:51:23 -04:00
Merge remote-tracking branch 'upstream/dev' into pr_member_notify
This commit is contained in:
@@ -20,7 +20,7 @@ class PlantingsController < ApplicationController
|
||||
format.json { render json: @plantings }
|
||||
format.rss { render :layout => false } #index.rss.builder
|
||||
format.csv do
|
||||
specifics = (@owner ? "#{@owner.name}-" : @crop ? "#{@crop.name}-" : nil)
|
||||
specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil)
|
||||
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
|
||||
render :csv => @plantings
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
.row
|
||||
.col-md-9
|
||||
|
||||
- if can? :edit, @garden or can? :delete, @garden
|
||||
%p.btn-group
|
||||
- if can? :edit, @garden
|
||||
@@ -28,36 +27,46 @@
|
||||
%div
|
||||
:growstuff_markdown
|
||||
#{strip_tags @garden.description}
|
||||
- unless @garden.description
|
||||
.row-fluid
|
||||
%p No description available yet.
|
||||
|
||||
- if can? :edit, @garden
|
||||
%p
|
||||
Why not
|
||||
= link_to 'tell us more.', edit_garden_path(@garden)
|
||||
|
||||
- if @garden.photos.size > 0 or (can? :edit, @garden and can? :create, Photo)
|
||||
.row
|
||||
%h2 Photos
|
||||
|
||||
%ul.thumbnails
|
||||
- @garden.photos.each do |p|
|
||||
.col-md-2.six-across
|
||||
= render :partial => 'photos/thumbnail', :locals => { :photo => p }
|
||||
.row-fluid
|
||||
%h3 Photos
|
||||
%p= pluralize(@garden.photos.length, "photo")
|
||||
.row-fluid
|
||||
%ul.thumbnails
|
||||
- @garden.photos.each do |p|
|
||||
.col-md-2.six-across
|
||||
= render :partial => 'photos/thumbnail', :locals => { :photo => p }
|
||||
.row-fluid
|
||||
- if can? :create, Photo and can? :edit, @garden
|
||||
.col-md-2
|
||||
.thumbnail(style='height: 220px')
|
||||
%p{:style => 'text-align: center; padding-top: 50px'}
|
||||
= link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary'
|
||||
%p
|
||||
= link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary'
|
||||
|
||||
%h3 What's planted here?
|
||||
- if @garden.plantings.current.size > 0
|
||||
.row
|
||||
.row-fluid
|
||||
%h3 What's planted here?
|
||||
- if @garden.plantings.current.size > 0
|
||||
- @garden.plantings.current.each.with_index do |planting_current, index_current|
|
||||
= render partial: "plantings/thumbnail", locals: {:planting => planting_current}
|
||||
- else
|
||||
%p
|
||||
Nothing is currently planted here.
|
||||
- else
|
||||
%p
|
||||
Nothing is currently planted here.
|
||||
|
||||
%h3 Previously planted in this garden
|
||||
- if @garden.plantings.finished.size > 0
|
||||
.row
|
||||
.row-fluid
|
||||
%h3 Previously planted in this garden
|
||||
- if @garden.plantings.finished.size > 0
|
||||
- @garden.plantings.finished.each.with_index do |planting_finished|
|
||||
= render partial: "plantings/thumbnail", locals: {:planting => planting_finished}
|
||||
|
||||
- else
|
||||
%p
|
||||
Nothing has been planted here.
|
||||
.col-md-3
|
||||
%h4 About this garden
|
||||
%p
|
||||
|
||||
@@ -7,31 +7,42 @@
|
||||
- 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
|
||||
%li.navbar-right
|
||||
= link_to new_garden_path, class: 'btn' do
|
||||
Add New Garden
|
||||
.tab-content{style: "padding-top: 1em"}
|
||||
- first_garden = true
|
||||
- member.gardens.each do |g|
|
||||
|
||||
%div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"}
|
||||
- first_garden = false
|
||||
|
||||
%div
|
||||
.container
|
||||
:growstuff_markdown
|
||||
#{ strip_tags g.description }
|
||||
- unless g.description
|
||||
.row
|
||||
%p No description available yet.
|
||||
|
||||
- if can? :edit, g
|
||||
%p
|
||||
Why not
|
||||
= link_to 'tell us more.', edit_garden_path(g)
|
||||
|
||||
|
||||
- if g.photos.size > 0 or (can? :edit, g and can? :create, Photo)
|
||||
.row
|
||||
%h2 Photos
|
||||
|
||||
%ul.thumbnails
|
||||
- g.photos.each do |p|
|
||||
.col-md-2.six-across
|
||||
= render :partial => 'photos/thumbnail', :locals => { :photo => p }
|
||||
- if can? :create, Photo and can? :edit, g
|
||||
.col-md-2
|
||||
.thumbnail(style='height: 220px')
|
||||
%p{:style => 'text-align: center; padding-top: 50px'}
|
||||
= link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary'
|
||||
%h3 Photos
|
||||
%p= pluralize(g.photos.length, "photo")
|
||||
.row
|
||||
%ul.thumbnails
|
||||
- g.photos.each do |p|
|
||||
.col-md-2.six-across
|
||||
= render :partial => 'photos/thumbnail', :locals => { :photo => p }
|
||||
.row
|
||||
- if can? :create, Photo and can? :edit, g
|
||||
%p
|
||||
= link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary'
|
||||
|
||||
%h3 What's planted here?
|
||||
.row
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
= link_to |
|
||||
image_tag( |
|
||||
avatar_uri(member, 150), |
|
||||
:alt => member.login_name, |
|
||||
:class => 'img-responsive member-image' |
|
||||
), |
|
||||
member, |
|
||||
:rel => "popover", |
|
||||
'data-trigger' => 'hover', |
|
||||
'data-title' => member.login_name, |
|
||||
'data-content' => "#{ render :partial => 'members/popover', :locals => { :member => member } }", |
|
||||
'data-html' => true
|
||||
@@ -1,15 +0,0 @@
|
||||
%small
|
||||
%p
|
||||
- if member.location
|
||||
%i
|
||||
= member.location
|
||||
%p
|
||||
Joined
|
||||
= distance_of_time_in_words(member.created_at, Time.zone.now)
|
||||
ago.
|
||||
%p
|
||||
= pluralize(member.gardens.size, "garden")
|
||||
%br/
|
||||
= pluralize(member.plantings.size, "planting")
|
||||
%br/
|
||||
= pluralize(member.seeds.size, "seed")
|
||||
@@ -1,16 +1,24 @@
|
||||
- cache member do
|
||||
.member-thumbnail.panel
|
||||
%div
|
||||
= render :partial => "members/image_with_popover", :locals => { :member => member }
|
||||
= render :partial => "members/avatar", :locals => { :member => member }
|
||||
%div
|
||||
%p
|
||||
%p.login-name
|
||||
= link_to member.login_name, member
|
||||
- if ! member.location.blank?
|
||||
- if !member.location.blank?
|
||||
%small
|
||||
%br/
|
||||
%i= member.location
|
||||
- if ! member.plantings.empty?
|
||||
- if !member.plantings.empty?
|
||||
%small
|
||||
%br/
|
||||
Recently planted:
|
||||
!= member.plantings.first(3).map{|p| link_to p.crop_name, p }.join(", ")
|
||||
%p
|
||||
%small
|
||||
Joined
|
||||
= distance_of_time_in_words(member.created_at, Time.zone.now)
|
||||
ago.
|
||||
%p
|
||||
%small
|
||||
= [pluralize(member.gardens.size, "garden"), pluralize(member.plantings.size, "planting"), pluralize(member.seeds.size, "seed")].join(", ")
|
||||
|
||||
@@ -5,3 +5,5 @@ to format your text.
|
||||
For instance, *italic*, **bold**, or a link [like this](http://to.some.site.com/).
|
||||
%br/
|
||||
Quick crop links: [sweet potato](crop).
|
||||
%br/
|
||||
Quick member links: @Username or [Username](member).
|
||||
|
||||
@@ -2,7 +2,10 @@ require 'bluecloth'
|
||||
|
||||
module Haml::Filters
|
||||
module GrowstuffMarkdown
|
||||
CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/
|
||||
CROP_REGEX = /(?<!\\)\[([^\[\]]+?)\]\(crop\)/
|
||||
MEMBER_REGEX = /(?<!\\)\[([^\[\]]+?)\]\(member\)/
|
||||
MEMBER_AT_REGEX = /(?<!\\)(\@\w+)/
|
||||
MEMBER_ESCAPE_AT_REGEX = /(?<!\\)\\(?=\@\w+)/
|
||||
include Haml::Filters::Base
|
||||
|
||||
def render(text)
|
||||
@@ -20,6 +23,34 @@ module Haml::Filters
|
||||
end
|
||||
end
|
||||
|
||||
# turn [jane](member) into [jane](http://growstuff.org/members/jane)
|
||||
expanded = expanded.gsub(MEMBER_REGEX) do |m|
|
||||
member_str = $1
|
||||
# find member case-insensitively
|
||||
member = Member.where('lower(login_name) = ?', member_str.downcase).first
|
||||
if member
|
||||
url = Rails.application.routes.url_helpers.member_url(member, :only_path => true)
|
||||
"[#{member_str}](#{url})"
|
||||
else
|
||||
member_str
|
||||
end
|
||||
end
|
||||
|
||||
# turn @jane into [@jane](http://growstuff.org/members/jane)
|
||||
expanded = expanded.gsub(MEMBER_AT_REGEX) do |m|
|
||||
member_str = $1
|
||||
# find member case-insensitively
|
||||
member = Member.where('lower(login_name) = ?', member_str[1..-1].downcase).first
|
||||
if member
|
||||
url = Rails.application.routes.url_helpers.member_url(member, :only_path => true)
|
||||
"[#{member_str}](#{url})"
|
||||
else
|
||||
member_str
|
||||
end
|
||||
end
|
||||
|
||||
expanded = expanded.gsub(MEMBER_ESCAPE_AT_REGEX, "")
|
||||
|
||||
return BlueCloth.new(expanded).to_html
|
||||
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ feature "members list" do
|
||||
expect(page).to have_css "#sort"
|
||||
expect(page).to have_selector "form"
|
||||
click_button('Show')
|
||||
all_links = page.all("#maincontainer p")
|
||||
all_links = page.all("#maincontainer p.login-name")
|
||||
expect(all_links.first).to have_text member1.login_name
|
||||
expect(all_links.last).to have_text member2.login_name
|
||||
end
|
||||
@@ -22,7 +22,7 @@ feature "members list" do
|
||||
expect(page).to have_selector "form"
|
||||
select("recently", :from => 'sort')
|
||||
click_button('Show')
|
||||
all_links = page.all("#maincontainer p")
|
||||
all_links = page.all("#maincontainer p.login-name")
|
||||
expect(all_links.first).to have_text member3.login_name
|
||||
expect(all_links.last).to have_text member1.login_name
|
||||
end
|
||||
|
||||
@@ -15,6 +15,20 @@ def output_link(crop, name=nil)
|
||||
end
|
||||
end
|
||||
|
||||
def input_member_link(name)
|
||||
return "[#{name}](member)"
|
||||
end
|
||||
|
||||
def output_member_link(member, name=nil)
|
||||
url = Rails.application.routes.url_helpers.member_url(member, :only_path => true)
|
||||
if name
|
||||
return "<a href=\"#{url}\">#{name}</a>"
|
||||
else
|
||||
return "<a href=\"#{url}\">#{member.login_name}</a>"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe 'Haml::Filters::Growstuff_Markdown' do
|
||||
it 'is registered as the handler for :growstuff_markdown' do
|
||||
Haml::Filters::defined['growstuff_markdown'].should ==
|
||||
@@ -32,6 +46,12 @@ describe 'Haml::Filters::Growstuff_Markdown' do
|
||||
rendered.should match /not a crop/
|
||||
end
|
||||
|
||||
it "doesn't convert escaped crop links" do
|
||||
@crop = FactoryGirl.create(:crop)
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render( "\\" << input_link(@crop.name))
|
||||
rendered.should match /\[#{@crop.name}\]\(crop\)/
|
||||
end
|
||||
|
||||
it "handles multiple crop links" do
|
||||
tomato = FactoryGirl.create(:tomato)
|
||||
maize = FactoryGirl.create(:maize)
|
||||
@@ -60,4 +80,47 @@ describe 'Haml::Filters::Growstuff_Markdown' do
|
||||
rendered.should match "<a href=\"http://example.com\">test</a>"
|
||||
end
|
||||
|
||||
it 'converts quick member links' do
|
||||
@member = FactoryGirl.create(:member)
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render(input_member_link(@member.login_name))
|
||||
rendered.should match /#{output_member_link(@member)}/
|
||||
end
|
||||
|
||||
it "doesn't convert nonexistent members" do
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render(input_member_link("not a member"))
|
||||
rendered.should match /not a member/
|
||||
end
|
||||
|
||||
it "doesn't convert escaped members" do
|
||||
@member = FactoryGirl.create(:member)
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render("\\" << input_member_link(@member.login_name))
|
||||
rendered.should match /\[#{@member.login_name}\]\(member\)/
|
||||
end
|
||||
|
||||
|
||||
it 'converts @ member links' do
|
||||
@member = FactoryGirl.create(:member)
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render("Hey @#{@member.login_name}! What's up")
|
||||
rendered.should match /#{output_member_link(@member, "@#{@member.login_name}")}/
|
||||
end
|
||||
|
||||
it "doesn't convert invalid @ members" do
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render("@not-a-member")
|
||||
rendered.should match /@not-a-member/
|
||||
end
|
||||
|
||||
it "doesn't convert nonexistent @ members" do
|
||||
@member = FactoryGirl.create(:member)
|
||||
@member_name = @member.login_name
|
||||
@member.destroy
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render("Hey @#{@member_name}")
|
||||
rendered.should match /Hey @#{@member_name}/
|
||||
end
|
||||
|
||||
it "doesn't convert escaped @ members" do
|
||||
@member = FactoryGirl.create(:member)
|
||||
rendered = Haml::Filters::GrowstuffMarkdown.render("Hey \\@#{@member.login_name}! What's up")
|
||||
rendered.should match /Hey @#{@member.login_name}!/
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user