Commits

Michael Granger committed cca3daa

Make subscriptions get nodes that were already published

Comments (0)

Files changed (5)

 	warn ">>> Inversion requires Ruby 1.9.2 or later. <<<" if RUBY_VERSION < '1.9.2'
 
 	# Library version constant
-	VERSION = '0.11.0'
+	VERSION = '0.11.1'
 
 	# Version-control revision constant
 	REVISION = %q$Revision$

lib/inversion/renderstate.rb

 		@destinations       = [ @output ]
 		@tag_data          = [ {} ]
 
-		# Hash of subscribed Nodes, keyed by the subscription key as a Symbol
-		@subscriptions      = Hash.new {|hsh, k| hsh[k] = [] } # Auto-vivify
+		# Hash of subscribed Nodes and published data, keyed by the subscription key
+		# as a Symbol
+		@subscriptions      = Hash.new {|hsh, k| hsh[k] = [] } # Auto-vivify to an Array
+		@published_nodes    = Hash.new {|hsh, k| hsh[k] = [] }
 
 	end
 
 	# Subscribe placeholders for publish/subscribe
 	attr_reader :subscriptions
 
+	# Published nodes, keyed by subscription
+	attr_reader :published_nodes
+
 	# The stack of rendered output destinations, most-recent last.
 	attr_reader :destinations
 
 			# 	[ nodes.length, subscriber, subscriber.class ]
 			subscriber.publish( *nodes )
 		end
+		self.published_nodes[ key ].concat( nodes )
 	end
 	alias_method :publish_nodes, :publish
 
 	### Subscribe the given +node+ to nodes published with the specified +key+.
 	def subscribe( key, node )
 		key = key.to_sym
+		self.log.debug "Adding subscription to %p nodes for %p" % [ key, node ]
 		self.subscriptions[ key ] << node
+		# self.log.debug "  now have subscriptions for: %p" % [ self.subscriptions.keys ]
+		if self.published_nodes.key?( key )
+			self.log.debug "    re-publishing %d %p nodes to late subscriber" %
+				[ self.published_nodes[key].length, key ]
+			node.publish( *self.published_nodes[key] )
+		end
 	end
 
 

lib/inversion/template/publishtag.rb

 		self.log.debug "Publishing %d nodes as %s" % [ self.subnodes.length, self.key ]
 		rendered_nodes = []
 		renderstate.with_destination( rendered_nodes ) do
-			self.render_subnodes( renderstate )
+			sn = self.render_subnodes( renderstate )
+			self.log.debug "  subnodes are: %p" % [ sn ]
+			sn
 		end
 
+		self.log.debug "  rendered nodes are: %p" % [ rendered_nodes ]
 		renderstate.publish( self.key, *rendered_nodes ) unless rendered_nodes.empty?
 
 		return nil

spec/inversion/template/publishtag_spec.rb

 	it "raises a parse error if the body isn't a simple attribute" do
 		expect {
 			Inversion::Template::PublishTag.new( 'a.non-identifier' )
-		}.should raise_exception( Inversion::ParseError, /malformed key/i )
+		}.to raise_exception( Inversion::ParseError, /malformed key/i )
 	end
 
 

spec/inversion/template/subscribetag_spec.rb

 	it "raises a parse error if the key isn't a simple attribute" do
 		expect {
 			Inversion::Template::SubscribeTag.new( 'a.non-identifier' )
-		}.should raise_exception( Inversion::ParseError, /malformed subscribe/i )
+		}.to raise_exception( Inversion::ParseError, /malformed subscribe/i )
 	end
 
 	it "renders the nodes published by an immediate subtemplate with the same key" do
 		template.render.should == '--a style--(subtemplate)'
 	end
 
+	it "renders nodes published by an immediate subtemplate that's rendered before it" do
+		template = Inversion::Template.new( '--<?attr subtemplate ?>--<?subscribe stylesheets ?>' )
+		subtemplate = Inversion::Template.new( '<?publish stylesheets ?>a style<?end?>(subtemplate)' )
+
+		template.subtemplate = subtemplate
+
+		template.render.should == '--(subtemplate)--a style'
+	end
+
 	it "doesn't render anything if there are no publications with its key" do
 		template = Inversion::Template.new( '--<?subscribe nostylesheets ?>--<?attr subtemplate ?>' )
 		subtemplate = Inversion::Template.new( '<?publish stylesheets ?>a style<?end?>(subtemplate)' )