Merge pull request #194 from foodcoop-adam/plugin-move

Better support for plugins (engines) + move wiki to plugin
This commit is contained in:
wvengen 2013-11-12 03:46:15 -08:00
commit bb5a67033d
36 changed files with 185 additions and 37 deletions

View File

@ -31,18 +31,20 @@ gem 'client_side_validations'
gem 'client_side_validations-simple_form' gem 'client_side_validations-simple_form'
gem 'inherited_resources' gem 'inherited_resources'
gem 'localize_input', git: "git://github.com/bennibu/localize_input.git" gem 'localize_input', git: "git://github.com/bennibu/localize_input.git"
gem 'wikicloth'
gem 'daemons' gem 'daemons'
gem 'twitter-bootstrap-rails' gem 'twitter-bootstrap-rails'
gem 'simple-navigation' gem 'simple-navigation'
gem 'simple-navigation-bootstrap' gem 'simple-navigation-bootstrap'
gem 'meta_search' gem 'meta_search'
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git' # Use this instead of rubygem
gem 'acts_as_tree' gem 'acts_as_tree'
gem "rails-settings-cached", "0.2.4" gem "rails-settings-cached", "0.2.4"
gem 'resque' gem 'resque'
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git'
gem 'foodsoft_wiki', path: 'lib/foodsoft_wiki'
group :production do group :production do
gem 'exception_notification' gem 'exception_notification'
end end

View File

@ -18,6 +18,14 @@ GIT
acts_as_versioned (0.6.0) acts_as_versioned (0.6.0)
activerecord (>= 3.0.9) activerecord (>= 3.0.9)
PATH
remote: lib/foodsoft_wiki
specs:
foodsoft_wiki (0.0.1)
acts_as_versioned
rails (~> 3.2.15)
wikicloth
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
@ -345,6 +353,7 @@ DEPENDENCIES
exception_notification exception_notification
factory_girl_rails (~> 4.0) factory_girl_rails (~> 4.0)
faker faker
foodsoft_wiki!
haml-rails haml-rails
i18n-js! i18n-js!
i18n-spec i18n-spec
@ -380,4 +389,3 @@ DEPENDENCIES
twitter-bootstrap-rails twitter-bootstrap-rails
uglifier (>= 1.0.3) uglifier (>= 1.0.3)
whenever whenever
wikicloth

View File

@ -48,6 +48,9 @@ class OrdersController < ApplicationController
end end
send_data pdf.to_pdf, filename: pdf.filename, type: 'application/pdf' send_data pdf.to_pdf, filename: pdf.filename, type: 'application/pdf'
end end
format.text do
send_data text_fax_template, filename: @order.name+'.txt', type: 'text/plain'
end
end end
end end
@ -101,12 +104,14 @@ class OrdersController < ApplicationController
rescue => error rescue => error
redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message) redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message)
end end
protected
# Renders the fax-text-file # Renders the fax-text-file
# e.g. for easier use with online-fax-software, which don't accept pdf-files # e.g. for easier use with online-fax-software, which don't accept pdf-files
# TODO move to text template
def text_fax_template def text_fax_template
order = Order.find(params[:id]) supplier = @order.supplier
supplier = order.supplier
contact = FoodsoftConfig[:contact].symbolize_keys contact = FoodsoftConfig[:contact].symbolize_keys
text = I18n.t('orders.fax.heading', :name => FoodsoftConfig[:name]) text = I18n.t('orders.fax.heading', :name => FoodsoftConfig[:name])
text += "\n#{Supplier.human_attribute_name(:customer_number)}: #{supplier.customer_number}" unless supplier.customer_number.blank? text += "\n#{Supplier.human_attribute_name(:customer_number)}: #{supplier.customer_number}" unless supplier.customer_number.blank?
@ -117,15 +122,13 @@ class OrdersController < ApplicationController
text += "****** " + I18n.t('orders.fax.articles') + "\n\n" text += "****** " + I18n.t('orders.fax.articles') + "\n\n"
text += I18n.t('orders.fax.number') + " " + I18n.t('orders.fax.amount') + " " + I18n.t('orders.fax.name') + "\n" text += I18n.t('orders.fax.number') + " " + I18n.t('orders.fax.amount') + " " + I18n.t('orders.fax.name') + "\n"
# now display all ordered articles # now display all ordered articles
order.order_articles.ordered.all(:include => [:article, :article_price]).each do |oa| @order.order_articles.ordered.all(:include => [:article, :article_price]).each do |oa|
number = oa.article.order_number number = oa.article.order_number
(8 - number.size).times { number += " " } (8 - number.size).times { number += " " }
quantity = oa.units_to_order.to_i.to_s quantity = oa.units_to_order.to_i.to_s
quantity = " " + quantity if quantity.size < 2 quantity = " " + quantity if quantity.size < 2
text += "#{number} #{quantity} #{oa.article.name}\n" text += "#{number} #{quantity} #{oa.article.name}\n"
end end
send_data text, text
:type => 'text/plain; charset=utf-8; header=present',
:disposition => "attachment; filename=#{order.name}"
end end
end end

