[ANN] tagz-5.0.0

A

ara.t.howard

It might be neat to add some more dynamic method magic for this, like:

foo_in_bar_ { =85 }

I realize that's a bad example in case you really have a tag with =20
that name, but you get the idea.



i actually did that with xx at one point.

i think that, or some proxy object is the way to go.


a @ http://codeforpeople.com/
 
A

Andrew S. Townley

On Mar 25, 2009, at 9:21 AM, James Gray wrote:
=20
=20
=20
=20
i actually did that with xx at one point.
=20
i think that, or some proxy object is the way to go.

I think in order to do namespaces correctly, you'd still need some kind
of registry, and some way to control emitting the namespace declarations
and prefixes at the right time.

There would still be times when you'd want to suppress it (like the
default case), but at the "top" of the relevant element (like the
document's root node), you'd want to be able to have it emit the
declarations.

Of course, (really dreaming now), but it would be _really_cool_ if it
could manage the nested scopes automatically and ensure that you'd spit
out all of the required namespaces used by all of the nested scopes....

I know I'm not making your day here... :)
--=20
Andrew S. Townley <[email protected]>
http://atownley.org
 
A

ara.t.howard

Thanks.

If you had to register the namespaces first in some kind of tagz
registry, maybe you could do something by handling the NameError when
you did:

foo.bar_('bar:foo' => 42)

If it had registered a namespace prefix of foo, then it'd just "do the
right thing", otherwise, you'd get the normal name error. This would
probably be the most logical syntax, but it's way beyond my Ruby
magical
abilities to figure out how to actually make it work.

Still, I think it'd be the most readable of the proposed approaches...
I don't want to have to find unicode characters on my keyboard! :)

Cheers,

how about this


cfp:~ > cat a.rb
require 'rubygems'
require 'tagz'

class Namespace
def initialize &block
@ns = block.call.to_s
@context = block
@self = eval 'self', block
end

instance_methods.each{|m| undef_method if m[%r/__/]}

def method_missing m, *a, &b
if m.to_s[%r/^_|_$/]
@self.send("#{ @ns }:#{ m }", *a, &b)
else
"#{ @ns }:#{ m }"
end
end
end

include Tagz.globally

a = Namespace.new{ :a }
b = Namespace.new{ :b }

xml =
a.root_{
a.foo_(b.bar => 'bar'){ 'content' }
b.bar_(a.foo => 'foo'){ 'content' }
}

puts xml



cfp:~ > ruby a.rb
<a:root><a:foo b:bar="bar">content</a:foo><b:bar a:foo="foo">content</
b:bar></a:root>






a @ http://codeforpeople.com/
 
A

Andrew S. Townley

how about this

I like it, but would change it a bit to allow you to initialize the
namespace URI. Not sure what you'd do with a default namespace
declaration...
cfp:~ > cat a.rb
require 'rubygems'
require 'tagz'

class Namespace
def initialize(nsuri) &block @nsuri = nsuri
@ns = block.call.to_s
@context = block
@self = eval 'self', block
end

instance_methods.each{|m| undef_method if m[%r/__/]}

def method_missing m, *a, &b
if m.to_s[%r/^_|_$/]
@self.send("#{ @ns }:#{ m }", *a, &b)
else
"#{ @ns }:#{ m }"
end
end
end

include Tagz.globally

a = Namespace.new(".."){ :a }
b = Namespace.new(".."){ :b }

xml =
a.root_(emit_nsuri => true, include_children => true) {
a.foo_(b.bar => 'bar'){ 'content' }
b.bar_(a.foo => 'foo'){ 'content' }
}

puts xml



cfp:~ > ruby a.rb
<a:root xmlns:a="..." xmlns:b="..."><a:foo b:bar="bar">content</a:foo><b:bar a:foo="foo">content</
b:bar></a:root>

What do you think?
 
A

Andrew S. Townley

how about this

Apologies. Forgot to say thanks for your help. Your suggestion is
probably good enough for what I need to do, and I can try to manage the
namespace declarations manually somehow, or actually implement part of
what I suggested.

Looking forward to getting started with tagz!

Cheers,

ast
 
A

ara.t.howard

Apologies. Forgot to say thanks for your help. Your suggestion is
probably good enough for what I need to do, and I can try to manage
the
namespace declarations manually somehow, or actually implement part of
what I suggested.

Looking forward to getting started with tagz!

Cheers,

ast

if that's the case i might roll something like that into tagz.

i'll post any other ideas i have here - really appreciate the feedback!

cheers.

a @ http://codeforpeople.com/
 
J

jonty

I have been using haml out of necessity recently (sinatra), erb is too
much like hard work.
I find that haml is deeply frustrating as getting the whitespace right
to nest things properly is, quite frankly, a pain.
Markaby used the right sort of syntax I think and therefore I am
mightily intrigued by Tagz.

Is it fast??

Thankyou Ara - I will try it our tomorrow.
 
A

ara.t.howard

I have been using haml out of necessity recently (sinatra), erb is
too much like hard work.
I find that haml is deeply frustrating as getting the whitespace
right to nest things properly is, quite frankly, a pain.
Markaby used the right sort of syntax I think and therefore I am
mightily intrigued by Tagz.

Is it fast??


it's fairly fast, but not as fast as erb.

it's faster that builder or rexml for xml though.

i actually find mixing erb and tagz is the best approach. my erb
templates are generally < 100 lines and look something like


<title> foobar </title>

<%=

ul_:)class => 'pretty'{
@records.each do |record|
li_{ record.name }
end
}

