<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7892073789948849699</id><updated>2011-08-29T16:17:33.130-07:00</updated><category term='Integration'/><category term='Office'/><title type='text'>The Diary of a WorkXpress Programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-4784659469513206472</id><published>2011-01-17T07:02:00.000-08:00</published><updated>2011-01-17T07:02:44.175-08:00</updated><title type='text'>Satisfaction</title><content type='html'>Recently I was forwarded &lt;a href="http://www.eventmarketer.com/article/staffing-dashboards"&gt;an article in Event Marketer Magazine&lt;/a&gt; where the author reviewed 5 products that have allowed "the last of the low-tech event sectors [to plug] in." &amp;nbsp;One of the products reviewed was built on the WorkXpress Platform, and is competing with no less than 4 software solutions built to serve the industry of Event Staffing, directly. &amp;nbsp;This level of success is very exciting to me personally because it shatters the depths of removal that our engineering team is constantly buried beneath.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://eventprostrategies.com/images/stories/technology/custom-client-portal.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://eventprostrategies.com/images/stories/technology/custom-client-portal.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;A screenshot of the homepage of their WorkXpress product.&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;Feature development at WorkXpress is very abstract.  On any given day I might make a change to how values of a certain field type sort, or are searched.  I might add a new type of field, defining how it looks when edited, and viewed, how it's searched, etc.   I might add a new type of action, adding power to our logic engine.  Often times these additions and changes are done inside a contained development space so that I know what will go in, and can tweak what will come out.  Seldom do I get to see how a builder uses this new feature, and even less often do I get to see a customer using this new feature in a way that impacts them.  Unfortunately, without seeing how what we do impacts feet on the ground, there is a certain satisfaction missing from our role as engineers.&lt;br /&gt;&lt;br /&gt;Granted, we hear things like "Tom from ServoLift told me yesterday that this past year was the best year they've ever had and in large part it's thanks to their WorkXpress product" from the support team, but that pale's in comparison to actually seeing a product built on our platform adding real value to a company's employee's day to day work. &amp;nbsp;Even that pale's in comparison to the satisfaction I got when I found out that not only does a product built on WorkXpress (EPS Tracker 2.0) power EventPro Strategy's day to day business, but it does it so well it was featured in a tech magazine about that industry.&lt;br /&gt;&lt;br /&gt;Our vision is to build a platform that is business agnostic; anyone should be able to use it to build solutions that can solve any business need regardless of size or shape. &amp;nbsp;We believe that if we do a good enough job in delivering our vision then businesses will be free of the non-customizeable, 'You will run your business &lt;b&gt;this&lt;/b&gt; way,' industry products that are out there now. &amp;nbsp;They will be able to produce software that's custom fit to their needs so they are free to run their business as they see fit on software that works with them instead of against them.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The satisfaction of seeing that vision deliver so well to EPS that they not only have a solution that's helped them be more successful, but that it competes with industry specific products, is immense.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-4784659469513206472?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/4784659469513206472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=4784659469513206472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4784659469513206472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4784659469513206472'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2011/01/satisfaction.html' title='Satisfaction'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-4264820221688280868</id><published>2010-10-22T13:17:00.000-07:00</published><updated>2010-10-22T13:23:13.784-07:00</updated><title type='text'>Speeding up MySQL Routines with C using UDF : Part 2 -&gt; MySQL's Example udf_example.c</title><content type='html'>&lt;a href="http://workxpress.blogspot.com/2010/10/speeding-up-mysql-routines-with-c-using.html"&gt;&lt;- Part 1 :  Intro&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The first thing I did when researching UDF's was to head over to the MySQL Documentation and read about what was ahead of me.  Makes sense, right?  If only it were that simple :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/udf-compiling.html"&gt;This page&lt;/a&gt; in the MySQL Docs tells us that there's an example udf file that comes with the source code for MySQL. &amp;nbsp;So, I hopped over to their site, downloaded the source, and found the file. &amp;nbsp;sql/udf_example.c &amp;nbsp;Now, admittedly it has been a &lt;b&gt;long&lt;/b&gt;&amp;nbsp;time since I wrote any C, or even compiled any (with the exception of ./configure, make, make install type "install from source" stuff)... so I figured their example compile line would work :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;dmclain@Percona:~$ gcc -shared -o udf_example.so udf_example.c&lt;br /&gt;udf_example.c:127:23: error: my_global.h: No such file or directory&lt;br /&gt;udf_example.c:128:20: error: my_sys.h: No such file or directory&lt;br /&gt;udf_example.c:139:19: error: mysql.h: No such file or directory&lt;br /&gt;udf_example.c:142: error: syntax error before ‘LOCK_hostname’&lt;br /&gt;udf_example.c:142: warning: data definition has no type or storage class&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;.. Not even close. &amp;nbsp;As you can see, it was missing a bunch of include files, so I ended up adding -I/path/to/mysql/includes&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;dmclain@Percona:~$ gcc -shared -o udf_example.so udf_example.c -I/home/dmclain/mysql_5.1/include&lt;br /&gt;In file included from ./udf_example2.c:127:&lt;br /&gt;./my_global.h:80:23: error: my_config.h: No such file or directory&lt;br /&gt;./my_global.h:602:26: error: my_attribute.h: No such file or directory&lt;br /&gt;./my_global.h:639:21: error: my_dbug.h: No such file or directory&lt;br /&gt;In file included from ./udf_example2.c:127:&lt;br /&gt;./my_global.h:678: error: syntax error before ‘size_socket’&lt;br /&gt;./my_global.h:678: warning: data definition has no type or storage class&lt;br /&gt;./my_global.h:803:2: error: #error "please add -DSTACK_DIRECTION=1 or -1 to your CPPFLAGS"&lt;br /&gt;./my_global.h:871:1: warning: "isnan" redefined&lt;br /&gt;In file included from /usr/include/math.h:28,&lt;br /&gt; ------ Snip --------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now keep in mind, I didn't actually install mysql from the source that I downloaded, I was just trying to compile the udf_example.c to use with my existing PerconaDB or MySQL installation. &amp;nbsp;I didn't want to mess up my existing installation.&lt;br /&gt;&lt;br /&gt;So, after a few hours of banging my head against this.. I found this cool site :&amp;nbsp;&lt;a href="http://www.mysqludf.org/"&gt;http://www.mysqludf.org&lt;/a&gt;&amp;nbsp;. &amp;nbsp;This is a group of folks who are trying to being a bit of order to a set of C functions that can be added to your MySQL installation in terms of the parameters, and naming conventions, etc. &amp;nbsp;What caught my eye mostly tho was the Skeleton package :&amp;nbsp;&lt;a href="http://www.mysqludf.org/participation/lib_mysqludf_skeleton.tar.gz"&gt;http://www.mysqludf.org/participation/lib_mysqludf_skeleton.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I downloaded and uncompressed this package which seems to include everything I need to compile an example C function for use in UDF in MySQL, which just returns it's own name, using commands I recognize!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;dmclain@Percona:~$ autoreconf&lt;br /&gt;dmclain@Percona:~$ ./configure&lt;br /&gt;  -- Snip --&lt;br /&gt;dmclain@Percona:~$ make&lt;br /&gt;  -- Snip --&lt;br /&gt;dmclain@Percona:~$ ls&amp;nbsp;lib_mysqludf_skeleton/.libs&lt;br /&gt;lib_mysqludf_skeleton.a  lib_mysqludf_skeleton.la  lib_mysqludf_skeleton.lai  lib_mysqludf_skeleton_la-lib_mysqludf_skeleton.o  lib_mysqludf_skeleton_la-mysqludf.o  lib_mysqludf_skeleton.so&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now you can use installdb.sql to register it. &amp;nbsp;I like to know what those kinds of scripts do tho, since I will need to replicate the registration process during the &lt;a href="http://www.workxpress.com/"&gt;WorkXpress&lt;/a&gt; engine rollout that includes this work. &amp;nbsp;First it drops the function incase it already exists in your database, then then it adds your new function :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;CREATE FUNCTION lib_mysqludf_skeleton_info RETURNS STRING SONAME 'lib_mysqludf_skeleton.so';&lt;/pre&gt;&lt;br /&gt;Notice there's no full path on the front of the SONAME.  That's because MySQL has a directory where it puts plugins.  You can ask your MySQL Server where *it* stores plugins with : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysql&gt; show variables like '%plugin%';&lt;br /&gt;+---------------+-----------------------+&lt;br /&gt;| Variable_name | Value                 |&lt;br /&gt;+---------------+-----------------------+&lt;br /&gt;| plugin_dir    | /usr/lib/mysql/plugin |&lt;br /&gt;+---------------+-----------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So I added a sym link from /usr/lib/mysql/plugin for my SO in my working area : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;dmclain@Percona:~$ sudo ln -s /home/dmclain/lib_mysqludf_skeleton/.libs/lib_mysqludf_skeleton.so  /usr/lib/mysql/plugin/lib_mysqludf_skeleton.so&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then I restarted MySQL so it would find the new plugin; and ran the command : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysql&gt; select lib_mysqludf_skeleton_info();&lt;br /&gt;+------------------------------+&lt;br /&gt;| lib_mysqludf_skeleton_info() |&lt;br /&gt;+------------------------------+&lt;br /&gt;| lib_mysqludf_skeleton 0.0.1  |&lt;br /&gt;+------------------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, this is step by step to download, compile, register and run the "Skeleton Info" function from &lt;a href="http://www.mysqludf.org"&gt;http://www.mysqludf.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now that I have a C function running in MySQL.. it's time to make one that does something I need it to do :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-4264820221688280868?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/4264820221688280868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=4264820221688280868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4264820221688280868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4264820221688280868'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2010/10/speeding-up-mysql-routines-with-c-using_22.html' title='Speeding up MySQL Routines with C using UDF : Part 2 -&gt; MySQL&apos;s Example udf_example.c'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-4511363439257529861</id><published>2010-10-22T12:46:00.000-07:00</published><updated>2010-10-22T13:20:27.935-07:00</updated><title type='text'>Speeding up MySQL Routines with C using UDF : Part 1</title><content type='html'>&lt;div&gt;Most of you probably already know that you can write Routines in MySQL (5.1+) to allow you to encapsulate logic that you re-use into a simple to run command.  An example...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;In &lt;a href="http://www.workxpress.com/"&gt;WorkXpress&lt;/a&gt; we store Address data in our databases as XML, since an address is just one field there's only one cell in the database to store Address 1, Address 2, City, State, Zip and Country.  So, instead of creating a special kind of table to store this data, we decided to simply store it like this :&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;multi_part_field&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="street"&amp;gt;1757 Canvasback Lane&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="street2"&amp;gt;&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="street3"&amp;gt;&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="city"&amp;gt;Eagan&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="state"&amp;gt;MN&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="zip_code"&amp;gt;55122&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="country"&amp;gt;United States&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;part id="type"&amp;gt;United States&amp;lt;/part&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/multi_part_field&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;So, when we need to pull just the City out of an address because it was requested in an expression, I can use an XML XPATH function built into MySQL called extractvalue() and pull the value out and return it.  The bold line is the key to this function, the rest is just structure/sanity checks :&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;FUNCTION `wx_Address_Us_GetCity`(input_value text) RETURNS varchar(64) CHARSET utf8 DETERMINISTIC&lt;br /&gt;&amp;nbsp;BEGIN&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IF input_value IS NULL THEN&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RETURN input_value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ELSE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;RETURN extractvalue(input_value, '/multi_part_field/part[@id="city"]');&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;END IF;&lt;br /&gt;&amp;nbsp;END&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;With this function in place, you can run SQL like the below (assuming there is XML Address Data in your 'value' column) and it will pull out just the City :&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;SELECT wx_Address_Us_GetCity(value) FROM table;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;This is great functionality, and it enabled us to do a lot of really cool stuff in the backend of &lt;a href="http://www.workxpress.com/"&gt;WorkXpress&lt;/a&gt;&amp;nbsp;with our Expression Builder. &amp;nbsp;We hit a wall, however, with the functionality of what you can do inside a MySQL FUNCTION, as declared above, and that's where UDF's come in.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The UDF features of MySQL allow you to write functions in C/C++, and hook them up into a MySQL function! &amp;nbsp;UDF Functions are not only more fully featured, but rumored to run more efficiently/quickly depending on the functionality you're looking to write into a function.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;As part of our switch from MyISAM on MySQL Server 5.1 to XtraDB (a better version of InnoDB) on PerconaDB we will absolutely need to re-write 4 of the 96 functions in C, because of feature limitations to MySQL's Function language. &amp;nbsp;Because of the rumored speed improvements in using UDF C functions over MySQL's built in language, we're likely going to rewrite all 96.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I'll be sharing performance benchmarks, pitfalls and potholes I hit along the way and hopefully my success story when the functions have been converted and are ready for release into the &lt;a href="http://www.workxpres.com/"&gt;WorkXpress&lt;/a&gt; PaaS Engine.&lt;/div&gt;&lt;br /&gt;&lt;a href="http://workxpress.blogspot.com/2010/10/speeding-up-mysql-routines-with-c-using_22.html"&gt;Part 2 : MySQL's Example - udf_example.c&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-4511363439257529861?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/4511363439257529861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=4511363439257529861' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4511363439257529861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4511363439257529861'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2010/10/speeding-up-mysql-routines-with-c-using.html' title='Speeding up MySQL Routines with C using UDF : Part 1'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-3660123962876756222</id><published>2009-10-28T06:45:00.000-07:00</published><updated>2009-10-28T07:06:57.453-07:00</updated><title type='text'>WorkXpress goes in for some pastic surgery</title><content type='html'>Today the Engineering Team at WorkXpress took the bandages off of the Engine after a few rounds of plastic surgery; and it looks goood.&lt;br /&gt;&lt;br /&gt;Below are some screen shots of before and after the changes :&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Production Mode : No Tools, 'old and busted':&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_F3uiLYjqK3A/SuhLrrpxO5I/AAAAAAAAAKU/W9qZh-Ggg9o/s1600-h/old_prod.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 247px;" src="http://2.bp.blogspot.com/_F3uiLYjqK3A/SuhLrrpxO5I/AAAAAAAAAKU/W9qZh-Ggg9o/s400/old_prod.png" alt="" id="BLOGGER_PHOTO_ID_5397647367227915154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Production Mode : No Tools, 'new hotness':&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_F3uiLYjqK3A/SuhLrCXlnuI/AAAAAAAAAKE/z55enRUx_40/s1600-h/new_prod.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 247px;" src="http://4.bp.blogspot.com/_F3uiLYjqK3A/SuhLrCXlnuI/AAAAAAAAAKE/z55enRUx_40/s400/new_prod.png" alt="" id="BLOGGER_PHOTO_ID_5397647356145802978" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Development Mode : With Tools, 'old and busted':&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_F3uiLYjqK3A/SuhP6oGXo9I/AAAAAAAAAKk/iQ4Cys1RTw8/s1600-h/old.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 247px;" src="http://4.bp.blogspot.com/_F3uiLYjqK3A/SuhP6oGXo9I/AAAAAAAAAKk/iQ4Cys1RTw8/s400/old.png" alt="" id="BLOGGER_PHOTO_ID_5397652022018679762" border="0" /&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Development Mode : With Tools, 'new hotness':&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_F3uiLYjqK3A/SuhP6QSKFOI/AAAAAAAAAKc/N13fr3H4Szc/s1600-h/new.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 247px;" src="http://2.bp.blogspot.com/_F3uiLYjqK3A/SuhP6QSKFOI/AAAAAAAAAKc/N13fr3H4Szc/s400/new.png" alt="" id="BLOGGER_PHOTO_ID_5397652015625671906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Never, ever... touch.. the red button!&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-3660123962876756222?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/3660123962876756222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=3660123962876756222' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3660123962876756222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3660123962876756222'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/10/workxpress-goes-in-for-some-pastic.html' title='WorkXpress goes in for some pastic surgery'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_F3uiLYjqK3A/SuhLrrpxO5I/AAAAAAAAAKU/W9qZh-Ggg9o/s72-c/old_prod.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-2863946033671521456</id><published>2009-07-06T06:18:00.001-07:00</published><updated>2009-07-06T06:19:03.610-07:00</updated><title type='text'>The Branding Spot : Week 3</title><content type='html'>The Week 3 review of how things are going with "The Branding Spot" has been posted.  Please take a minute to check it out : &lt;strong&gt;&lt;a href="http://tiny.cc/JTcoM" target="_blank"&gt;&lt;strong&gt;http://tiny.cc/JTcoM&lt;/strong&gt;&lt;/a&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-2863946033671521456?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/2863946033671521456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=2863946033671521456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2863946033671521456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2863946033671521456'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/07/branding-spot-week-3.html' title='The Branding Spot : Week 3'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-6990695851982171077</id><published>2009-06-25T14:01:00.001-07:00</published><updated>2009-06-25T14:03:36.888-07:00</updated><title type='text'>The Scoop on PaaS</title><content type='html'>Ever wonder how a PaaS might help a mid to large sized business like the one you work for?  Give this post a quick read, and if it strikes a nerve "Oh yeah.. we deal with that.. and MAN is it a drag!", get in touch with &lt;a href="mailto:jburns@workxpress.com"&gt;Jake&lt;/a&gt;, or &lt;a href="mailto:ahodges@workxpress.com"&gt;Anna&lt;/a&gt;, or the &lt;a href="mailto:sales@workxpress.com"&gt;Sales Team&lt;/a&gt; so we can have a deeper discussion about how we might help you out!&lt;br /&gt;&lt;br /&gt;Believe it or not.. we truely want to help!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.workxpress.com/blog/2009/06/5gl-paas-will-change-it-landscape"&gt;http://www.workxpress.com/blog/2009/06/5gl-paas-will-change-it-landscape&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-6990695851982171077?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/6990695851982171077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=6990695851982171077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/6990695851982171077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/6990695851982171077'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/06/scoop-on-paas.html' title='The Scoop on PaaS'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-2740635353276222636</id><published>2009-06-25T13:30:00.001-07:00</published><updated>2009-06-25T13:30:33.336-07:00</updated><title type='text'>WorkXpress working with The Branding Spot</title><content type='html'>Recently Jake Burns wrote : &lt;a href="http://www.workxpress.com/blog/2009/06/week-2-week-week-introspective-how-branding-spot-will-use-workxpress-transform-clients-"&gt;http://www.workxpress.com/blog/2009/06/week-2-week-week-introspective-how-branding-spot-will-use-workxpress-transform-clients-&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's exciting to me, having worked on the platform since the beginning, to hear customers say things like&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"As far as we know, and we’ve done the research, our company will be far ahead of the curve in ability to provide companies exactly the staffing they need to pull off successful sampling and other promotional events. &lt;span class="Apple-style-span" style="border-collapse: separate; color: rgb(7, 36, 140); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;font-family:'Times New Roman';font-size:16;"  &gt;&lt;span class="Apple-style-span" style="color: rgb(102, 102, 102); line-height: 21px;font-family:'Trebuchet MS';font-size:12;"  &gt;&lt;/span&gt;&lt;/span&gt;"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It's just very rewarding.  I get a similar thrill out of walking down the hall and seeing TexVisions Users screens with WorkXpress up on them.  It's one thing to build a product, and make it the best you can, but its another to have a business owner choose it to help run their business.  Despite all the customers using WorkXpress, it still excites me to see it :-)&lt;br /&gt;&lt;br /&gt;Last, I'll just say that I really enjoy working with Noah.  He's a sharp guy, communicates well with his customers, and communicates well with the Dev team on the occasion that ne needs to.  For the most part, tho, he doesn't need to.. and that brings a satisfaction all it's own.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-2740635353276222636?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/2740635353276222636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=2740635353276222636' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2740635353276222636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2740635353276222636'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/06/workxpress-working-with-branding-spot.html' title='WorkXpress working with The Branding Spot'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-3147834020553643416</id><published>2009-06-18T13:37:00.001-07:00</published><updated>2009-06-19T10:03:04.354-07:00</updated><title type='text'>Q2 (early Q3) 2009 Upcoming Engine Features</title><content type='html'>The WorkXpress Engine Development team's schedule is booked, and the requests keep coming.  More work the better, I say :-)  I have posted the items we'll be working on for the next 4-6 weeks on the WorkXpress Blog, so if you're interested check it out : &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.workxpress.com/forums/upcoming-features/714"&gt;http://www.workxpress.com/forums/upcoming-features/714&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-3147834020553643416?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/3147834020553643416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=3147834020553643416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3147834020553643416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3147834020553643416'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/06/q2-early-q3-2009-upcoming-engine.html' title='Q2 (early Q3) 2009 Upcoming Engine Features'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-243657831451354413</id><published>2009-03-30T10:47:00.000-07:00</published><updated>2009-03-30T10:53:53.945-07:00</updated><title type='text'>The Videos are up!</title><content type='html'>Today is a capstone day, marking the completion of a recent video production project that we embarked on.  A few weeks back we had my brother, &lt;a href="http://mclainhome.blogspot.com/"&gt;Tim McLain&lt;/a&gt;, up for a 1 day "shooting spree", shooting the raw video for our training videos, introduction and our "&lt;a href="http://www.workxpress.com/tour/build-application-10-minutes"&gt;Build an app in 10 minutes&lt;/a&gt;" video.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;He turned them around quite fast, and after wrestling with the bandwidth costs of hosting the videos ourselves, we decided to post them on Google's Video service.  That went quite smoothly, and we got the videos posted to our live website around 1:00PM today.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My favorite video is the "&lt;a href="http://www.workxpress.com/tour/build-application-10-minutes"&gt;Build an Application in 10 minutes&lt;/a&gt;" video and it's one that really captures the basics of what WorkXpress IS, and what it's used for.  I urge any of you who still don't understand "What does WorkXpress do/What is it?"  Please, enjoy this video!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-243657831451354413?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/243657831451354413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=243657831451354413' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/243657831451354413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/243657831451354413'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/03/videos-are-up.html' title='The Videos are up!'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-4004032222070521864</id><published>2009-03-26T14:23:00.000-07:00</published><updated>2009-03-26T14:27:29.505-07:00</updated><title type='text'>How WorkXpress cut my project timeline by 70%</title><content type='html'>&lt;div&gt;Recently I wrote a Blog post for WorkXpress about how I was able to produce a fully featured Systems and Network Monitoring tool in record time, and with 100% user satisfaction.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Check it out &lt;a href="http://www.workxpress.com/content/how-workxpress-cut-my-project-timeline-70"&gt;here&lt;/a&gt;!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-4004032222070521864?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/4004032222070521864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=4004032222070521864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4004032222070521864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/4004032222070521864'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/03/how-workxpress-cut-my-project-timeline.html' title='How WorkXpress cut my project timeline by 70%'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-5782680277660020764</id><published>2009-03-07T05:42:00.001-08:00</published><updated>2009-03-07T06:51:39.055-08:00</updated><title type='text'>Does a Fox go on Safari, or to the Opera?</title><content type='html'>Browsers, the bane of all web developers.  Anyone who's ever tried to write their own web code (not talking about &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;DWeaver&lt;/span&gt;, Blogger, Google Pages, or even &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;AngelFire&lt;/span&gt;) has gotten this inevitable email.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Dear Webmaster,&lt;br /&gt;&lt;br /&gt;I'm using Netscape 3 and your &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;web page&lt;/span&gt; doesn't look right!&lt;br /&gt;&lt;br /&gt;Sincerely,&lt;br /&gt;0.5% of the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;Market Share&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;existence&lt;/span&gt; of more than 1 web browser has lead to a lot of extra work for web developers all over the world.  This morning my desktop looks like this :&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_F3uiLYjqK3A/SbJ_ckowxHI/AAAAAAAAAE4/st8p4QAV2fw/s1600-h/Browsers.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 55px;" src="http://3.bp.blogspot.com/_F3uiLYjqK3A/SbJ_ckowxHI/AAAAAAAAAE4/st8p4QAV2fw/s400/Browsers.png" alt="" id="BLOGGER_PHOTO_ID_5310447039470945394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I have just completed close to a week of cleanup of our &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;WX&lt;/span&gt;2 engine fixing small problems that effect one browser or another.  Mostly, IE7 is the problem as it treats the box model, float and positioning layers a bit differently than the other browsers do; and... according to a few of the leading browser market-share reporting sites, it still holds a small lead over FireFox.&lt;br /&gt;&lt;br /&gt;I'm encouraged tho, the balance of "power" is starting to shift.&lt;br /&gt;&lt;br /&gt;I looked at &lt;a href="http://www.w3schools.com/browsers/browsers_stats.asp"&gt;w3schools&lt;/a&gt; (IE6+7 43%, FF 45% in Jan), &lt;a href="http://www.w3counter.com/globalstats.php"&gt;W3Counter&lt;/a&gt; (IE6+7 57%, FF 31%), and stats for our own site :&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_F3uiLYjqK3A/SbKBg5Gbl4I/AAAAAAAAAFA/HFTWEaKWhO0/s1600-h/GAnalytics.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 168px;" src="http://3.bp.blogspot.com/_F3uiLYjqK3A/SbKBg5Gbl4I/AAAAAAAAAFA/HFTWEaKWhO0/s400/GAnalytics.png" alt="" id="BLOGGER_PHOTO_ID_5310449312706828162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And it's undeniable that FireFox is on the rise.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IE8 : Good News&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; * 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1: Supposedly, IE8 is aimed at&lt;a href="http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx"&gt; fixing the rampant IE standards compliance issues&lt;/a&gt; that have been causing web developers so much headache over the past 10 years.  How good is it?  Well.. the latest beta finally passes the ACID 2 test, but &lt;a href="http://www.maximumpc.com/article/features/browser_brouhaha_your_maximum_guide_browsers_today_and_tomorrow?page=0%2C3"&gt;doesn't do too well on ACID 3 (20/100)&lt;/a&gt;.  No browser of Microsoft's has ever scored well on those tests, at least they seem to be trying.&lt;br /&gt;&lt;br /&gt;2: According to &lt;a href="http://tech.slashdot.org/tech/09/03/06/2028231.shtml"&gt;reports by people who spend time trying this kind of stuff out&lt;/a&gt; you will be able to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;uninstall&lt;/span&gt; IE8!  So, I'm *hoping* this means mainstream PC makers, like Dell and HP, will consider taking a few hours to implement a simple interface to let people pick which browser they would like to use when they "setup their computer" the first time it boots.&lt;br /&gt;&lt;br /&gt;I see some argument for including IE with Windows, unlike the justice department.  If there was *no* web browser, then how would people go download FireFox, Chrome, Opera or Safari?  It would be like a network card that doesn't run on Windows &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;XP&lt;/span&gt; native drivers (so you have to download the drivers (1.2MB) on another machine, and grab your thumb drive to get them installed.. /sigh).. but I digress.&lt;br /&gt;&lt;br /&gt;If you gave someone like &lt;a href="http://www.facebook.com/profile.php?id=1094604016"&gt;my Mom&lt;/a&gt; a choice of web browsers, with truthful information about each and let her pick.. would she pick IE?  Probably not.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;WorkXpress&lt;/span&gt; Staff really cares about most : Performance&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We have spent a lot of energy on trying to make the User Experience for both builders and users of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;WorkXpress&lt;/span&gt; as pleasant as possible.  This means neat things like little indicators that AJAX activity is going on inside the Actions interface, on layout load, tab content load, etc.  Some of these wait times are caused by the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;PHP&lt;/span&gt; processing on our end, but a healthy % of it is waiting for your browser to process the Javascript (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;JS&lt;/span&gt;) for the page.&lt;br /&gt;&lt;br /&gt;So, that means that if your PC is fast, and not doing a whole lot other than &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;WorkXpress&lt;/span&gt;, you will have a better experience then if you're also &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;actively&lt;/span&gt; running a lot of other apps.  If your PC is slow, your &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;WorkXpress&lt;/span&gt; experience will be slower; and there's not a lot we can do about it.&lt;br /&gt;&lt;br /&gt;What can *you* do about it, besides upgrading your PC?  Use a browser with a faster Javascript engine!  &lt;a href="http://www.maximumpc.com/article/features/browser_brouhaha_your_maximum_guide_browsers_today_and_tomorrow?page=0%2C6"&gt;An &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_15"&gt;independent&lt;/span&gt; review of the current, and near-release&lt;/a&gt; browsers reveals that FireFox 3.5, Google Chrome. Safari &lt;span style="font-weight: bold;"&gt;and&lt;/span&gt; Opera all have &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;JS&lt;/span&gt; engines that are far faster than &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;IE's&lt;/span&gt;.  Even IE8!&lt;br /&gt;&lt;br /&gt;See, while Microsoft has been struggling to catch up with compliance issues (that the other browsers started off handling properly) the other browser companies have been working on making their &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;JS&lt;/span&gt; engines lean and mean.  We like that; fast &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;JS&lt;/span&gt; means fast pages in general, and it means a faster &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;WorkXpress&lt;/span&gt; experience.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.getfirefox.com/"&gt;Get FireFox&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.google.com/chrome"&gt;Get Chrome&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.opera.com/download/"&gt;Get Opera&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.apple.com/safari/download/"&gt;Get Safari (for Windows)&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-5782680277660020764?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/5782680277660020764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=5782680277660020764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/5782680277660020764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/5782680277660020764'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/03/does-fox-go-on-safari-or-to-opera.html' title='Does a Fox go on Safari, or to the Opera?'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_F3uiLYjqK3A/SbJ_ckowxHI/AAAAAAAAAE4/st8p4QAV2fw/s72-c/Browsers.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-5105337809838850406</id><published>2009-02-11T17:11:00.000-08:00</published><updated>2009-02-11T17:17:47.858-08:00</updated><title type='text'>WorkXpress 2 hits the streets!</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Ladies and gentlemen, I am VERY proud to announce that WorkXpress 2's public release is officially here!  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Check out http://www.workxpress.com; and click on "Sign Up" in the top right corner.  This link will take you to a page that lets you get your User/Account setup and ready to roll.  Then, after a short call and demo with one of our sales folks (Welcome Steve Treglia!) you'll be ready to rock and roll with WorkXpress.&lt;br /&gt;&lt;br /&gt;Over the next few weeks Ill be documenting how to pull a pre-built Application Version off the shelf and use it in an existing, or new Project.  I'll show you how to update the Add/Search areas of the header to meld your existing structure in with the newly imported structure, and Ill cover some of the most recent features added to the Engine.&lt;br /&gt;&lt;br /&gt;I know it's been over a year since I posted here, but I've been locked in a dark room writing code :-)&lt;br /&gt;&lt;br /&gt;Please, check it out and let me know what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-5105337809838850406?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/5105337809838850406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=5105337809838850406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/5105337809838850406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/5105337809838850406'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2009/02/workxpress-2-hits-streets.html' title='WorkXpress 2 hits the streets!'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-3278710570347606292</id><published>2008-01-09T04:41:00.000-08:00</published><updated>2008-01-09T04:58:25.316-08:00</updated><title type='text'>Language Translation and Currency</title><content type='html'>Our newest client continues to demand things we don't yet do with WorkXpress.  This time, it's language translation and currency conversion.&lt;br /&gt;&lt;br /&gt;They are a company that works with people in Europe and so they have a need to know how many Euro's $200 converts into at any given moment (since the exchange rate changes every second), and they need to know what those comments mean that were faxed into them from overseas.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Currency Conversion : Web Services to the rescue!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The problem with telling someone that $200 is 174.78 EUR is that this minute that is true,but th next minute it might be 173.99 EUR.  So, as a programmer the challenge is figuring out how to lookup the rate, in real time.&lt;br /&gt;&lt;br /&gt;Conversion basics :&lt;br /&gt;&lt;br /&gt;1 USD = 0.7544 EUR (Euros) at this moment.&lt;br /&gt;So, if you have USD's, then $rate = 0.7544&lt;br /&gt;&lt;br /&gt;$new_amount = $amount * $rate;&lt;br /&gt;&lt;br /&gt;Simple enough.  Now, for my next trick : I'll find an  accurate place to get the rate!&lt;br /&gt;&lt;br /&gt;You can pay $200 a day for it : &lt;a href="http://www.oanda.com/site/converter-intro/ccc_intro.shtml"&gt;http://www.oanda.com/site/converter-intro/ccc_intro.shtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Or, you can pay $40 a day for it : &lt;a href="http://www.xe.com/sitemap.php"&gt;http://www.xe.com/sitemap.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Or, you can get it for free! : &lt;a href="http://www.webservicex.net/WS/WSDetails.aspx?WSID=10&amp;amp;CATID=2"&gt;http://www.webservicex.net/WS/WSDetails.aspx?WSID=10&amp;amp;CATID=2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All of these are SOAP Web Services, which with one SOAP call will give you the up-to-the-minute currency exchange rate.  But, how good is the free one?&lt;br /&gt;&lt;br /&gt;So, I setup 4 Tabs in Fire Fox.  One that showed the rate of USD to EUR on all 3 of these web services, and the 4th was &lt;a href="http://finance.yahoo.com/currency?u"&gt;Yahoo! Currency Exchange&lt;/a&gt;.  Then, every minute or so, for 15 minutes I hit refresh on all 4 tabs, and compared the rates.  They were the same... across the board!&lt;br /&gt;&lt;br /&gt;So, I decided to use the Free one :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Language Translation : There's got to be a webservice for that, right?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The short answer here is : there used to be!  BabelFish used to provide their translations through web services, but apparently it caused them big load issues, with no benefit ($) to the company.  So, they shut down their web service, which also shut down every other translation web service, since it seems they all actually used babel fish :-)&lt;br /&gt;&lt;br /&gt;So, I had no luck finding an actual web service that did this. I did come across the "&lt;a href="http://googlified.com/2006unofficial-google-translate-api/"&gt;Unofficial Google Translate API&lt;/a&gt;".  Which is a simple post, and screen scrape setup of Google's Beta Translation service.&lt;br /&gt;&lt;br /&gt;So, while not a SOAP Web Service, it does provide real time translation that I was able to integrate into WorkXpress using AJAX.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-3278710570347606292?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/3278710570347606292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=3278710570347606292' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3278710570347606292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/3278710570347606292'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2008/01/language-translation-and-currency.html' title='Language Translation and Currency'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-6410160635672955351</id><published>2007-12-31T07:25:00.000-08:00</published><updated>2007-12-31T07:47:44.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Office'/><title type='text'>Creating a Document with nice Headers and Footers when all you have to work with.. is HTML (A solution found in Word 2007)</title><content type='html'>Our newest client is pushing the limits of our reporting tools.  Our customers, to this point, have been quite happy with either no header/footer (they print on letter head), or one header at the top and one at the bottom of their documents.   And, in fact, all of them have either transmitted their report results via inline email (which means we can use HTML to add Header/Footer, and no one cares about "Pages"), or they have printed their documents (on letter head).  So, headers and footers on each page has never been an issue... until now!&lt;br /&gt;&lt;br /&gt;So, the problem is this : You let your customers enter as little as 1 sentence or as much as 50 pages of text into a rich text area, with formatting, tables, images, etc.  Then, they want to output their fluid body of a document into a template of sorts with headers/footers and better yet, in PDF Format, for emailing to customers!&lt;br /&gt;&lt;br /&gt;Well, HTML doesn't know anything about page breaks, and I don't know about you, but programming to the PDF standard, or even using FPDF is a nightmare I wouldn't wish on any developer, especially not if you want your users to be able to create content, that's later saved in PDF Format. &lt;br /&gt;&lt;br /&gt;I had no luck with the HTML to PDF Converters; they lack CSS support almost completely, don't handle images particularly well, and if an integration package that's supposed to make my life easier has me pulling my hair out after 6 hours working on a simple sample that they provided, I tend to look for alternate solutions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Enter : Microsoft Word 2007.  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tho previous "new releases" of word carried with them only a nicer logo, and 5 new features buried under 30 menus that no one needs any way, it appears that Word 2007 has introduced an actual improvement that will make my job here a lot easier : Open XML.&lt;br /&gt;&lt;br /&gt;See, previously a Word Document was encoded in some way, so generating an actual word document was near impossible; especially for those of us who don't use Microsoft programming languages.  Word did, however, do a nice job of taking my HTML Document (named with .doc on it), and converting it to look just like a Word document when opened in Word.  There were some issues here tho (Save As... "Web Page" ??; and no support for Headers, Footers, Water marks, etc.) which didn't make it much more attractive as a final format.  Meaning it didn't add anything I couldn't already do with just straight HTML.&lt;br /&gt;&lt;br /&gt;Word 2007, however, has changed that landscape quite a bit.  DOCX files (the new, Word 2007 document extension) is now just a .zip file!  Upon unzipping one, you will find the insides quite interesting.  Heavy use of XML, and document relationships which point one XML document to another in the tiered directory structure inside your Word Document.  This structured format is termed &lt;a href="openxmldeveloper.org"&gt;OpenXML&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The prior "mystery encoding" is gone, and we are left with something that humans can understand.. for the most part :-)  The document.xml file (the body of the actual document) still uses XML to describe the body of your document, which would leave me in a position much like writing to fpdf or some other non-html structure.&lt;br /&gt;&lt;br /&gt;So, Treff and I set out trying to figure out how Microsoft could go to an open standard like this, support converting HTML to it's native format (for display inside Word) without allowing us to feed it HTML, embed the HTML inside the docx file in some way.  Were they really that... unhelpful?&lt;br /&gt;&lt;br /&gt;Turns out, the answer is no... they weren't!  It's actually quite easy to take normal HTML, and merge it into a Word Document with Header, Footers and Water marks and these elements stay in tact, while the body of the document changes to what you added to the HTML.  AND... once opened, Word converts this HTML to it's document.xml "Voodoo" syntax, and saves as a normal .docx document, or as a Word 2003/XP format... OR as a PDF!&lt;br /&gt;&lt;br /&gt;It took me a while to get all the pieces to come together, but at this point the process to create a PDF with Headers, Footers and Water mark from HTML input involves :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create your headers/footers/watermark in Word 2007, save as DOCX&lt;/li&gt;&lt;li&gt;Unzip the document&lt;/li&gt;&lt;li&gt;Follow &lt;a href="http://openxmldeveloper.org/forums/2566/ShowThread.aspx#2566"&gt;this example&lt;/a&gt; for adding HTML to it&lt;/li&gt;&lt;li&gt;Save all files, ZIP, change name to .docx.&lt;/li&gt;&lt;li&gt;Open the document in Word&lt;/li&gt;&lt;li&gt;Save as PDF&lt;/li&gt;&lt;/ul&gt;Next step is to work out creating the Header/Footer with HTML Contents, and setting the water mark image.  Then, I can create a Report Output type in WorkXpress that allows the Implementer (IM) to create a Header, a Body, a Footer, and set a Water mark image, click Next, and have a Word .docx download right to their machine!&lt;br /&gt;&lt;br /&gt;If only PDF had an open standard like that, we could skip all the remaining silly steps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-6410160635672955351?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/6410160635672955351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=6410160635672955351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/6410160635672955351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/6410160635672955351'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2007/12/creating-document-with-nice-headers-and.html' title='Creating a Document with nice Headers and Footers when all you have to work with.. is HTML (A solution found in Word 2007)'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-8499699193141931997</id><published>2007-12-28T14:24:00.000-08:00</published><updated>2007-12-28T14:43:03.686-08:00</updated><title type='text'>A Quick Books integration</title><content type='html'>A few days ago I set about trying to figure out how we're going to add Quickbooks integration functionality to WorkXpress, and today I had my first bit of success.&lt;br /&gt;&lt;br /&gt;I've found that the tricky part of developing an "Integration" is almost always figuring out what the other side has to offer.  What does *their* API look like?  How do I connect to their systems?  What 128,000,000,000 bit keys do I need to access their systems, and where do I get them?  Now that I have one.. where do I put it?!?  It goes on and on.&lt;br /&gt;&lt;br /&gt;So what's the first step?  Making a Connection to the third party, in an elementary way.&lt;br /&gt;&lt;br /&gt;The trouble with Quickbooks is that it's on it's 7th SDK revision.  So, the net is covered in a sea of integration examples from all different revisions of Quickbooks connectivity; and I had trouble even figuring out which one would work with the version of quickbooks the client wants to use.&lt;br /&gt;&lt;br /&gt;In the end, it was QuickBooks Enterprise 2007, which meant SDK 7.0.  This version of QuickBooks uses the "Web Connector", or QBWC.&lt;br /&gt;&lt;br /&gt;The Web Connectors role in allowing Quickbooks to be exposed is quite cool.&lt;br /&gt;&lt;br /&gt;Quickbooks, as you know, is a "standalone desktop app".  Which is tech speak for "a program you install, in Windows, that just works."  So, how does a developer connect to this kind of application?  Through the web connector!&lt;br /&gt;&lt;br /&gt;The QBWC is another desktop app that you install on the computer with the QuickBooks company file.  These three things (an install of QuickBooks, QuickBooks Web Connector, and the Company File you want to access) all live on one Windows machine, that becomes the "QuickBooks Server", or the computer with Windows that is always running that always has this quickbooks file open in QB, and the QBWC always running.&lt;br /&gt;&lt;br /&gt;Once I got the QBWC running, it was time to tell it about my application; IE : LET ME IN!  It turns out, instead of providing access to Quickbooks directly, this little gems job is to make SOAP calls out to another server, retrieve work to do, do the work with QBooks, and return the results from the requested work, via SOAP.&lt;br /&gt;&lt;br /&gt;So you don't make "Calls" to Quickbooks really, what you do is you queue up work for Quickbooks to do the next time it connects, which QBWC controls the frequency of.&lt;br /&gt;&lt;br /&gt;You provide QBWC with a username and password to give back to you to authenticate itself, and you have to implement authenticate for your own UName/PW.  There's a series of simple calls that the QBWC makes to get its work, and report back it's progress/completion/response.&lt;br /&gt;&lt;br /&gt;Instead of reinventing the wheel on this side, I found a &lt;a href="http://64.20.43.157/%7Ekeithpalmerjr/PHP%20QuickBooks%20Integration%20Framework.zip"&gt;PHP Framework for Quickbooks&lt;/a&gt; on the &lt;a href="http://idnforums.intuit.com/messageview.aspx?catid=56&amp;amp;threadid=9164&amp;amp;enterthread=y"&gt;Intuit Developers Blog&lt;/a&gt;, developed by Keith Palmer.  Keith went ahead and wrote a MySQL Driven, PHP supported Soap Server that handles receiving communication from QBWC, queueing up tasks to send to QBWC, and sending them when they are requested.&lt;br /&gt;&lt;br /&gt;All you have to do is figure out how you want to store your data for the queue, and implement request and response functions which are the interface between your app (the one making the request)... and your app (the one that you need to effect when there is a response).&lt;br /&gt;&lt;br /&gt;So, he's gone ahead and ripped out all of the tough stuff, and left us with simple implementation, based on what WE need to tell, and listen to, from Quickbooks.  Thanks Keith!&lt;br /&gt;&lt;br /&gt;So.. I modified his examples a little bit, and built myself a page, that queues up an Add Customer request, that will add me, myself and I to the QuickBooks File when the QBWC asks for work.&lt;br /&gt;&lt;br /&gt;Now that I have the simple implementation working, it's time to move on to what the customer actually wants :-)  And, all the while, trying to figure out an elegant way to allow an Implementer to simply create an action, answer some questions, and BOOM, pull data from their QuickBooks installation.&lt;br /&gt;&lt;br /&gt;Chances are pretty good, since we're under the time (as usual) on this project, that I will just implement exactly what's needed for this customer, and worry about circling back and implementing something elegant later.  Once we have one customer integrated with Quickbooks, we can setup similar integrations for any other customer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-8499699193141931997?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/8499699193141931997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=8499699193141931997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/8499699193141931997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/8499699193141931997'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2007/12/quick-books-integration.html' title='A Quick Books integration'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7892073789948849699.post-2091549400239937258</id><published>2007-12-27T08:22:00.000-08:00</published><updated>2007-12-27T10:41:52.348-08:00</updated><title type='text'>What is WorkXpress?</title><content type='html'>&lt;span style="font-size:85%;"&gt;Well, you can check out the marketing version of what WorkXpress is here : &lt;a href="http://www.workxpress.com"&gt;http://www.workxpress.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I can give you the short story here :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Engine&lt;/span&gt;&lt;br /&gt;WorkXpress is an engine for building applications that are served over the web.  It is designed with a high level of usability in mind, so much so that the goal is to allow non-programmers, people who are essentially "really good with Excel", to create sophisticated, totally customized (and customizable) web based applications to run their department, their division, or ultimately their whole company.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Technology&lt;/span&gt;&lt;br /&gt;The technology is based in the open source world of products utilizing PHP, MySQL, Apache on Gentoo Linux based servers.  We use other open source packages such as many PEAR packages and JQuery for javascript.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://www.workxpress.com/technology/building_in_workxpress.php"&gt;How it works&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;The website has a bit about the building blocks on it but I'd like to talk about them from a more.. traditional-programming perspective.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;a href="http://www.workxpress.com/technology/building_in_workxpress.php?selected_section=1"&gt;Items&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;In WorkXpress, we track things.  These things can be grouped into types.  In any CRM Tool people track Contacts and Companies.  These things are types of items, or Item Types.  Each individual Contact or Company is AN item.&lt;br /&gt;&lt;br /&gt;You can think of Item Types like Tables in a traditional database model.  When you're designing a CRM Tool, you decide you will definitely need a 'Contacts' Table, and this table will have columns like "First Name", "Last Name", "Phone Number", etc.&lt;br /&gt;&lt;br /&gt;In WorkXpress, the Table is an Item Type, the Columns are 'Fields', and each Row in the Table, is an Item.&lt;br /&gt;&lt;br /&gt;Item Types's go a few steps further than tables, and start to be more like OO Classes when you add Rules.  If Fields are like Member Variables in your class, then Rules are like Methods.  You can (through a web-based, point and click interface) build simple, or complex methods which are fired when certain events happen.  For instance, there is a set of Rules that fire when an Item of that type is created (like the constructor of a class),  an item of that type is recycled (destructor).   The difference is that the instances of these classes are preserved, saved in the database, so they are available to other users, and they are available the next time you login, etc.  Much like rows in a table.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.workxpress.com/technology/building_in_workxpress.php?selected_section=2"&gt;&lt;span style="font-style: italic;"&gt;Fields&lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;We've already covered Fields a bit, they are simply data stored on an item.  When you create a field, you setup it's parameters like a label, width, max characters, etc.  These options vary greatly based on the type of field you create.  Currently, WorkXpress supports over 40 Field Types, from the familiar and common Text Box, Text Area (Long Text), Check Box, and Select Box to the advanced field types like Date/Time Pickers, Rich Formatted Text (Like a forum post body, blog entry, etc. where you have formatting controls), Item Selectors, File Uploads and Buttons.&lt;br /&gt;&lt;br /&gt;Some field types map directly to INPUT elements, and some are a collection of Javascript and INPUT elements to create a very pleasant user experience using these fields.  The goal here is to make each field type as naturally easy to use, and familiar as a select box.&lt;br /&gt;&lt;br /&gt;&lt;a style="font-style: italic;" href="http://www.workxpress.com/technology/building_in_workxpress.php?selected_section=4"&gt;Layouts&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Stepping out of backend world for a second, every application needs an interface. Some of the elements of the interface are provided by the fields that are created/placed on a page.  The remaining interface elements are provided by a block we call Layouts.&lt;br /&gt;&lt;br /&gt;First, each page in WorkXpress is just that.. a Page Layout.  This Layout has one important job : receive the information about what item we're going to show data for, and draw it's child layouts with that information.&lt;br /&gt;&lt;br /&gt;Inside each Page Layout is a series of other layouts, of varying types.  When a new Item Type is created, an Add Page and a Home Page (or View Page) are both created, a single Field Layout is created, and placed on both the Add and Home Pages.  Then, the first field is created and placed on this Field Layout, giving the implementer a very basic framework to start with. &lt;br /&gt;&lt;br /&gt;So, one major type of Layout is a Field Layout.  This layout.. shows fields and allows those fields to be edited. &lt;br /&gt;&lt;br /&gt;Another major type of Layout is a List Layout, or Related Item List.  This layout shows a list of items that are attached to the item the page is about, via relationships.  The implementer sets up what columns (Fields) are shown about each related item, and the Layout allows new relationships to be added, and existing relationships to be destroyed.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.workxpress.com/technology/building_in_workxpress.php?selected_section=3"&gt;&lt;span style="font-style: italic;"&gt;Relationships&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;Ok, so I have Contacts (Drew, John and Sally), and I have Companies (Express Dynamics, Best Buy) and I want to somehow store the fact that Drew is an Employee of Express Dynamics and John and Sally are employees of Best Buy.  How do I do that?  We have created relationships to track exactly this kind of situation. &lt;br /&gt;&lt;br /&gt;First, you create the Relationship Type.  Much like an Item Type, a Relationship Type describes the kinds of relationships we're going to make.  In this case, we want to Relate Contacts to Companies, and we want a related Comapny to be called an "Employer" and a related Contact to be called an "Employee".  These 4 pieces of info (Item Types on both sides, names on both sides) is all it takes to setup a relationship.&lt;br /&gt;&lt;br /&gt;Second, we create some way to create these relationships.  For this we have 2 constructs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Item Picker&lt;/span&gt;&lt;br /&gt;The Item Picker is a type of field, that allows either 1 or many other items to be selected on an item.  So, if you wanted a field on your Contact that allows you to select this Contact's Employer from the list of all Companies, you would create an Item picker on Contact, that selects Companies.  On the item picker, you can choose a relationship for it to automatically create/maintain as the fields value is changed.  It's important that we create the relationship as well as set the pickers value if we want to access this contacts employer later, through Actions.&lt;br /&gt;&lt;br /&gt;An Item Picker with a value filled in (Employer Field on a Contact) will show the selected item's Name field, with it's Icon as a link to the selected item's Homepage.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The List &lt;/span&gt;(or Related Item List)&lt;br /&gt;As described above, the List is a Type of Layout.  It can be configured to use one or many relationships to show related items, and the implementer gets to pick what columns to show about the related item.  So, in a List Layout one could show not only this Contact's Employer, but also its address, office line, yearly revanue, etc.  Any other fields about Company the Implementer see's fit to show.&lt;br /&gt;&lt;br /&gt;This is highly applicable on the other side, from the Company.  One could show the first and last names, Email Address, Phone Number, Birthdate, etc. of each Employee attached to the Company (which there may be several).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.workxpress.com/technology/building_in_workxpress.php?selected_section=5"&gt;&lt;span style="font-style: italic;"&gt;Actions&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;Actions are programmatic functionality setup to be executed at various specific times while the application is in use.  Actions can be added to Fields, Relationship Types or Item Types.  Fields can have actions before and after saving, and before and after clearing that field.  Relationship Types can have actions before and after creating a relationship of that type, before and after recycling a relationship of that type, and before and after deleting a relationship of that type.  Items has a longer list, some of the highlights include before and after adding an item, updating and item, and recycling an item.  These "times" when actions are executed are called "Events".&lt;br /&gt;&lt;br /&gt;Each action can be configured to run on one or many events.  So if you have something that you want to happen when a user adds a Contact, and anytime that Contact is updated, you can write one action and put it on both events.&lt;br /&gt;&lt;br /&gt;Each action has 3 parts : evaluation, operation on pass, operation on fail.&lt;br /&gt;&lt;br /&gt;Evaluations occur before any action takes place, the if in an if... then... else... type format, the evaluations job is to make sure that this action should run now...&lt;br /&gt;&lt;br /&gt;Operation on pass and fail are the same, they are just the then... and else... parts in an if... then.. else... format.  There are many Operation types that do many types of different things.  They all have point and click interfaces to setup.&lt;br /&gt;&lt;br /&gt;One quick example of an action is the age old "We want to store and sort contacts in a "Last Name, First Name" format.&lt;br /&gt;&lt;br /&gt;No problem.  Add an action on after add and after update with no evaluation.  Make the Pass Operation a "Build String" operation, and begin building your value.  You are presented with a map of information, starting on Contact (since you're writing a Contact Action), which shows all the fields on Contact.  Click Last Name, "Finish", and you've added the first piece of the string.  Then add just a Comma, and lastly choose First name from the map.&lt;br /&gt;&lt;br /&gt;Then, you select a place to store this new string, which will also show a map, starting on Contact.  Select "Contact Name", which is the field responsible for showing the Contact in pickers, and at the top of the homepage, etc.&lt;br /&gt;&lt;br /&gt;You can also use actions to grab values from items through relationships.  Let's say you have an "Employer Address" field on Contact.  This field is supposed to show this Contacts, Employers, Address field.  No Problem!  Add an action, and use the map to navigate from Contact, across to Company through Employee -&gt; Employer, and select the Address Field.  Choose the local (Contact) "Employers Address" field, and save.&lt;br /&gt;&lt;br /&gt;More on Items, Fields, Layouts, Actions and Relationships soon!  Stay tuned!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7892073789948849699-2091549400239937258?l=workxpress.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://workxpress.blogspot.com/feeds/2091549400239937258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7892073789948849699&amp;postID=2091549400239937258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2091549400239937258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7892073789948849699/posts/default/2091549400239937258'/><link rel='alternate' type='text/html' href='http://workxpress.blogspot.com/2007/12/what-is-workxpress.html' title='What is WorkXpress?'/><author><name>Drew "Druman" McLain</name><uri>http://www.blogger.com/profile/14733744802162296120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