View File

@ -17,7 +17,6 @@ class User < ActiveRecord::Base
has_many :assignments, :dependent => :destroy has_many :assignments, :dependent => :destroy
has_many :tasks, :through => :assignments has_many :tasks, :through => :assignments
has_many :send_messages, :class_name => "Message", :foreign_key => "sender_id" has_many :send_messages, :class_name => "Message", :foreign_key => "sender_id"
has_many :pages, :foreign_key => 'updated_by'
has_many :created_orders, :class_name => 'Order', :foreign_key => 'created_by_user_id', :dependent => :nullify has_many :created_orders, :class_name => 'Order', :foreign_key => 'created_by_user_id', :dependent => :nullify
attr_accessor :password, :settings_attributes attr_accessor :password, :settings_attributes

View File

@ -1,3 +1,3 @@
%tr.edit_inline{:id=> "edit_"+@article.id.to_s} %tr.edit_inline{:id=> "edit_"+@article.id.to_s}
%td{:colspan=>"10"} %td{:colspan=>"10"}
= t('.note', article: h(@article.name), drop_link: link_to(t('.drop'), :controller => 'orders', :action => 'edit', :id => @order)).html_safe = t('.note', article: h(@article.name), drop_link: link_to(t('.drop'), edit_order_path(@order))).html_safe

View File

@ -4,7 +4,7 @@
%li.nav-header= t '.foodcoop' %li.nav-header= t '.foodcoop'
%li= link_to t('.members'), foodcoop_users_path %li= link_to t('.members'), foodcoop_users_path
%li= link_to t('.tasks'), user_tasks_path %li= link_to t('.tasks'), user_tasks_path
%li= link_to t('.write_message'), :controller => "messages", :action => "new" %li= link_to t('.write_message'), new_message_path
- has_ordergroup = !@current_user.ordergroup.nil? - has_ordergroup = !@current_user.ordergroup.nil?
- has_orders_role = @current_user.role_orders? - has_orders_role = @current_user.role_orders?

View File

@ -5,7 +5,7 @@
%h3 %h3
= h(t('.user.title', user: @current_user.nick)) = h(t('.user.title', user: @current_user.nick))
%small= t '.user.since', when: distance_of_time_in_words(Time.now, @current_user.created_on) %small= t '.user.since', when: distance_of_time_in_words(Time.now, @current_user.created_on)
= simple_form_for(@current_user, :url => { :action => 'update_profile'}) do |f| = simple_form_for(@current_user, :url => update_profile_path) do |f|
= render :partial => 'shared/user_form_fields', :locals => {:f => f} = render :partial => 'shared/user_form_fields', :locals => {:f => f}
.form-actions .form-actions
= submit_tag t('ui.save'), class: 'btn' = submit_tag t('ui.save'), class: 'btn'

View File

@ -1,6 +1,6 @@
- title t('.title') - title t('.title')
= t('.body').html_safe = t('.body').html_safe
= simple_form_for User.new, url: {action: 'reset_password'} do |form| = simple_form_for User.new, url: reset_password_path do |form|
= form.input :email = form.input :email
.form-actions .form-actions
= form.submit t('.submit'), class: 'btn' = form.submit t('.submit'), class: 'btn'

View File

@ -1,6 +1,6 @@
- title t('.title') - title t('.title')
= t('.body', user: h(@user.nick)).html_safe = t('.body', user: h(@user.nick)).html_safe
= simple_form_for @user, :url => {:action => 'update_password', :id => @user.id, :token => @user.reset_password_token} do |form| = simple_form_for @user, :url => update_password_path(@user.id, :token => @user.reset_password_token) do |form|
= form.input :password = form.input :password
= form.input :password_confirmation = form.input :password_confirmation
.form-actions .form-actions

View File

@ -50,7 +50,7 @@
%li= order_pdf(@order, :articles, t('.download.article_pdf')) %li= order_pdf(@order, :articles, t('.download.article_pdf'))
%li= order_pdf(@order, :matrix, t('.download.matrix_pdf')) %li= order_pdf(@order, :matrix, t('.download.matrix_pdf'))
%li= order_pdf(@order, :fax, t('.download.fax_pdf')) %li= order_pdf(@order, :fax, t('.download.fax_pdf'))
%li= link_to t('.download.fax_txt'), {action: 'text_fax_template', id: @order }, {title: t('.download.download_file')} %li= link_to t('.download.fax_txt'), order_path(@order, format: :txt), {title: t('.download.download_file')}
%section#articles_table %section#articles_table
= render 'articles', order: @order = render 'articles', order: @order