%>

in erb...


when that gets to ugly i factor or helpers that look like this

def the_list
ul_:)class => 'pretty'{
@records.each do |record|
li_{ record.name }
end
}
end

and then tagz really starts to shine - you can stay in erb for the
designer friendly bits and use straight tagz or factored out tagz for
the logic bits.


cheers.

a @ http://codeforpeople.com/
 
A

Andrew S. Townley

On Mar 26, 2009, at 5:43 AM, Andrew S. Townley wrote:
if that's the case i might roll something like that into tagz.

That would be fantastic.
i'll post any other ideas i have here - really appreciate the feedback!

I'm looking at trying to figure out how to do the emit stuff, and I
think that the Namespace class should certainly be part of Tagz.

New would do something similar to your example, but with also adding the
Namespace URI, e.g. (example from
http://www.w3schools.com/Xforms/xforms_namespace.asp)

include Tagz.globally

xhtml = Tagz::Namespace.new:)xhtml => "http://www.w3.org/1999/xhtml")
xf = Tagz::Namespace.new:)xf => "http://www.w3.org/2002/xforms")

etc.

I tried to do this based on the example you provided, but I'm getting an
error I don't understand. I'm sure it's due to scoping issues, but I've
no idea how to fix it.

I also discovered that output of empty elements doesn't behave as I'd
expect. If you do

empty_element_

you get "<empty_element>"

rather than "<empty_element/>"

I think this can be fixed easily with a check to see if the value of
tagz is empty on line 62.

Any ideas as to what's going on?

excalibur$ cat /tmp/a.rb
require 'rubygems'
require 'tagz'

class Namespace
def initialize hash, &block
@prefix, @uri = hash.inject([]) { |a, (k, v)| a << k << v }
@context = block
@self = eval 'self', block
end

instance_methods.each{|m| undef_method if m[%r/__/]}

def emit_ns
{ "xmlns:#{ @prefix }".to_sym => "#{@uri}" }
end

def method_missing m, *a, &b
if m.to_s[%r/^_|_$/]
@self.send("#{ @prefix }:#{ m }", *a, &b)
else
"#{ @prefix }:#{ m }"
end
end
end

include Tagz.globally

xhtml = Namespace.new:)xhtml => "http://www.w3.org/1999/xhtml")
xf = Namespace.new:)xf => "http://www.w3.org/2002/xforms")

puts xhtml.emit_ns.inspect
puts xf.emit_ns.inspect

# BUG!!
puts empty_element_

