module ActionControllerAdditions def self.included(controller) controller.class_eval do # override in your controller def page_title nil end # override in your controller def ajaxify_extra_content '' end private def ajaxified? request.xhr? and params[:ajaxified] end def render *args, &block if ajaxified? args = _normalize_args(*args, &block) layout = args[:layout] || current_layout layout = (layout == 'application' or layout == true or layout == false) ? false : layout args[:layout] = layout flashes = {} flash.keys.each do |key| flashes[key] = flash[key] flash[key] = nil end extra_content = ajaxify_extra_content super args # Store current path for redirect url changes. Also used to remove the ajaxify parameter that gets added to some auto generated urls # like e.g. pagination links see (ajaxify.js -> on_ajaxify_success()) # current_url_tag = view_context.content_tag(:span, remove_ajaxify_params(request.fullpath), id: 'ajaxify_location') response_body[0] += view_context.content_tag(:div, current_url_tag + extra_content, id: 'ajaxify_content', style: 'display:none', data: { page_title: page_title, flashes: flashes.to_json } ) response.body = response_body[0] response.headers['Ajaxify-Assets-Digest'] = ajaxify_assets_digest return end super ajaxify_add_meta_tag( ajaxify_assets_digest_meta_tag ) if !request.xhr? # Correcting urls for non history api browsers wont work for post requests so add a meta tag to the response body to communicate this to # the ajaxify javascript ajaxify_add_meta_tag( view_context.tag(:meta, name: 'ajaxify:dont_correct_url', content: 'true') ) if request.post? and not request.xhr? return end def current_layout return @current_layout if @current_layout @current_layout = _layout return @current_layout if @current_layout == false @current_layout = File.basename(@current_layout.identifier).split('.').first unless @current_layout.instance_of? String @current_layout end def redirect_to(options = {}, response_status = {}) request.referer.sub!('#/', '') if request.referer # make redirect to back work for browsers without history api super ajaxify_params = "ajaxified=true&ajaxify_redirect=true" self.location += "#{self.location =~ /\?/ ? '&' : '?'}#{ajaxify_params}" if request.xhr? # to avoid the full layout from being rendered end def ajaxify_redirect_to url render inline: "<%= javascript_tag(\"Ajaxify.load({url: '#{url}'});\") %>", layout: true end def remove_ajaxify_params url url.sub(/\?ajaxified=true&(.*)/, '?\1'). sub(/\?ajaxify_redirect=true&(.*)/, '?\1'). sub(/(&|\?)ajaxified=true/, ''). sub(/(&|\?)ajaxify_redirect=true/, '') end # Meta tag for asset change detection - inspired by wiselinks # def ajaxify_assets_digest_meta_tag view_context.tag(:meta, name: 'ajaxify:assets-digest', content: ajaxify_assets_digest) end def ajaxify_assets_digest digests = Rails.application.config.assets.digests digests ? Digest::MD5.hexdigest(digests.values.join) : '' end def ajaxify_add_meta_tag meta_tag response.body = response_body[0].sub('<head>', "<head>\n #{meta_tag}") end end end end