Ruby and XMPP/Jabber Part 3: Adding html to the messages
Posted by Guy Naor Wed, 18 Oct 2006 15:02:00 GMT
If you used a Jabber client like GAIM or Trillian you know that it supports rich text messages. Those can be really nice to send some nicely formatted messages.
But I couldn't find much documentation on how to do it, outside the XEP/JEPs. To save you the pain of reading RFCs and XEPs/JEPs, I'll show you here how to send those nice rich messages.
The rich text is sent as an additional element of the message. The body still remains the same plain text body, and will be displayed by clients that do not support rich-text.
The type of markup that can be used is pretty limited - a small subset of regulat xhtml markup. The full details of the markup and how to use it are given in XEP-0071. But I'll go here over the important details.
To send the message we add a new element of type html with the namespace http://jabber.org/protocol/xhtml-im, and in it we put the html. The html should be the body part only. The following tags are supported: a, br, img, ul, li, ol, p, span. (Technically there are more tags that could match the namespace, but are not recommended.) The markup is styled with CSS using the style attribute of the tag. Supported styles are: background-color, color, font-family, font-size, font-style, font-weight, margin-left, margin-right, text-align, text-decoration.
Lets give it a try in irb (using the same login details from the previous post:
require 'xmpp4r/client'
include Jabber
# Login
jid = JID::new('test@yeush.com/Testing')
password = 'test'
cl = Client::new(jid)
cl.connect
cl.auth(password)
# Create a message
to = "test_with_me@yeush.com"
subject = "XMPP4R Rich-Text Test"
body = "Wow, I can do HTML now. But if you see this, your client doesn't support it"
m = Message::new(to, body).set_type(:normal).set_id('1').set_subject(subject)
# Create the html part
h = REXML::Element::new("html")
h.add_namespace('http://jabber.org/protocol/xhtml-im')
# The body part with the correct namespace
b = REXML::Element::new("body")
b.add_namespace('http://www.w3.org/1999/xhtml')
# The html itself
t = REXML::Text.new( "This is so <strong><span style='background: #003EFF; '><span style='font-size: large; '>COOL!!!</span></span></strong>. I can really do <strong>HTML</strong> now.", false, nil, true, nil, %r/.^/ )
# Add the html text to the body, and the body to the html element
b.add(t)
h.add(b)
# Add the html element to the message
m.add_element(h)
# Send it
cl.send mIt's pretty simple once you understand how to add the element to the message. Nothing fancy going on. And you can use other ways to build the markup. I'm using REXML as it's what XMPP4R considers the native elements. But assigning pre-formatted elements will also work.
Well, go send some nice messages, and come back for the next post about queries and callbacks. This will get us a bit deeper into the protocol, and get us ready for more interesting things.
UPDATE: A short explanation of the last parameter on the REXML::Text.new parameter is in order. As we are passing a pre-formatted text that include characters that are XHTML markup characters, we need to tell REXML to ignore those. We do that by passing a regular expression that will never match anything as the illegal parameter.

