doc =
xhtml.html_(xhmtl.emit_ns, xf.emit_ns) {
xhtml.head_{
xhtml.title_ "Important Document"
xf.model_{
xf.instance_{
person_{
fname_
lname_
}
}
}
xf.submission:)id => "form1", :method => "get", :action => "doit.jsp")
}
xhtml.body_{
"..."
}
}
excalibur$ ruby /tmp/a.rb
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml"}
{:"xmlns:xf"=>"http://www.w3.org/2002/xforms"}
<empty_element>
/tmp/a.rb:38: undefined local variable or method `xhmtl' for #<Object:0x7f1e7ce77358 @tagz=nil> (NameError)
 
A

Andrew S. Townley

Apologies for the typo earlier. I think I have it mostly working now,
but it would need a couple of changes in Tagz to do what I want with the
ns declarations and to fix the empty element handling.

Here's the examples:

cat /tmp/a.rb
require 'rubygems'
require 'tagz'

class Namespace
def initialize hash, &block
if hash.is_a? Hash
@prefix, @uri = hash.inject([]) { |a, (k, v)| a << k << v }
else
@prefix = nil
@uri = hash
end
@context = block
@self = eval 'super()', block
end

instance_methods.each{|m| undef_method if m[%r/__/]}

def emit_ns
if [email protected]?
return { "xmlns:#{ @prefix }".to_sym => @uri }
else
return { :xmlns => @uri }
end
end

def method_missing m, *a, &b
if m.to_s[%r/^_|_$/] && [email protected]?
@self.send("#{ @prefix }:#{ m }", *a, &b)
else
if @prefix.nil?
"#{ super }"
else
"#{ @prefix }:#{ m }"
end
end
end

end

include Tagz.globally

xhtml = Namespace.new:)xhtml => "http://www.w3.org/1999/xhtml")
xf = Namespace.new:)xf => "http://www.w3.org/2002/xforms")
default = Namespace.new("http://www.w3.org/1999/xhtml")

puts xhtml.emit_ns.inspect
puts xf.emit_ns.inspect
puts default.emit_ns.inspect

xml =
default.html_(default.emit_ns) {
a_ "link", :href => "uri"
}

puts "\nDefault namespace example"
puts xml
puts


# BUG!!
puts empty_element_


xml =
xhtml.html_{
xhtml.foo_(xhtml.bar => 'bar') { 'content' }
xf.bar_(xf.foo => 'foo') { 'content' }
}

puts
puts xml

nsdecls = xhtml.emit_ns.merge xf.emit_ns
puts nsdecls.inspect

a = Namespace.new:)a => "uri_a")
simple =
doc =
# want to do this:
# xhtml.html_(xhtml.emit_ns, xf.emit_ns) {
xhtml.html_(nsdecls) {
xhtml.head_{
xhtml.title_ "Important Document"
xf.model_{
xf.instance_{
person_{
fname_
lname_
}
}
}
xf.submission:)id => "form1", :method => "get", :action =>
"doit.jsp")
}
xhtml.body_{
"..."
}
}

puts "\nXForms example"
puts doc



excalibur$ ruby /tmp/a.rb
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml"}
{:"xmlns:xf"=>"http://www.w3.org/2002/xforms"}
{:xmlns=>"http://www.w3.org/1999/xhtml"}

Default namespace example
<html xmlns="http://www.w3.org/1999/xhtml"><a href="uri">link</a></html>

<empty_element>

<xhtml:html><xhtml:foo xhtml:bar="bar">content</xhtml:foo><xf:bar
xf:foo="foo">content</xf:bar></xhtml:html>
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml", :"xmlns:xf"=>"http://www.w3.org/2002/xforms"}

XForms example
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"><xhtml:head><xhtml:title>Important Document</xhtml:title><xf:model><xf:instance><person><fname><lname></person></xf:instance></xf:model></xhtml:head><xhtml:body>...</xhtml:body></xhtml:html>
 
A

ara.t.howard

I also discovered that output of empty elements doesn't behave as I'd
expect. If you do

empty_element_

you get "<empty_element>"

rather than "<empty_element/>"

this by design.

it's a false assumption that one never needs to separate opening and
ending tags wrt to scopes

(from the samples)


<========< samples/d.rb >========>

~ > cat samples/d.rb

#
# tagz.rb doesn't cramp your style, allowing even invalid html to
be
# generated. note the use of the 'tagz' method, which can be
used both to
# capture output and to append content to the top of the stack.
#

require 'tagz'
include Tagz.globally

def header
tagz{
html_
body_:)class => 'ninja-like', :id => 'giraffe-slayer')

___ "<!-- this is the header -->"

div_:)class => 'content')
}
end

def footer
tagz{
___ "<!-- this is the footer -->"

_div
_body
_html
}
end

puts header, footer

~ > ruby samples/d.rb

<html><body class="ninja-like" id="giraffe-slayer">
<!-- this is the header -->
<div class="content">

<!-- this is the footer -->
</div></body></html>






however, one can use a bang to indicate a tag should be close even if
it has not content

cfp:~/src/ruby/tagz/tagz-5.1.0 > ruby -r tagz -e 'puts
Tagz{ element_! }'
<element/>


alternatively you can pass an empty block, which is the style i prefer

cfp:~/src/ruby/tagz/tagz-5.1.0 > ruby -r tagz -e 'puts
Tagz{ element_{} }'
<element/>



i'll look into your namespace stuff.


cheers.




a @ http://codeforpeople.com/
 
A

Andrew S. Townley

this by design.

Fair enough.
it's a false assumption that one never needs to separate opening and
ending tags wrt to scopes

It wasn't an assumption I was making. The assumption I *was* making was
that the library was biased to ensuring you had well-formed & correct
mark-up. To me, I'd see the need to separate scopes to be something I'd
want to explicitly request rather than the other way around.

Not a big deal now that I know about the bang operator.

Cheers,

ast
 
J

jonty

Have tried it out this morning - I am delighted with it - natural ruby
style, fast (see
http://blog.zenspider.com/2009/02/tagz-vs-markabybuilderhamlerub.html )

Is there a forum / user group or anything for it? I spotted one or two
issues I'd like to discuss somewhere
is this list the best place?

Getting it to work with Sinatra was interesting - I had to setup ruby
methods as views, because it is not yet incorporated
as a templating engine by Sinatra, but that works fine. Any plans to
fit it into Sinatra like the other templating engines?

But many thanks Ara.
 
A

ara.t.howard

It wasn't an assumption I was making. The assumption I *was* making
was
that the library was biased to ensuring you had well-formed & correct
mark-up. To me, I'd see the need to separate scopes to be something
I'd
want to explicitly request rather than the other way around.

there is actually one other important usecase br_ etc, and other
html4 tags. just fyi.

a @ http://codeforpeople.com/
 
A

Andrew S. Townley

there is actually one other important usecase br_ etc, and other
html4 tags. just fyi.

Who uses HTML4 anymore???? ;)

..maybe an XML vs. HTML mode to switch them?

but I take your point.
 
A

Andrew S. Townley

Who uses HTML4 anymore???? ;)


Actually, there are enough reasons for sticking with HTML. Especially
interesting is the point how most Browsers consume XHTML, to be found
in [1], section "HTML-compatible XHTML".

Hi Florian,

I hadn't seen this article, but I'm quite familiar with the differences.
Generating (X)HTML with Tagz will be handy, but it isn't my primary
interest.

I want a really slick tool/syntax for generating complex XML documents
using multiple namespaces and processing instructions. I've been doing
this in various ways for several years, and nearly all of them suck --
equally and in different ways.

One of the things I used to sorta like was Jakarta's Element
Construction Set (ECS), but it was more complicated than it needed to
be because of Java's syntax issues. I've also tried custom templates,
various approaches to fragments, various templating languages, etc.,
etc....

Tagz is the first thing I've seen (accidentally, I might add) that
finally allowed me to write quasi-markup in code vs. the other way
around. It's also quite timely, because I once again need to generate a
bunch of XML, but this time I'm using Ruby and it's looking like I'll be
adopting Tagz across the board for what I'm doing.

I'd already started doing embedded mark-up and was thinking about trying
to fold in one of the template engines. Then I saw Ara's announcement
and thought "Hallelujah! At last, a decent syntax for doing this!"

Hopefully, the namespace PI stuff will make it into an official release
at some stage. I can live with the (from an XML perspective) backwards
view of element closure, because I understand where Ara (and probably
most of you) are coming from and what the main interest in a library
like this is.

As sick as it is, thanks to Tagz, I'm actually sorta excited about
writing code to generate XML instead of feeling the usual sense of
tedium, dread and pending frustration.

If I ever meet Ara, I'm buying him a pint! :)

Cheers,

ast
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

[ANN] tagz-4.6.0 1
[ANN] tagz-4.3.0 0
[ANN] tagz-4.2.0 - giraffe slayer 9
[PATCH] tagz-5.0.0 -- processing instruction support 1
[ANN] tagz-1.0.0 0
tagz and entities 3
[ANN] xx-2.1.0 2
[ANN] fattr-5.0.0 0

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top