View File

@ -13,5 +13,5 @@
- @tasks.each do |task| - @tasks.each do |task|
%tr %tr
%td= task.due_date unless task.due_date.nil? %td= task.due_date unless task.due_date.nil?
%td= link_to t('.task_format', name: task.name, duration: task.duration), :controller => "tasks", :action => "show", :id => task %td= link_to t('.task_format', name: task.name, duration: task.duration), task_path(task)
%td= task_assignments task %td= task_assignments task

View File

@ -3,6 +3,11 @@
SimpleNavigation::Configuration.run do |navigation| SimpleNavigation::Configuration.run do |navigation|
# allow engines to add to the menu - https://gist.github.com/mjtko/4873ee0c112b6bd646f8
engines = Rails.application.railties.engines.select { |e| e.respond_to?(:navigation) }
# to include an engine but keep it from modifying the menu:
#engines.reject! { |e| e.instance_of? FoodsoftMyplugin::Engine }
navigation.items do |primary| navigation.items do |primary|
primary.dom_class = 'nav' primary.dom_class = 'nav'
@ -16,11 +21,6 @@ SimpleNavigation::Configuration.run do |navigation|
subnav.item :tasks, I18n.t('navigation.tasks'), tasks_path, id: nil subnav.item :tasks, I18n.t('navigation.tasks'), tasks_path, id: nil
end end
primary.item :wiki, I18n.t('navigation.wiki.title'), '#', id: nil do |subnav|
subnav.item :wiki_home, I18n.t('navigation.wiki.home'), wiki_path, id: nil
subnav.item :all_pages, I18n.t('navigation.wiki.all_pages'), all_pages_path, id: nil
end
primary.item :orders, I18n.t('navigation.orders.title'), '#', id: nil do |subnav| primary.item :orders, I18n.t('navigation.orders.title'), '#', id: nil do |subnav|
subnav.item :ordering, I18n.t('navigation.orders.ordering'), group_orders_path, id: nil subnav.item :ordering, I18n.t('navigation.orders.ordering'), group_orders_path, id: nil
subnav.item :ordering_archive, I18n.t('navigation.orders.archive'), archive_group_orders_path, id: nil subnav.item :ordering_archive, I18n.t('navigation.orders.archive'), archive_group_orders_path, id: nil
@ -47,6 +47,8 @@ SimpleNavigation::Configuration.run do |navigation|
subnav.item :ordergroups, I18n.t('navigation.admin.ordergroups'), admin_ordergroups_path, id: nil subnav.item :ordergroups, I18n.t('navigation.admin.ordergroups'), admin_ordergroups_path, id: nil
subnav.item :workgroups, I18n.t('navigation.admin.workgroups'), admin_workgroups_path, id: nil subnav.item :workgroups, I18n.t('navigation.admin.workgroups'), admin_workgroups_path, id: nil
end end
engines.each { |e| e.navigation(primary, self) }
end end
end end

View File

@ -18,27 +18,20 @@ Foodsoft::Application.routes.draw do
match '/login' => 'sessions#new', :as => 'login' match '/login' => 'sessions#new', :as => 'login'
match '/logout' => 'sessions#destroy', :as => 'logout' match '/logout' => 'sessions#destroy', :as => 'logout'
get '/login/forgot_password' => 'login#forgot_password', as: :forgot_password get '/login/forgot_password' => 'login#forgot_password', as: :forgot_password
get '/login/new_password' => 'login#new_password', as: :new_password post '/login/reset_password' => 'login#reset_password', as: :reset_password
get '/login/new_password' => 'login#new_password', as: :new_password
get '/login/update_password' => 'login#update_password', as: :update_password
match '/login/accept_invitation/:token' => 'login#accept_invitation', as: :accept_invitation match '/login/accept_invitation/:token' => 'login#accept_invitation', as: :accept_invitation
resources :sessions, :only => [:new, :create, :destroy] resources :sessions, :only => [:new, :create, :destroy]
########### User specific ########### User specific
match '/home/profile' => 'home#profile', :as => 'my_profile' match '/home/profile' => 'home#profile', :as => 'my_profile'
put '/home/update_profile' => 'home#update_profile', :as => 'update_profile'
match '/home/ordergroup' => 'home#ordergroup', :as => 'my_ordergroup' match '/home/ordergroup' => 'home#ordergroup', :as => 'my_ordergroup'
match '/home/cancel_membership' => 'home#cancel_membership', :as => 'cancel_membership' match '/home/cancel_membership' => 'home#cancel_membership', :as => 'cancel_membership'
############ Wiki
resources :pages do
get :all, :on => :collection
get :version, :on => :member
get :revert, :on => :member
end
match '/wiki/:permalink' => 'pages#show', :as => 'wiki_page' # , :constraints => {:permalink => /[^\s]+/}
match '/wiki' => 'pages#show', :defaults => {:permalink => 'Home'}, :as => 'wiki'
############ Orders, ordering ############ Orders, ordering
resources :orders do resources :orders do
@ -191,8 +184,5 @@ Foodsoft::Application.routes.draw do
resources :users, :only => [:index] resources :users, :only => [:index]
# TODO: This is very error prone. Better deactivate this catch all route
match ':controller(/:action(/:id))(.:format)'
end # End of /:foodcoop scope end # End of /:foodcoop scope
end end

