Making the template
Base image
I
drew the frame base in Paint Shop Pro and used its "Export Slices"
function to cut image to 9 pieces. Each piece has its own image file. Filenames are formed with pattern red_portlet_[y coordinate]x[x coordinate].jpg.
Images are located under
"red_portlet" folder in my skin folder. It's better to make a dedicated folder
for a sliced image, since if there exists even few sliced images your skin folder, the folder listing will be polluted hindering navigation when working with skins.
The color of empty page area is gray. The portlet has dark red header and pure white content area. Drop shadow was added to make the portlet look like it's floating above the page area.

TAL template
The following macro defines the template which will be filled with portlet content. In my skin, the portlet template filename is portlet_slot.pt.
TAL page template language has a template mechanism for defining places where calling macros can fill content. metal:define-slot sets the place folder for incoming content. The caller of a template can fill these places with metal:fill-slot call.
The
portlet header is placed to cell 1x2 (top center). 1x2 image must be so
tall that even if portlet header contains more than one row it doesn't
break image layout. Use metal:fill-slot="portlet-header" to place
header.
The portlet content is placed into cell 2x2. The background is filled with solid white color, though texture pattern could be used. Use metal:fill-slot="portlet-body" to place portlet content.
Note that screen readers, utilities for visually challenged
people, treat <table> tags as content elements. Instead of a
<table>, nested <div> layout should be used to render
visuals so that text-to-speech software handle the content propeply. I used <table> as an example because table cell concept is easier to grasp than
nested divs with CSS tricks. For example about how to use nested
divs and background images, see this article.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
i18n:domain="plone">
<body>
<div metal:define-macro="portlet">
<table class="portlet-frame">
<tr>
<td class="portlet-top-left"/>
<td class="portlet-top">
<div class="portletHeader" metal:define-slot="portlet-header">
Portlet name
</div>
</td>
<td class="portlet-top-right"/>
</tr>
<tr>
<td class="portlet-left"/>
<td class="portlet-center">
<div class="portletBody" metal:define-slot="portlet-body">
Portlet body
</div>
</td>
<td class="portlet-right"/>
</tr>
<tr class="portlet-frame-bottom-row">
<td class="portlet-bottom-left"/>
<td class="portlet-bottom"/>
<td class="portlet-bottom-right"/>
</tr>
</table>
</div>
</body>
</html>
CSS code
We define the CSS code for portlet frame in separated file. In my skin, it's called portlet_slot.css.dtml.
This
is not pure CSS, but it has mixed in DTML mark-up which allows using
variables in CSS. Plone defines variables like emptySpaceColor and
background color in file called base_properties.prop, which has a syntax similiar to various configuration file formats.
Each
of nine parts of frame image has its own CSS declaration. One need
to be careful with image sizes since left, right and bottom
border width/height definitions must match actual images or there will
be gaps. Use backgrounds colors cleverly so that browsers with images
disabled and still loading pages have proper looks for frames.

/*
*
* Image frame component definitions
*
*/
.portlet-top-left {
padding: 0;
margin: 0;
border: 0;
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_1x1.jpg) top left no-repeat;
}
.portlet-top {
padding: 0;
margin: 0;
border: 0;
padding-top: 20px;
background: &dtml-backgroundColor; url(&dtml-portal_url;/red_portlet/portlet_1x2.jpg) top center repeat-x;
}
.portlet-top-right {
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_1x3.jpg) top right no-repeat;
}
.portlet-left {
padding: 0;
margin: 0;
border: 0;
width: 18px;
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_2x1.jpg) center left repeat-y;
}
.portlet-center {
padding: 0;
margin: 0;
border: 0;
text-align: left;
background: &dtml-globalBackgroundColor;;
}
.portlet-right {
padding: 0;
margin: 0;
border: 0;
width: 17px;
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_2x3.jpg) center right repeat-y;
}
.portlet-bottom-left {
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_3x1.jpg) bottom left no-repeat;
padding: 0;
margin: 0;
border: 0;
}
.portlet-bottom {
padding: 0;
margin: 0;
border: 0;
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_3x2.jpg) bottom center repeat-x;
height: 16px;
}
.portlet-bottom-right {
padding: 0;
margin: 0;
border: 0;
background: &dtml-emptySpaceColor; url(&dtml-portal_url;/red_portlet/portlet_3x3.jpg) bottom right no-repeat;
}
