Here is a code sample on how to pull your email off of Gmail.
<cfset javaSystem = createObject("java", "java.lang.System") />
<cfset jProps = javaSystem.getProperties() />
<cfset jProps.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory") />
<cfset jProps.setproperty("mail.pop3.port",995) />
<cfset jProps.setProperty("mail.pop3.socketFactory.port", 995) />
<cfpop action="GETALL" name="getMail" server="pop.gmail.com" username="[yourUserName]" password="[yourPassword]" port="995" maxrows="20" timeout="90">
<cfdump var="#getMail#">
Be sure to enable POP on your gmail account
Fusecast Web Application Development and Web Hosting Services
www.fusecast.com
Thursday, February 26, 2009
Monday, February 23, 2009
I.E. Select Drop Down Cuts Off Using CSS width
The Problem
While setting up an HTML form I ran into an issue where the select box I was using has an option that was really really long. I set the size of the select box to 166px using CSS styles. Except for I.E., Firefox and every other real browser out there handled it just fine. Since the bulk of my users use I.E., I needed to come up with a hack that would not add a lot of code overhead and be maintainable.
Here's what I came up with and it works great!
The Solution
Original Code
Sample
New Code
Sample
Note: If you want to constrict the size the drop down option opens out to, simply change the width parameter in the onFocus from auto to say 300px or something. Play with it. You'll get the idea.
And YES, this hack makes the select box float over your other form widgets and text so it doesn't do strange things with the other form elements.
Have a go at it! It did the trick for me. I hope it works for you too!
While setting up an HTML form I ran into an issue where the select box I was using has an option that was really really long. I set the size of the select box to 166px using CSS styles. Except for I.E., Firefox and every other real browser out there handled it just fine. Since the bulk of my users use I.E., I needed to come up with a hack that would not add a lot of code overhead and be maintainable.
Here's what I came up with and it works great!
The Solution
Original Code
<form name="test">
<select name="safetyProgram" id="safetyProgram" style="width:166px;">
<option value="0" selected>No safety program</option>
<option value="1">Cost containment safety program as certified by the state</option>
<option value="2">Formal written safety program with management oversight including inspections, written documentation, on regular meetings</option>
<option value="3">Formal written safety program with regular meeting</option>
<option value="4">Any safety program less than the aformentioned categories</option>
</select>
</form>
<select name="safetyProgram" id="safetyProgram" style="width:166px;">
<option value="0" selected>No safety program</option>
<option value="1">Cost containment safety program as certified by the state</option>
<option value="2">Formal written safety program with management oversight including inspections, written documentation, on regular meetings</option>
<option value="3">Formal written safety program with regular meeting</option>
<option value="4">Any safety program less than the aformentioned categories</option>
</select>
</form>
Sample
New Code
<form name="test">
<select name="safetyProgram" id="safetyProgram" style="width:166px;position:absolute;z-index:50;" onfocus="this.style.width='auto';" onblur="this.style.width='166px';">
<option value="0" selected>No safety program</option>
<option value="1">Cost containment safety program as certified by the state</option>
<option value="2">Formal written safety program with management oversight including inspections, written documentation, on regular meetings</option>
<option value="3">Formal written safety program with regular meeting</option>
<option value="4">Any safety program less than the aformentioned categories</option>
</select>
</form>
<select name="safetyProgram" id="safetyProgram" style="width:166px;position:absolute;z-index:50;" onfocus="this.style.width='auto';" onblur="this.style.width='166px';">
<option value="0" selected>No safety program</option>
<option value="1">Cost containment safety program as certified by the state</option>
<option value="2">Formal written safety program with management oversight including inspections, written documentation, on regular meetings</option>
<option value="3">Formal written safety program with regular meeting</option>
<option value="4">Any safety program less than the aformentioned categories</option>
</select>
</form>
Sample
Note: If you want to constrict the size the drop down option opens out to, simply change the width parameter in the onFocus from auto to say 300px or something. Play with it. You'll get the idea.
And YES, this hack makes the select box float over your other form widgets and text so it doesn't do strange things with the other form elements.
Have a go at it! It did the trick for me. I hope it works for you too!
Tuesday, January 27, 2009
Binary Object Decoding, Transmitting, Encoding Using Coldfusion
As we start delving into storing binary objects (pdf's, images etc) this post will help you encode, decode and/or transmit the data you are working with. Now I am coming from the perspective of a CF developer so you will need to adapt where need be for environment.
We start with a Binary Object (an image).
1. Binary Object
2. Convert it to base64 for transmitting via xml or another HTTP method
---> a. CF method: toBase64(binaryObj)
3. Receiver takes the data and encodes it back to a binary object
---> a. CF method: toBinary(base64String)
Example:
<cfquery name="q" datasource="#REQUEST.mysqldsn#">
SELECT binaryColumn <!--- This column is a longblob --->
FROM mytable
</cfquery>
<!--- View the data from the DB call --->
<cfdump var="#q#">
<!--- Create a way to view the binary object --->
<cfset myImg1 = ImageNew(q.document)>
<cfimage action="WRITETOBROWSER" source="#myImg1#">
<!--- Now convert the binary object from the DB to a base64 string --->
<cfset doc = tobase64(q.document)>
<!--- Display the base64 string --->
<cfoutput>#doc#</cfoutput>
<!--- Convert the base64 string to a binary object --->
<cfset doc = toBinary(doc)>
<!--- Dump the converted base64 to a binary object to view it --->
<cfdump var="#doc#">
<!--- Create a way to view the binary object --->
<cfset myImg2 = ImageNew(doc)>
<cfimage action="WRITETOBROWSER" source="#myImg2#">
Note: Be sure you change your CFADMIN longblob size limits if you need to store large binary objects. Otherwise the data will be truncated.
We start with a Binary Object (an image).
1. Binary Object
2. Convert it to base64 for transmitting via xml or another HTTP method
---> a. CF method: toBase64(binaryObj)
3. Receiver takes the data and encodes it back to a binary object
---> a. CF method: toBinary(base64String)
Example:
<cfquery name="q" datasource="#REQUEST.mysqldsn#">
SELECT binaryColumn <!--- This column is a longblob --->
FROM mytable
</cfquery>
<!--- View the data from the DB call --->
<cfdump var="#q#">
<!--- Create a way to view the binary object --->
<cfset myImg1 = ImageNew(q.document)>
<cfimage action="WRITETOBROWSER" source="#myImg1#">
<!--- Now convert the binary object from the DB to a base64 string --->
<cfset doc = tobase64(q.document)>
<!--- Display the base64 string --->
<cfoutput>#doc#</cfoutput>
<!--- Convert the base64 string to a binary object --->
<cfset doc = toBinary(doc)>
<!--- Dump the converted base64 to a binary object to view it --->
<cfdump var="#doc#">
<!--- Create a way to view the binary object --->
<cfset myImg2 = ImageNew(doc)>
<cfimage action="WRITETOBROWSER" source="#myImg2#">
Note: Be sure you change your CFADMIN longblob size limits if you need to store large binary objects. Otherwise the data will be truncated.
Wednesday, May 14, 2008
Using SPRY and JSON to Get and Display Query Data
1. Create a Coldfusion Component (cfc) to gather and package your data (See File 1)
2. Create a page to call the cfc and display the returned data. (See File 2)
--------------------------------------------
File 1. (/components/remote.cfc)
--------------------------------------------
<cfcomponent output="false">
<cffunction name="get" access="private" returntype="query" output="yes">
<cfset var q = "">
<cfquery name="q" datasource="#REQUEST.mysqldsn#">
SELECT *
FROM departments
</cfquery>
<cfreturn q>
</cffunction>
<cffunction name="queryToArray" access="private" returntype="array" output="No">
<cfargument name="queryIn" required="Yes" type="query">
<cfset var aResult = arrayNew(1)>
<cfset var q = ARGUMENTS.queryIn>
<cfset var stData = structNew()>
<cfloop query="q">
<cfset stData = structNew()>
<cfloop list="#q.columnList#" index="col">
<cfset stData["#col#"] = Evaluate('q.' & col)>
</cfloop>
<cfset arrayAppend(aResult,stData)>
</cfloop>
<cfreturn aResult>
</cffunction>
<cffunction name="getJSON" access="remote" output="yes" returntype="void">
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<!--- Get department data --->
<cfset departments = get()>
<!--- SPRY likes to work with an array of structures rather than a query object since those are unique to Coldfusion. --->
<cfoutput>#serializeJSON(queryToArray(departments))#</cfoutput>
</cffunction>
</cfcomponent>
--------------------------------------------
--------------------------------------------
File 2. (mySpryExample.cfm)
--------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<html>
<head>
<title>SPRY At Work</title>
<script src="/SpryAssets/SpryData.js" type="text/javascript"></script>
<script src="/SpryAssets/SpryJSONDataSet.js" type="text/javascript"></script>
<script language="JavaScript">
var ds1 = new Spry.Data.JSONDataSet("/components/remote.cfc?method=getJSON",{useCache:false});
</script>
</head>
<body>
<div spry:region="ds1">
<table>
<tr>
<th spry:sort="DEPARTMENTID" style="cursor:pointer;">Dept ID</th>
<th spry:sort="DEPARTMENT" style="cursor:pointer;">Department</th>
</tr>
<tr spry:repeat="ds1" spry:even="altColor">
<td>{ds1::DEPARTMENTID}</td>
<td>{ds1::DEPARTMENT}</td>
</tr>
</table>
</div>
</body>
</html>
--------------------------------------------
--------------------------------------------
MySQL Table Construct
--------------------------------------------
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for departments
-- ----------------------------
CREATE TABLE `departments` (
`departmentid` int(11) NOT NULL auto_increment,
`department` varchar(45) default NULL,
PRIMARY KEY (`departmentid`),
UNIQUE KEY `deptid` (`departmentid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `departments` VALUES ('1', 'Sales');
INSERT INTO `departments` VALUES ('2', 'Accounting');
INSERT INTO `departments` VALUES ('3', 'Customer Service');
--------------------------------------------
This code has been tested on Firefox and I.E.
Fusecast Web Application Development and Web Hosting Services
www.fusecast.com
2. Create a page to call the cfc and display the returned data. (See File 2)
--------------------------------------------
File 1. (/components/remote.cfc)
--------------------------------------------
<cfcomponent output="false">
<cffunction name="get" access="private" returntype="query" output="yes">
<cfset var q = "">
<cfquery name="q" datasource="#REQUEST.mysqldsn#">
SELECT *
FROM departments
</cfquery>
<cfreturn q>
</cffunction>
<cffunction name="queryToArray" access="private" returntype="array" output="No">
<cfargument name="queryIn" required="Yes" type="query">
<cfset var aResult = arrayNew(1)>
<cfset var q = ARGUMENTS.queryIn>
<cfset var stData = structNew()>
<cfloop query="q">
<cfset stData = structNew()>
<cfloop list="#q.columnList#" index="col">
<cfset stData["#col#"] = Evaluate('q.' & col)>
</cfloop>
<cfset arrayAppend(aResult,stData)>
</cfloop>
<cfreturn aResult>
</cffunction>
<cffunction name="getJSON" access="remote" output="yes" returntype="void">
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<!--- Get department data --->
<cfset departments = get()>
<!--- SPRY likes to work with an array of structures rather than a query object since those are unique to Coldfusion. --->
<cfoutput>#serializeJSON(queryToArray(departments))#</cfoutput>
</cffunction>
</cfcomponent>
--------------------------------------------
--------------------------------------------
File 2. (mySpryExample.cfm)
--------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<html>
<head>
<title>SPRY At Work</title>
<script src="/SpryAssets/SpryData.js" type="text/javascript"></script>
<script src="/SpryAssets/SpryJSONDataSet.js" type="text/javascript"></script>
<script language="JavaScript">
var ds1 = new Spry.Data.JSONDataSet("/components/remote.cfc?method=getJSON",{useCache:false});
</script>
</head>
<body>
<div spry:region="ds1">
<table>
<tr>
<th spry:sort="DEPARTMENTID" style="cursor:pointer;">Dept ID</th>
<th spry:sort="DEPARTMENT" style="cursor:pointer;">Department</th>
</tr>
<tr spry:repeat="ds1" spry:even="altColor">
<td>{ds1::DEPARTMENTID}</td>
<td>{ds1::DEPARTMENT}</td>
</tr>
</table>
</div>
</body>
</html>
--------------------------------------------
--------------------------------------------
MySQL Table Construct
--------------------------------------------
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for departments
-- ----------------------------
CREATE TABLE `departments` (
`departmentid` int(11) NOT NULL auto_increment,
`department` varchar(45) default NULL,
PRIMARY KEY (`departmentid`),
UNIQUE KEY `deptid` (`departmentid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `departments` VALUES ('1', 'Sales');
INSERT INTO `departments` VALUES ('2', 'Accounting');
INSERT INTO `departments` VALUES ('3', 'Customer Service');
--------------------------------------------
This code has been tested on Firefox and I.E.
Fusecast Web Application Development and Web Hosting Services
www.fusecast.com
Tuesday, May 13, 2008
Getting Internet Explorer to Release Dataset Cache
Getting I.E. to STOP caching Spry datasets.
This help can be applied to all languages (PHP, ASP, Coldfusion) but since I am primarily a Coldfusion developer, I'll demonstrate how I solved this issue using CFML and JavaScript.
--------------------------------------------------------------------------
File 1. remote.cfc
This file basically returns the XML I will call from Spry
--------------------------------------------------------------------------
<cfcomponent>
<cffunction name="qGetData" access="remote" output="No" returntype="any">
<cfargument name="chatid" required="Yes">
<cfquery name="qGetData" datasource="#DSN#">
SELECT *
FROM chat
WHERE chatid = #ARGUMENTS.chatid#
</cfquery>
<!--- !!!!! IMPORTANT !!!!! --->
<!--- START :: THIS BLOCK OF CODE IS REQUIRED!!! THIS IS WHAT TELLS SPRY TO NOT CACHE THE INCOMING DATA --->
<cfcontent type="text/xml"><!--- I.E. NEEDS THIS --->
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<!--- END :: THIS BLOCK OF CODE IS REQUIRED!!! THIS IS WHAT TELLS SPRY TO NOT CACHE THE INCOMING DATA --->
<!--- !!!!! IMPORTANT !!!!! --->
<cfset rtrn = "">
<cfxml variable="rtrn">
<chat>
<topic><cfoutput>#qGetData.topic#</cfoutput></topic>
<cfoutput query="qGetData">
<thread>
<date>#DateFormat(qGetData.dtCreated,"m/d/yyyy")#</date>
<time>#TimeFormat(qGetData.dtCreated,"h:mm:ss tt")#</time>
<firstName>#qGetData.first_name#</firstName>
<lastName>#qGetData.last_name#</lastName>
<content><![CDATA[#qGetData.content#]]></content>
</thread>
</cfoutput>
</chat>
</cfxml>
<cfreturn rtrn>
</cffunction>
</cfcomponent>
--------------------------------------------------------------------------
--------------------------------------------------------------------------
File 2. Calling page (chat.cfm)
This file uses Spry to get my dataset from File 1.
--------------------------------------------------------------------------
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<html>
<head><title>My Chat</title></head>
<script src="/SpryAssets/xpath.js" type="text/javascript"></script>
<script src="/SpryAssets/SpryData.js" type="text/javascript"></script>
<body>
<cfoutput><script language="JavaScript">
//!!!!! IMPORTANT !!!!!
//This variable is appended to the query string to ensure that a cached dataset isn't returned.
var d = new Date().valueOf();
//!!!!! IMPORTANT !!!!!
threads = new Spry.Data.XMLDataSet("/components/remote.cfc?method=qGetData&chatid=#URL.chatid#&cacheBuster=" + d.toString(), //!!!!! IMPORTANT !!!!!
"chat/thread",
{
distinctOnLoad:true,
loadInterval:2000,
useCache:false //this ONLY works in Firefox.
}
);
//The content column needs to be defined as HTML. What a bugger this was to figure out!
threads.setColumnType("content", "html");
</script></cfoutput>
<!--- Output your data! --->
<div spry:region="threads">
<div spry:repeat="threads">
{threads::firstName} says: {threads::time}<br>
<div>{threads::content}</div>
</div>
</div>
</body>
</html>
--------------------------------------------------------------------------
That should do it. EVERYWHERE you see !!!!! IMPORTANT !!!!! you must be sure to do.
Good luck!
Steve Holland
Fusecast
This help can be applied to all languages (PHP, ASP, Coldfusion) but since I am primarily a Coldfusion developer, I'll demonstrate how I solved this issue using CFML and JavaScript.
--------------------------------------------------------------------------
File 1. remote.cfc
This file basically returns the XML I will call from Spry
--------------------------------------------------------------------------
<cfcomponent>
<cffunction name="qGetData" access="remote" output="No" returntype="any">
<cfargument name="chatid" required="Yes">
<cfquery name="qGetData" datasource="#DSN#">
SELECT *
FROM chat
WHERE chatid = #ARGUMENTS.chatid#
</cfquery>
<!--- !!!!! IMPORTANT !!!!! --->
<!--- START :: THIS BLOCK OF CODE IS REQUIRED!!! THIS IS WHAT TELLS SPRY TO NOT CACHE THE INCOMING DATA --->
<cfcontent type="text/xml"><!--- I.E. NEEDS THIS --->
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<!--- END :: THIS BLOCK OF CODE IS REQUIRED!!! THIS IS WHAT TELLS SPRY TO NOT CACHE THE INCOMING DATA --->
<!--- !!!!! IMPORTANT !!!!! --->
<cfset rtrn = "">
<cfxml variable="rtrn">
<chat>
<topic><cfoutput>#qGetData.topic#</cfoutput></topic>
<cfoutput query="qGetData">
<thread>
<date>#DateFormat(qGetData.dtCreated,"m/d/yyyy")#</date>
<time>#TimeFormat(qGetData.dtCreated,"h:mm:ss tt")#</time>
<firstName>#qGetData.first_name#</firstName>
<lastName>#qGetData.last_name#</lastName>
<content><![CDATA[#qGetData.content#]]></content>
</thread>
</cfoutput>
</chat>
</cfxml>
<cfreturn rtrn>
</cffunction>
</cfcomponent>
--------------------------------------------------------------------------
--------------------------------------------------------------------------
File 2. Calling page (chat.cfm)
This file uses Spry to get my dataset from File 1.
--------------------------------------------------------------------------
<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="0">
<cfheader name="Pragma" value="no-cache">
<html>
<head><title>My Chat</title></head>
<script src="/SpryAssets/xpath.js" type="text/javascript"></script>
<script src="/SpryAssets/SpryData.js" type="text/javascript"></script>
<body>
<cfoutput><script language="JavaScript">
//!!!!! IMPORTANT !!!!!
//This variable is appended to the query string to ensure that a cached dataset isn't returned.
var d = new Date().valueOf();
//!!!!! IMPORTANT !!!!!
threads = new Spry.Data.XMLDataSet("/components/remote.cfc?method=qGetData&chatid=#URL.chatid#&cacheBuster=" + d.toString(), //!!!!! IMPORTANT !!!!!
"chat/thread",
{
distinctOnLoad:true,
loadInterval:2000,
useCache:false //this ONLY works in Firefox.
}
);
//The content column needs to be defined as HTML. What a bugger this was to figure out!
threads.setColumnType("content", "html");
</script></cfoutput>
<!--- Output your data! --->
<div spry:region="threads">
<div spry:repeat="threads">
{threads::firstName} says: {threads::time}<br>
<div>{threads::content}</div>
</div>
</div>
</body>
</html>
--------------------------------------------------------------------------
That should do it. EVERYWHERE you see !!!!! IMPORTANT !!!!! you must be sure to do.
Good luck!
Steve Holland
Fusecast
Tuesday, March 25, 2008
Set All Form Fields In All Forms To Disabled
/*----------------------------------------------------
This code disables ALL fields in all forms on a screen.
USAGE:
<script language="JavaScript">
disableForms()
</script>
----------------------------------------------------*/
function disableForms(){
//Loop over the forms
for(i=0;i<document.forms.length;i++){
//Loop over the form elements
for(j=0;j>document.forms[i].elements.length;j++){
//alert(document.forms[i].elements[j].name);
document.forms[i].elements[j].disabled = "true";
}
}
}
This code disables ALL fields in all forms on a screen.
USAGE:
<script language="JavaScript">
disableForms()
</script>
----------------------------------------------------*/
function disableForms(){
//Loop over the forms
for(i=0;i<document.forms.length;i++){
//Loop over the form elements
for(j=0;j>document.forms[i].elements.length;j++){
//alert(document.forms[i].elements[j].name);
document.forms[i].elements[j].disabled = "true";
}
}
}
Friday, February 8, 2008
FCKEditor and Stylesheets
Getting FCKEditor to work with your stylesheets is a trick because documentation on how to do it is not very good. You get the basics here and there but finding docs that tell you how from A-Z just doesn't exists.... till now. Here's how I did it.
This is what I figured out for FCKEditor to get it to use custom stylesheets...
1. Open up /fckeditor/fckconfig.js
1a. Edit the following variable:
FCKConfig.BaseHref = 'http://www.yourDomain.com/';
FCKConfig.EditorAreaCSS = '/style.css' ;
Save and close
2. Open up /fckeditor/fckstyles.xml
2a. Define your styles:
E.g.
<Style name="heading1" element="span">
<Attribute name="class" value="heading1" />
</Style>
<Style name="heading2" element="span">
<Attribute name="class" value="heading2" />
</Style>
<Style name="heading3" element="span">
<Attribute name="class" value="heading3" />
</Style>
(Note: this XML must coincide with your CSS. If you have a Style called "myHeader", then you would have XML that would look like this)
<Style name="myHeader" element="span">
<Attribute name="class" value="myHeader" />
</Style>
Save and close.
The Jist.
The first operation pulls in the entire CSS stylesheet your using.
The second operation allows you to show in the style drop down what styles to be used by the user. Not all of the styles in the CSS file are seen or needed by the user normally. This is a great way to separate them but allow them to use their defined styles.
This is what I figured out for FCKEditor to get it to use custom stylesheets...
1. Open up /fckeditor/fckconfig.js
1a. Edit the following variable:
FCKConfig.BaseHref = 'http://www.yourDomain.com/';
FCKConfig.EditorAreaCSS = '/style.css' ;
Save and close
2. Open up /fckeditor/fckstyles.xml
2a. Define your styles:
E.g.
<Style name="heading1" element="span">
<Attribute name="class" value="heading1" />
</Style>
<Style name="heading2" element="span">
<Attribute name="class" value="heading2" />
</Style>
<Style name="heading3" element="span">
<Attribute name="class" value="heading3" />
</Style>
(Note: this XML must coincide with your CSS. If you have a Style called "myHeader", then you would have XML that would look like this)
<Style name="myHeader" element="span">
<Attribute name="class" value="myHeader" />
</Style>
Save and close.
The Jist.
The first operation pulls in the entire CSS stylesheet your using.
The second operation allows you to show in the style drop down what styles to be used by the user. Not all of the styles in the CSS file are seen or needed by the user normally. This is a great way to separate them but allow them to use their defined styles.
Subscribe to:
Posts (Atom)
