Tech Tidbits - Ruby, Ruby On Rails, Merb, .Net, Javascript, jQuery, Ajax, CSS...and other random bits and pieces.

Showing posts with label plugin. Show all posts
Showing posts with label plugin. Show all posts

Thursday, May 22, 2008

cache_fu: Conditional action-caching stops after a period of time

http://groups.google.com/group/acts_as_cached/browse_thread/thread/eff6287664362f66

fragment_cache.rb

module ActsAsCached
module FragmentCache
def self.setup!
class << CACHE
include Extensions
end

setup_fragment_cache_cache
setup_rails_for_memcache_fragments
setup_rails_for_action_cache_options
end

# add :ttl option to cache helper and set cache store memcache object
def self.setup_rails_for_memcache_fragments
if ::ActionView.const_defined?(:Template)
# Rails 2.1+
::ActionController::Base.cache_store = CACHE
else
# Rails < svn r8619
::ActionView::Helpers::CacheHelper.class_eval do
def cache(name = {}, options = nil, &block)
@controller.cache_erb_fragment(block, name, options)
end
end
::ActionController::Base.fragment_cache_store = CACHE
end
end

def self.setup_fragment_cache_cache
Object.const_set(:FragmentCacheCache, Class.new { acts_as_cached :store => CACHE })
end

# add :ttl option to caches_action on the per action level by passing in a hash instead of an array
#
# Examples:
# caches_action :index # will use the default ttl from your memcache.yml, or 25 minutes
# caches_action :index => { :ttl => 5.minutes } # cache index action with 5 minute ttl
# caches_action :page, :feed, :index => { :ttl => 2.hours } # cache index action with 2 hours ttl, all others use default
#
def self.setup_rails_for_action_cache_options
::ActionController::Caching::Actions::ActionCacheFilter.class_eval do
# convert all actions into a hash keyed by action named, with a value of a ttl hash (to match other cache APIs)
def initialize(*actions, &block)
if [].respond_to?(:extract_options!)
#edge
@options = actions.extract_options!
@actions = actions.inject(@options.except(:cache_path)) do |hsh, action|
action.is_a?(Hash) ? hsh.merge(action) : hsh.merge(action => { :ttl => nil })
end
@options.slice!(:cache_path)
else
#1.2.5
@actions = actions.inject({}) do |hsh, action|
action.is_a?(Hash) ? hsh.merge(action) : hsh.merge(action => { :ttl => nil })
end
end
end

# override to skip caching/rendering on evaluated if option
def before(controller)
return unless @actions.include?(controller.action_name.intern)

# maintaining edge and 1.2.x compatibility with this branch
# Jan Prill - added && false
#if @options && false
# DSS - removed false - false causing else to always run - this may be
# because Jan was using Rails 1.2...
if @options
action_cache_path = ActionController::Caching::Actions::ActionCachePath.new(controller, path_options_for(controller, @options))
else
action_cache_path = ActionController::Caching::Actions::ActionCachePath.new(controller)
end

# should probably be like ActiveRecord::Validations.evaluate_condition. color me lazy.
if conditional = @actions[controller.action_name.intern][:if]
conditional = conditional.respond_to?(:call) ? conditional.call(controller) : controller.send(conditional)
end
# Jan Prill - causing caching to stop after a period of time?
#@actions.delete(controller.action_name.intern) if conditional == false

# Jan Prill - added if clause
cache = controller.read_fragment(action_cache_path.path) if conditional != false
if cache && (conditional || conditional.nil?)
controller.rendered_action_cache = true
if method(:set_content_type!).arity == 2
set_content_type!(controller, action_cache_path.extension)
else
set_content_type!(action_cache_path)
end
controller.send(:render, :text => cache)
false
else
# 1.2.x compatibility
# Jan Prill added &&
controller.action_cache_path = action_cache_path if (controller.respond_to?(:action_cache_path) && conditional != false)
end
end

# override to pass along the ttl hash
def after(controller)
# Jan Prill - added || controller.action_cache_path.nil?
return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache || controller.action_cache_path.nil?
# 1.2.x compatibility
path = controller.respond_to?(:action_cache_path) ? controller.action_cache_path.path : ActionController::Caching::Actions::ActionCachePath.path_for(controller)
controller.write_fragment(path, controller.response.body, action_ttl(controller))
end

private
def action_ttl(controller)
@actions[controller.action_name.intern]
end
end
end

module Extensions
def read(*args)
return if ActsAsCached.config[:skip_gets]
FragmentCacheCache.cache_store(:get, args.first)
end

def write(name, content, options = {})
ttl = (options.is_a?(Hash) ? options[:ttl] : nil) || ActsAsCached.config[:ttl] || 25.minutes
FragmentCacheCache.cache_store(:set, name, content, ttl)
end
end

module DisabledExtensions
def read(*args) nil end
def write(*args) "" end
end
end
end

Wednesday, January 23, 2008

jQuery: Cookie Plugin

I've become a big fan of jQuery and have contributed two small plugins myself, so when it came time to switch to a library for cookie manipulation with Javascript (time to replace all that nasty inline JS code) my first choice was jQuery.

Not to be disappointed, I found that Klaus Hartl has written a very slim and useful Cookie Plugin for jQuery.

Here's a small page test using the jQuery Cookie plugin:

<html>
<head>
<title>jquery cookie</title>

<script type="text/javascript" src="jquery-1.2.1.min.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>

<script type="text/javascript">

$(function($) {

function displayMessage(msg) {
$('#message').html(msg).css({color: 'green'});
}

displayMessage('jQuery cookie plugin test');

$('#setSessionCookie').click(function() {
$.cookie('test', 'Hmmm, cookie');
displayMessage("Cookie 'test' has been set.");
});

$('#setCookie').click(function() {
$.cookie('test', 'Hmmm, cookie', { expires: 7 });
displayMessage("Cookie 'test' has been set and will expire in 7 days.");
});

$('#getCookie').click(function() {
displayMessage("The value of the cookie named 'test' is: " + $.cookie('test'));
});

$('#deleteCookie').click(function() {
$.cookie('test', null);
displayMessage("Cookie 'test' has been deleted.");
});

$('#testCookiesEnabled').click(function() {
$.cookie('testcookiesenabled', null);
$.cookie('testcookiesenabled', 'enabled');
if ($.cookie('testcookiesenabled')) {
displayMessage("Cookie: "+ $.cookie('testcookiesenabled'));
} else {
displayMessage("Cookies disabled");
$.cookie('testcookiesenabled', null);
}
});

});

</script>

</head>

<body>

<p><span id="message" style="forecolor: red;"></span>

<p><input type="button" id="testCookiesEnabled" value="Cookies enabled?"/></p>

<p><input type="button" id="setSessionCookie" value="Set session cookie"/></p>

<p><input type="button" id="setCookie" value="Set cookie expires in 7 days"/></p>

<p><input type="button" id="getCookie" value="Show cookie value"/></p>

<p><input type="button" id="deleteCookie" value="Delete the cookie"/></p>

</body>
</html>


My jQuery cookie demo using jquery.cookie.js

About Me

My photo
Developer (Ruby on Rails, iOS), musician/composer, Buddhist, HSP, Vegan, Aspie.

Labels