Search code examples
delphidelphi-xe

Generating dynamic HTML page with UTF8 in Delphi


I'm generating HTML dynamically using Delphi strings (Delphi XE). What is the correct way to encode accentuated characters into my HTML?

var
 s : string;
 myHTML : string;

(...)
s:= 'programação';
 myHTML:= 
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+#10+
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'+#10+
(...)
'<title>OmneeK Server - Intraweb</title>'+#10+
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'+#10+
(...)

myHTML:= myHTML + '<font color="red">' + s + '</font>';

(...)

with the above code I get (from the browser):

"programa��o"

I've tried with HTMLEncode but the result is the same. I'm using ICS components to handle the HTTP requests.


Solution

  • I'm generating a runtime string and returning the string as a response to a HTTP Server component (ICS). Is it possible to apply TEncoding into a string?

    Yes. A Delphi String is a UnicodeString in XE. Delphi has had native support for UTF-8 encoded strings since D2009.

    One thing you can do is simply assign the original UnicodeString to a UTF8String variable and let the RTL encode the Unicode data to UTF-8 for you, then you can send the raw bytes of the UTF8String to the client:

    var 
      myHTML: string;  
      myHTMLUtf8: UTF8String; 
    
    myHTML := ...
    myHTMLUtf8 := myHTML;
    // send myHTMLUtf8 as-is...
    

    Another option is to send the UTF-8 data as a TStream. You can place a UTF8String into a TMemoryStream:

    var 
      myHTML: string;  
      myHTMLUtf8: UTF8String;
      strm: TMemoryStream;
    
    myHTML := ...
    myHTMLUtf8 := myHTML;
    
    strm := TMemoryStream.Create;
    strm.WriteBuffer(PAnsiChar(myHTMLUtf8)^, Length(myHTMLUtf8) * SizeOf(AnsiChar));
    strm.Position := 0;
    // send strm as-is...
    strm.Free;
    

    Or place the original UnicodeString into a TStringStream with TEncoding.UTF8 applied to it:

    var 
      myHTML: string;  
      strm: TStringStream;
    
    myHTML := ...
    
    strm := TStringStream.Create(myHTML, TEncoding.UTF8);
    // send strm as-is...
    strm.Free;