View File

@ -0,0 +1,24 @@
# This migration comes from foodsoft_wiki_engine (originally 20090325175756)
class CreatePages < ActiveRecord::Migration
def self.up
create_table :pages do |t|
t.string :title
t.text :body
t.string :permalink
t.integer :lock_version, :default => 0
t.integer :updated_by
t.integer :redirect
t.integer :parent_id
t.timestamps
end
add_index :pages, :title
add_index :pages, :permalink
Page.create_versioned_table # Automaticly creates pages_versions table
end
def self.down
drop_table :pages
Page.drop_versioned_table
end
end

View File

@ -0,0 +1,18 @@
FoodsoftWiki
============
This plugin adds wiki pages to foodsoft. A new 'Wiki' menu is added next to
the 'Foodcoops' menu in the navigation bar.
This plugin is enabled by default in foodsoft, so you don't need to do anything
to install it. If you still want to, for example when it has been disabled,
add the following to foodsoft's Gemfile:
```Gemfile
# we use the git version of acts_as_versioned, so this needs to be in foodsoft's Gemfile
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git'
gem 'foodsoft_wiki', path: 'lib/foodsoft_wiki'
```
This plugin is part of the foodsoft package and uses the GPL-3 license (see
foodsoft's LICENSE for the full license text).

View File

@ -0,0 +1,40 @@
#!/usr/bin/env rake
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
begin
require 'rdoc/task'
rescue LoadError
require 'rdoc/rdoc'
require 'rake/rdoctask'
RDoc::Task = Rake::RDocTask
end
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'FoodsoftWiki'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Bundler::GemHelper.install_tasks
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task :default => :test

View File

@ -0,0 +1,15 @@
Rails.application.routes.draw do
scope '/:foodcoop' do
resources :pages do
get :all, :on => :collection
get :version, :on => :member
get :revert, :on => :member
end
match '/wiki/:permalink' => 'pages#show', :as => 'wiki_page' # , :constraints => {:permalink => /[^\s]+/}
match '/wiki' => 'pages#show', :defaults => {:permalink => 'Home'}, :as => 'wiki'
end
end

View File

@ -0,0 +1,24 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "foodsoft_wiki/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "foodsoft_wiki"
s.version = FoodsoftWiki::VERSION
s.authors = ["wvengen"]
s.email = ["dev-foodsoft@willem.engen.nl"]
s.homepage = "https://github.com/foodcoops/foodsoft"
s.summary = "Wiki plugin for foodsoft."
s.description = "Adds a wiki to foodsoft."
s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"]
s.test_files = Dir["test/**/*"]
s.add_dependency "rails", "~> 3.2.15"
s.add_dependency 'wikicloth'
s.add_dependency 'acts_as_versioned' # need git version, make sure that is included in foodsoft's Gemfile
s.add_development_dependency "sqlite3"
end

View File

@ -0,0 +1,6 @@
require 'wikicloth'
require 'acts_as_versioned'
require 'foodsoft_wiki/engine'
module FoodsoftWiki
end

View File

@ -0,0 +1,14 @@
module FoodsoftWiki
class Engine < ::Rails::Engine
def navigation(primary, ctx)
primary.item :wiki, I18n.t('navigation.wiki.title'), '#', id: nil do |subnav|
subnav.item :wiki_home, I18n.t('navigation.wiki.home'), ctx.wiki_path, id: nil
subnav.item :all_pages, I18n.t('navigation.wiki.all_pages'), ctx.all_pages_path, id: nil
end
# move this last added item to just after the foodcoop menu
if i = primary.items.index(primary[:foodcoop])
primary.items.insert(i+1, primary.items.delete_at(-1))
end
end
end
end

View File

@ -0,0 +1,3 @@
module FoodsoftWiki
VERSION = "0.0.1"
end