Merging with upstream
[shapado:cantonics-shapado.git] / app / helpers / application_helper.rb
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
3   def multiauth_dropdown(title)
4     render 'shared/login_menu', :title => title
5   end
6
7   def with_facebook?
8     return true if current_group.share.fb_active
9
10     if request.host =~ Regexp.new("#{AppConfig.domain}$", Regexp::IGNORECASE)
11       AppConfig.facebook["activate"]
12     else
13       false
14     end
15   end
16
17   def context_panel_ads(group)
18     if AppConfig.enable_adbard && request.domain == AppConfig.domain &&
19         !Adbard.where(:group_id => current_group.id).first
20       adbard = "<!--Ad Bard advertisement snippet, begin -->
21         <script type='text/javascript'>
22         var ab_h = '#{AppConfig.adbard_host_id}';
23         var ab_s = '#{AppConfig.adbard_site_key}';
24         </script>
25         <script type='text/javascript' src='http://cdn1.adbard.net/js/ab1.js'></script>
26         <!--Ad Bard, end -->"
27     else
28       adbard = ""
29     end
30     if group.has_custom_ads == true
31       ads = []
32       Ad.where(:group_id => group.id,:position =>'context_panel').each do |ad|
33         ads << ad.code
34       end
35       ads << adbard
36       return ads.join.html_safe unless ads.empty?
37     end
38   end
39
40   def header_ads(group)
41     if group.has_custom_ads
42       ads = []
43       Ad.where(:group_id => group.id,:position => 'header').each do |ad|
44         ads << ad.code
45       end
46       return ads.join.html_safe  unless ads.empty?
47     end
48   end
49
50   def content_ads(group)
51     if group.has_custom_ads
52       ads = []
53       Ad.where(:group_id => group.id,:position => 'content').each do |ad|
54         ads << ad.code
55       end
56       return ads.join.html_safe  unless ads.empty?
57     end
58   end
59
60   def footer_ads(group)
61     if group.has_custom_ads
62       ads = []
63       Ad.where(:group_id => group.id,:position => 'footer').each do |ad|
64         ads << ad.code
65       end
66       return ads.join.html_safe  unless ads.empty?
67     end
68   end
69
70   def language_desc(langs)
71     (langs.kind_of?(Array) ? langs : [langs]).map do |lang|
72       I18n.t("languages.#{lang}", :default => lang).capitalize
73     end.join(', ')
74   end
75
76   def language_select(f, question, opts = {})
77     selected = if question.new?
78       logged_in? ? current_user.main_language : question.language
79     else
80       question.language
81     end
82     languages = logged_in? ? current_user.preferred_languages : current_group.languages
83
84     f.select :language, languages_options(languages), {:selected => selected}, {:class => "select"}.merge(opts)
85   end
86
87   def language_select_tag(name = "language", value = nil, opts = {})
88     languages = logged_in? ? current_user.preferred_languages : current_group.languages
89     select_tag name, options_for_select(languages_options(languages)), {:value => value, :class => "select"}.merge(opts)
90   end
91
92   def languages_options(languages=nil, current_languages = [])
93     languages = AVAILABLE_LANGUAGES-current_languages if languages.blank?
94     locales_options(languages)
95   end
96
97   def locales_options(languages=nil)
98     languages = AVAILABLE_LOCALES if languages.blank?
99
100     languages.collect do |lang|
101       [language_desc(lang), lang]
102     end
103   end
104
105   def tag_cloud(tags = [], options = {}, limit = nil)
106     if tags.empty?
107       tags = Question.tag_cloud({:group_id => current_group.id, :banned => false}.
108                         merge(language_conditions.merge(language_conditions)), limit)
109     end
110
111     return '' if tags.size <= 2
112
113     # Sizes: xxs xs s l xl xxl
114     css = {1 => "xxs", 2 => "xs", 3 => "s", 4 => "l", 5 => "xl" }
115     max_size = 5
116     min_size = 1
117
118     tag_class = options.delete(:tag_class) || "tag"
119
120     lowest_value = tags.min { |a, b| a["count"].to_i <=> b["count"].to_i }
121     highest_value = tags.max { |a, b| a["count"].to_i <=> b["count"].to_i }
122
123     spread = (highest_value["count"] - lowest_value["count"])
124     spread = 1 if spread == 0
125     ratio = (max_size - min_size) / spread
126
127     render 'shared/tag_cloud', :tags => tags, :css => css,
128                                :lowest_value => lowest_value, :ratio => ratio,
129                                :min_size => min_size, :tag_class => tag_class
130   end
131
132   def country_flag(code, name)
133     if code
134       image_tag("flags/flag_#{code.downcase}.gif", :title => name, :alt => "")
135     end
136   end
137
138   def markdown(txt, options = {})
139     raw = options.delete(:raw)
140     body = render_page_links(txt.to_s, options)
141     txt = if raw
142       (defined?(RDiscount) ? RDiscount.new(body) : Maruku.new(body)).to_html
143     else
144       (defined?(RDiscount) ? RDiscount.new(body, :smart, :strict) : Maruku.new(sanitize(body))).to_html
145     end
146
147     if options[:sanitize] != false
148       txt = defined?(Sanitize) ? Sanitize.clean(txt, SANITIZE_CONFIG) : sanitize(txt)
149     end
150     txt.html_safe
151   end
152
153   def render_page_links(text, options = {})
154     group = options[:group]
155     group = current_group if group.nil?
156     in_controller = respond_to?(:logged_in?)
157
158     text.gsub!(/\[\[([^\,\[\'\"]+)\]\]/) do |m|
159       link = $1.split("|", 2)
160       # FIXME mongoid .only(:title, :slug).where()
161       page = Page.by_title(link.first, :group_id => group.id)
162
163
164       if page.present?
165         %@<a href="/pages/#{page.slug}" class="page_link">#{link[1] || page.title}</a>@
166       else
167         %@<a href="/pages/#{link.first.parameterize.to_s}?create=true&title=#{link.first}" class="missing_page">#{link.last}</a>@
168       end
169     end
170
171     return text if !in_controller
172
173     text.gsub(/%(\S+)%/) do |m|
174       case $1
175         when 'site'
176           group.domain
177         when 'site_name'
178           group.name
179         when 'current_user'
180           if logged_in?
181             link_to(current_user.login, user_path(current_user))
182           else
183             "anonymous"
184           end
185         when 'hottest_today'
186           question = Question.where(:activity_at.gt => Time.zone.now.yesterday, :order => "hotness desc, views_count asc", :group_id => group.id, :select => [:slug, :title]).first
187           if question.present?
188             link_to(question.title, question_path(question))
189           end
190         else
191           m
192       end
193     end
194   end
195
196   def format_number(number)
197     return if number.nil?
198
199     if number < 1000
200       number.to_s
201     elsif number >= 1000 && number < 1000000
202       "%.01fK" % (number/1000.0)
203     elsif number >= 1000000
204       "%.01fM" % (number/1000000.0)
205     end
206   end
207
208   def class_for_number(number)
209     return if number.nil?
210
211     if number >= 1000 && number < 10000
212       "medium_number"
213     elsif number >= 10000
214       "big_number"
215     elsif number < 0
216       "negative_number"
217     end
218   end
219
220   def shapado_auto_link(text, options = {})
221     text = auto_link(text, :all,  { "rel" => 'nofollow', :class => 'auto-link' })
222     if options[:link_users]
223       text = TwitterRenderer.auto_link_usernames_or_lists(text, :username_url_base => "#{users_path}/", :suppress_lists => true)
224     end
225
226     text
227   end
228
229   def require_js(*files)
230     content_for(:js) { javascript_include_tag(*files) }
231   end
232
233   def require_css(*files)
234     content_for(:css) { stylesheet_link_tag(*files) }
235   end
236
237   def render_tag(tag)
238     %@<span class="tag"><a href="#{questions_path(:tags => tag)}">#{@badge.token}</a></span>@
239   end
240
241   def class_for_question(question)
242     klass = ""
243
244     if question.accepted
245       klass << "accepted"
246     elsif !question.answered
247       klass << "unanswered"
248     end
249
250     if logged_in?
251       if current_user.is_preferred_tag?(current_group, *question.tags)
252         klass << " highlight"
253       end
254
255       if current_user == question.user
256         klass << " own_question"
257       end
258     end
259
260     klass
261   end
262
263   def googlean_script(analytics_id, domain)
264     "<script type=\"text/javascript\">
265        var _gaq = _gaq || [];
266        _gaq.push(['_setAccount', '#{analytics_id}']);
267        _gaq.push(['_trackPageview'],['_setDomainName', '#{domain}']);
268
269        (function() {
270          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
271          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
272          (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
273        })();
274     </script>".html_safe
275   end
276
277   def logged_out_language_filter
278     custom_lang = session["user.language_filter"]
279     case custom_lang
280     when "any"
281       languages = "any"
282     else
283       languages = session["user.language_filter"] || I18n.locale.to_s.split('-').first
284     end
285     languages
286   end
287
288   def clean_seo_keywords(tags, text = "")
289     if tags.size < 5
290
291       text.scan(/(\S+)/) do |s|
292         word = s.to_s.downcase
293         if word.length > 3 && !tags.include?(word)
294           tags << word
295         end
296
297         break if tags.size >= 5
298       end
299     end
300
301     tags.join(', ')
302   end
303
304   def current_announcements(hide_time = nil)
305     conditions = {:starts_at.lte => Time.zone.now.to_i,
306                   :ends_at.gte => Time.zone.now.to_i,
307                   :group_id.in => [current_group.id, nil]}
308     if hide_time
309       conditions[:updated_at] = {:$gt => hide_time}
310     end
311
312     if logged_in?
313       conditions[:only_anonymous] = false
314     end
315
316     Announcement.order_by(:starts_at.desc).where(conditions)
317   end
318
319   def top_bar_links
320     top_bar = raw(current_group.custom_html.top_bar)
321     return [] if top_bar.blank?
322
323     top_bar.split("\n").map do |line|
324       render_page_links(line.strip)
325     end
326   end
327
328   def gravatar(*args)
329     super(*args).html_safe
330   end
331
332   def include_latex
333     if current_group.enable_latex
334       require_js domain_url(:custom => current_group.domain)+'/javascripts/jsMath/easy/load.js'
335     end
336   end
337
338   def find_answer(question)
339     if question.accepted
340       question.answer
341     else
342       question.answers.order_by(:votes_average.asc).first
343     end
344   end
345
346   def widget_css(widget)
347     "<style type='text/css'>#{widget.settings["custom_external_css"]}</style>"
348   end
349
350   def widget_code(widget)
351     path = embedded_widget_path(:id => widget.id)
352     url = domain_url(:custom => current_group.domain) + path
353     %@<iframe src="#{url}" height="200px"></iframe>@
354   end
355 end
356