<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Edward A. Webb (.com) &#187; web development</title>
	<atom:link href="http://edwardawebb.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://edwardawebb.com</link>
	<description>get all his digital goodness 24/7</description>
	<lastBuildDate>Sat, 28 Jan 2012 17:46:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Authenticate Facebook Users in MOdx, and Build a User Profile</title>
		<link>http://edwardawebb.com/web-development/facebook-login-modx-sites</link>
		<comments>http://edwardawebb.com/web-development/facebook-login-modx-sites#comments</comments>
		<pubDate>Thu, 12 May 2011 23:31:07 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[modx]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=939</guid>
		<description><![CDATA[ I've used Facebook's API before, and know it makes authentication pretty easy, but I had to figure out to insert that authorized user into Modx's web context.  And it was actually quite easy as well.

The user becomes a full blown member, and can be treated the same as any user that registered. (you can also treat them differently)

Read on to learn how two simple snippets allow Facebooks users to add themselves to your site in the provided member groups.

The extra also <strong>creates a full user profile in modx based on Facebook</strong>'s info, complete with:
<ul>
	<li>Name</li>
	<li>Username</li>
	<li>Email</li>
	<li>Hometown</li>
	<li>Photo</li>
</ul><!--more-->
]]></description>
			<content:encoded><![CDATA[<p>Although still very new, and with much to learn I am loving Modx as a tool to quickly build out robust sites.</p>
<p>Recently <strong>a client wanted to add Facebook Integration to their MODx site</strong>.   I&#8217;ve used Facebook&#8217;s API before, and know it makes authentication pretty easy, but I had to figure out to insert that authorized user into Modx&#8217;s web context.  And it was actually quite easy as well.</p>
<p>The user becomes a full blown member, and can be treated the same as any user that registered. (you can also treat them differently)</p>
<p>Read on to learn how two simple snippets allow Facebooks users to add themselves to your site in the provided member groups.</p>
<p>The extra also <strong>creates a full user profile in modx based on Facebook</strong>&#8216;s info, complete with:</p>
<ul>
<li>Name</li>
<li>Username</li>
<li>Email</li>
<li>Hometown</li>
<li>Photo</li>
</ul>
<p><span id="more-939"></span></p>
<p>Finally, in case you want to add more social features using their Javascript API we make the appID and session available to the front end using placeholders.</p>
<h3>Important:You Must Have Basic Login working using Login</h3>
<p><strong>This article assumes you already have basic authentication working for your users using <a href="http://rtfm.modx.com/display/ADDON/login" rel="nofollow" title="Login Extra for Modx"  target="_blank">Shaun and Jason&#8217;s<em>Login</em> extra</a>.   They also has great docs, so I&#8217;ll spare you.</strong></p>
<p><em>But, </em>I strongly suggest 3 things:</p>
<ol>
<li>A dedicated Login/Logout page</li>
<li>A Login Link that shows to unknown users that simply links to the dedicated page &lt;a href=&#8221;[[~29]]&#8221;&gt;Login&lt;/a&gt;</li>
<li>A Logout link shown to authenticated users that links to the same page, but specifies logout.<br />
&lt;a href=&#8221;[[~29? &#038;service=`logout`]]&#8221;&gt;Logout&lt;/a&gt;</li>
</ol>
<p><a href="http://rtfm.modx.com/display/ADDON/If" rel="nofollow" >Shaun&#8217;s IF extra </a>is a great way to manage that choir:</p>
<h4>LoginChunk used on all pages</h4>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div id=&quot;login-bar&quot;&gt;
&nbsp;
[[!If?
   &amp;subject=`[[+modx.user.id]]`
   &amp;operator=`empty`
&nbsp;
   &amp;then=`&lt;!-- we dont know who the user is, show login and register links --&gt;
      &lt;a href=&quot;[[~29]]&quot;&gt;Login&lt;/a&gt;, 
    &lt;a href=&quot;[[~27]]&quot;/&gt;Register&lt;/a&gt;
    `
&amp;else=`&lt;!-- well hello old friend, show the known user his profile link, etc --&gt;
	[[!Profile]]		
        Welcome Back, &lt;a href=&quot;/users/my-profile.html&quot;&gt;[[+modx.user.username]]&lt;/a&gt;  | 
        &lt;a href=&quot;[[~29? &amp;service=`logout`]]&quot; title=&quot;Logout&quot;&gt;Logout&lt;/a&gt;
`
]]
&nbsp;
&nbsp;
&nbsp;
&lt;/div&gt;</pre></div></div>

<p>&nbsp;<br />
Once you&#8217;re all setup and working with that, read on.<br />
&nbsp;</p>
<h3>Facebook API</h3>
<p>You&#8217;ll want to visit <a href="http://developer.facebook.com" rel="nofollow"  target="_blank">Facebook&#8217;s developer site</a> and get yourself and application ID.  They have great documentation, so I wont regurgitate it.</p>
<p>While you are there, be sure to grab the <a href="https://github.com/facebook/php-sdk/" rel="nofollow" title="PHP Client Library for Facebook"  target="_blank">PHP Client</a> they provide. ( you can save a step by using wget from your server to download the <a href="https://github.com/facebook/php-sdk/tarball/master" rel="nofollow"  target="_blank">sdk tarball</a> as well)</p>
<p>Now that facebook nows about your app, and you have an application ID and secret we can add our 2 snippets to MOdx, and upload the PHP Client and Certificate.<br />
<a name="appId">&nbsp;</a><br />
<strong>Note</strong>: Once you have created the two snippets below, you will need to provide them to <em>both </em>snippets as default properties.<br />
<div id="attachment_953" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2011/05/Capture2.png"><img src="http://edwardawebb.com/wp-content/uploads/2011/05/Capture2-300x170.png" alt="Capture2 300x170 Authenticate Facebook Users in MOdx, and Build a User Profile" title="appId and secret" width="300" height="170" class="size-medium wp-image-953" /></a><p class="wp-caption-text">Edit the snippets, click &quot;Properties&quot; &gt; &quot;Unlock Default Properties&quot; and then add the two values &quot;appId&quot; and &quot;secret&quot;</p></div></p>
<h4>Upload the facebook client</h4>
<p>I chose to put the php class under <em>core/components/facebookLogin/</em> , and reccomend you do as well, because I plan to release all this as an extra very soon. (and that will keep the transition smooth)</p>
<p>You can use the file explorer to create the folder, but MOdx wont let you upload the PHP file. So you will need to ftp the file to the server or use wget right from the server. But in the end you need this, a directory with Facebook.php and fb_ca_chain_bundle.crt.  We will call the facebook.php file in later steps.</p>
<p><a href="http://edwardawebb.com/wp-content/uploads/2011/05/Capture.png"><img class="aligncenter size-medium wp-image-942" title="Modx_facebook_files" src="http://edwardawebb.com/wp-content/uploads/2011/05/Capture-208x300.png" alt="Capture 208x300 Authenticate Facebook Users in MOdx, and Build a User Profile" width="208" height="300" /></a></p>
<p>&nbsp;</p>
<h3>Creating the facebookLogin snippet for Modx</h3>
<p>&nbsp;<br />
First add a new category named facebookLogin (again, keeps life easy), and write two new snippets, facebookLogin, and facebookLogout.</p>
<p><a href="http://edwardawebb.com/wp-content/uploads/2011/05/Capture1.png"><img src="http://edwardawebb.com/wp-content/uploads/2011/05/Capture1.png" alt="Capture1 Authenticate Facebook Users in MOdx, and Build a User Profile" title="modx_facebook_snippets" width="199" height="195" class="aligncenter size-full wp-image-943" /></a></p>
<p>The Login  snippet outputs the Connect With Faceboook button, so you can just include it in the above code, right next to the login link. </p>
<h4>Updated LoginChunk used on all pages</h4>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[[!If?
   &amp;subject=`[[+modx.user.id]]`
   &amp;operator=`empty`
&nbsp;
   &amp;then=`&lt;!-- we dont know who the user is, show login and register links --&gt;
      &lt;a href=&quot;[[~29]]&quot;&gt;Login&lt;/a&gt;, 
    &lt;a href=&quot;[[~27]]&quot;/&gt;Register&lt;/a&gt;
    [[!facebookLogin? &amp;userGroups=`Members`]]
    `
&amp;else=`&lt;!-- well hello old friend, show the known user his profile link, etc --&gt;
	[[!Profile]]		
        Welcome Back, &lt;a href=&quot;/users/my-profile.html&quot;&gt;[[+modx.user.username]]&lt;/a&gt;  | 
        &lt;a href=&quot;[[~29? &amp;service=`logout`]]&quot; title=&quot;Logout&quot;&gt;Logout&lt;/a&gt;
`
]]</pre></div></div>

<p>(Note: The extra will eventually use a chunk as a template to allow you to customize the text or image shown easily, this is more aligned with Modx&#8217;s recommended architecture as well, so bonus if you just implement that from the get go.)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
  *FacebookLogin Snippet for Modx
  * FacebookLogin is free software; you can redistribute it and/or modify it
 * under the terms of the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * FacebookLogin is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; for more details.
 *
 * You should have received a copy of the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; along with
 * FacebookLogin; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
*/</span>
<span style="color: #009933; font-style: italic;">/**
&nbsp;
A substantial chunk of Jason Coward's and Shaun McCormick's Login snippet was used, and noted in the code below
&nbsp;
*/</span>
<span style="color: #009933; font-style: italic;">/**
 * Login
 *
 * Copyright 2010 by Jason Coward &lt;jason@modx.com&gt; and Shaun McCormick
 * &lt;shaun@modx.com&gt;
 *
 * Login is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * Login is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * Login; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'core_path'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'components/facebookLogin/facebook.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//what permissions do we want</span>
<span style="color: #000088;">$par</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$par</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'req_perms'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;email,user_hometown,user_website&quot;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">//</span>
<span style="color: #666666; font-style: italic;">// Where do these come from? Add them as Properties to the snippet!</span>
<span style="color: #666666; font-style: italic;">//</span>
<span style="color: #000088;">$appId</span><span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'appId'</span><span style="color: #339933;">,</span><span style="color: #000088;">$scriptProperties</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$secret</span><span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'secret'</span><span style="color: #339933;">,</span><span style="color: #000088;">$scriptProperties</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$appId</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$secret</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$output</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'No AppID or Secret Provided, please obtain from developer.facebook.com'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">// Create our Application instance.</span>
<span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'appId'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$appId</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'secret'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$secret</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'cookie'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$session</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">/*
* Make the appID and current session available to the front end 
* (in case you want to add more social features using Javascript, specify those in the init() call)
*/</span>
<span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toPlaceholder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook_session'</span><span style="color: #339933;">,</span><span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$session</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toPlaceholder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook_app_id'</span><span style="color: #339933;">,</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAppId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$output</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$me</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Session based API call.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$session</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$uid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$me</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/me'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>FacebookApiException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">error_log</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// login or logout url will be needed depending on current user state.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//die(print_r($me));</span>
&nbsp;
	<span style="color: #000088;">$contexts</span> <span style="color: #339933;">=</span> <span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contexts</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">context</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'key'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$contexts</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contexts</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$ctxKey</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$contexts</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$ctxKey</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contexts</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$ctxKey</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUser'</span><span style="color: #339933;">,</span>  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'remote_key:='</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'remote_key:!='</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	    	<span style="color: #666666; font-style: italic;">//their new!</span>
		<span style="color: #666666; font-style: italic;">//facebook may pass multiple hometowns back</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hometown'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hometown'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			   <span style="color: #000088;">$homet</span><span style="color: #339933;">=</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hometown'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
       			   <span style="color: #000088;">$homet</span><span style="color: #339933;">=</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hometown'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
	  	<span style="color: #666666; font-style: italic;">// Create an empty modx user and populate with facebvook data</span>
		<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">newObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUser'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fromArray</span><span style="color: #009900;">&#40;</span>
                          <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'username'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'active'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span>
		                <span style="color: #339933;">,</span><span style="color: #0000ff;">'remote_key'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">,</span><span style="color: #0000ff;">'remote_data'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$me</span> <span style="color: #666666; font-style: italic;">//store the remote data as json object in db (in case you need more info bout the FB user later)</span>
		             <span style="color: #009900;">&#41;</span>
                   <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//We'll also toss a profile on to save their email and photo and such</span>
		<span style="color: #000088;">$profile</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">newObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUserProfile'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$profile</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fromArray</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'email'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'facebook-user@facebook.com'</span>
		<span style="color: #339933;">,</span><span style="color: #0000ff;">'fullname'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span>
		<span style="color: #339933;">,</span><span style="color: #0000ff;">'city'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$homet</span>
                <span style="color: #339933;">,</span><span style="color: #0000ff;">'photo'</span><span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'http://graph.facebook.com/'</span><span style="color: #339933;">.</span> <span style="color: #000088;">$me</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span><span style="color: #0000ff;">'/picture'</span>
		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOne</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$profile</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Profile'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #009933; font-style: italic;">/** Login, (C) 2010, Jason Coward, Shaun McCormick**/</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* if usergroups set */</span>
		<span style="color: #000088;">$usergroups</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'usergroups'</span><span style="color: #339933;">,</span><span style="color: #000088;">$scriptProperties</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$usergroups</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		    <span style="color: #000088;">$usergroups</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span><span style="color: #000088;">$usergroups</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$usergroups</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$usergroupMeta</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span><span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">/* get usergroup */</span>
			<span style="color: #000088;">$pk</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$pk</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span> ? <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$usergroup</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUserGroup'</span><span style="color: #339933;">,</span><span style="color: #000088;">$pk</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$usergroup</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">/* get role */</span>
			<span style="color: #000088;">$rolePk</span> <span style="color: #339933;">=</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$usergroupMeta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'Member'</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$role</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUserGroupRole'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$rolePk</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">/* create membership */</span>
			<span style="color: #000088;">$member</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">newObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modUserGroupMember'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$member</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'member'</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$member</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user_group'</span><span style="color: #339933;">,</span><span style="color: #000088;">$usergroup</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$role</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			    <span style="color: #000088;">$member</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'role'</span><span style="color: #339933;">,</span><span style="color: #000088;">$role</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			    <span style="color: #000088;">$member</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'role'</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addMany</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$member</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'UserGroupMembers'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		    <span style="color: #009900;">&#125;</span><span style="color: #666666; font-style: italic;">//end foreach</span>
		<span style="color: #009900;">&#125;</span><span style="color: #666666; font-style: italic;">//end user grops</span>
<span style="color: #009933; font-style: italic;">/** End Login Code Block froom Login, (C) 2010 Jason Coward, Shaun McCormick **/</span>
		<span style="color: #000088;">$saved</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #666666; font-style: italic;">//end if new user</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//new or not, they're logged in</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasSessionContext</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'web'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	   <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$contexts</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$context</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addSessionContext</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$context</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	   <span style="color: #009900;">&#125;</span>
&nbsp;
	   <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//else give them the chance to login</span>
<span style="color: #666666; font-style: italic;">/* This should parse the generated URL with a chunk, for now you can edit the image or text here */</span>
  	<span style="color: #000088;">$output</span><span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLoginUrl</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$par</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;&lt;img src=&quot;http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif&quot;&gt;&lt;/a&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now just call that snippet, with the optional attribute of &#8220;userGroups&#8221; to add group membership for new users. That attribute, like Login&#8217;s accepts a comma separated list of groups.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[[!facebookLogin? &amp;usergroups=`Members`]]</pre></div></div>

<p><strong>Well there you have it, users can now authenticate against facebook, and if they grant permissions, MODX will be able to add them as a new user complete with email, photo and hometown</strong>.</p>
<p>..Oh what&#8217;s that?  You want them to be able to logout too.  OK, ok..</p>
<h4> facebookLogout <em>hook</em> for Modx&#8217;s Login Extra</h4>
<p>The login code above adds the Facebook user as a fully fledged user. SO if you have Jason and Shaun&#8217;s Login extra working properly they should see a logout link.  But what happens when you click it? </p>
<blockquote><p>Modx says <em>Logout</em>!, Done. Redirect to whatever page. Facebook extra says <em>Hey! i know you welcome back</em>, and adds user back into the current context.</p></blockquote>
<p> So unless we also tell Facebook that the user is logging out, they will never be able to logout again! Oh my..</p>
<p>So the solution is use the facebookLogout snippet as a post hook. This allows MOdx and facebook to work in tandem. </p>
<blockquote><p>Modx says <em>Logout</em>!, Done. Redirect <em>to Facebook&#8217;s logout URL</em>. Facebook kills authentication session, sends back to whatever page. Facebook extra still checks, but can not load the previous session</p></blockquote>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
  *FacebookLogin Snippet for Modx
  * FacebookLogin is free software; you can redistribute it and/or modify it
 * under the terms of the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * FacebookLogin is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; for more details.
 *
 * You should have received a copy of the &lt;a href=&quot;www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License&lt;/a&gt; along with
 * FacebookLogin; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Login doesn't provide separate hook calls for logging or logging out, so we check..</span>
<span style="color: #000088;">$islogout</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'logoutResourceId'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$hook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValues</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$islogout</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'core_path'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'components/facebookLogin/facebook.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//</span>
<span style="color: #666666; font-style: italic;">// Where do these come from? Add them as Properties to the snippet!</span>
<span style="color: #666666; font-style: italic;">//</span>
<span style="color: #000088;">$appId</span><span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'appId'</span><span style="color: #339933;">,</span><span style="color: #000088;">$scriptProperties</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$secret</span><span style="color: #339933;">=</span> <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'secret'</span><span style="color: #339933;">,</span><span style="color: #000088;">$scriptProperties</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create our Application instance.</span>
<span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'appId'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$appID</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'secret'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$secret</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'cookie'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$session</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toPlaceholder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook_session'</span><span style="color: #339933;">,</span><span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$session</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toPlaceholder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'facebook_app_id'</span><span style="color: #339933;">,</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAppId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #000088;">$me</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Session based API call.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$session</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$uid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$me</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/me'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>FacebookApiException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">error_log</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$me</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">//we are logging out but facebook is still logged in, kill session</span>
     <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLogoutUrl</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
 <span style="color: #666666; font-style: italic;">// they are logging out, but not FB user, do nothing</span>
&nbsp;
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//just logging in</span>
       <span style="color: #000088;">$modx</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/users'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>SO how do we call that code?  Remember you&#8217;re dedicated Login/Logout page?</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[[!Login? &amp;tplType=`modChunk` &amp;loginTpl=`lgnLoginTpl`]]</pre></div></div>

<p> Just add the logout snippet as a posthook</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[[!Login? &amp;tplType=`modChunk` &amp;loginTpl=`lgnLoginTpl` &amp;postHooks=`facebookLogout`]]</pre></div></div>

<blockquote><p>That&#8217;s everything I think.  As I said I am still new to MOdx, and have much to learn, so don&#8217;t hold back on the input.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/facebook-login-modx-sites/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Will MODx Revolution bring about change?</title>
		<link>http://edwardawebb.com/web-development/modx-revolution-bring-change</link>
		<comments>http://edwardawebb.com/web-development/modx-revolution-bring-change#comments</comments>
		<pubDate>Tue, 05 Apr 2011 02:18:55 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[modx]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=914</guid>
		<description><![CDATA[Somewhere between CMS and Scaffolding Framework
MODx is a PHP based, mm.. tool, for publishing websites.  I don't want to call it a CMS, though If you read MODx documentation, they'll call it a Content Management System.  But in my experience products labeled CMS tend to be inflexible tools that require lots of effort to place widgets on custom templates.  I remember using one tool in which you could not have a publicly accessible page not belong to a menu. We ended up building a hidden menu for all such pages - absurd!

At the other end of the spectrum are highly flexible frameworks. These are much more flexible, and let you run wild, but leave a good chunk of work to setup decent content management, authorization, etc. before you even get to the site at hand.

Well MODx sit nicely between a CMS and a framework in my opinion. You get user management, admin panel, powerful configuration, etc.  But you are not forced into any mold.  In face the default install (without sample content) is literally an empty page :o !  Uncomfortable at first,  but once you spend a few hours with it you begin to live the freedom.   It is intended for sites that are heavy content focused, but provides full CRUD application abilities as well.  ]]></description>
			<content:encoded><![CDATA[<h3>Somewhere between CMS and Scaffolding Framework</h3>
<p>MODx is a PHP based, mm.. tool, for publishing websites.  I don&#8217;t want to call it a CMS, though If you read <a href="http://modx.com/" rel="nofollow" >MODx</a> documentation, they&#8217;ll call it a Content Management System.  But in my experience products labeled CMS tend to be inflexible tools that require lots of effort to place widgets on custom templates.  I remember using one tool in which you could not have a publicly accessible page not belong to a menu. We ended up building a hidden menu for all such pages &#8211; absurd!</p>
<p>At the other end of the spectrum are highly flexible frameworks. These are much more flexible, and let you run wild, but leave a good chunk of work to setup decent content management, authorization, etc. before you even get to the site at hand.</p>
<p>Well MODx sit nicely between a CMS and a framework in my opinion. You get user management, admin panel, powerful configuration, etc.  But you are not forced into any mold.  In face the default install (without sample content) is literally an empty page!  Uncomfortable at first,  but once you spend a few hours with it you begin to love the freedom.   It is intended for sites that are heavy content focused, but provides full CRUD application abilities as well.</p>
<h3><span id="more-914"></span>Experience</h3>
<p>I&#8217;ll admit I&#8217;m speaking from limited experience, having only published three sites using MODx Revolution. I used MODx (Evolution), this version&#8217;s rougher predecessor, a few years back and thought, &#8220;meh.&#8221;  I have also published sites using drupal, joomla, cakephp, wordpress, and concrete5cms. I have varying opinions of all these tools, but have learned what I like, and what annoys me.</p>
<p>&nbsp;</p>
<h3>First Thoughts</h3>
<p>I&#8217;m impressed.  I&#8217;ll admit the first site I tried to publish I really struggled, mostly because I stubbornly refused to spend more then 5 minutes <a href="http://rtfm.modx.com" rel="nofollow" title="Read the Manual"  target="_blank">reading the manual</a> before diving in.  By the second site though my attitude changed. The ability to start with mockups and publish a flexible and robust app is intuitive and powerful.  Great flexibility is retained while a full package,user, setting management package is provided for you and site maintainers.</p>
<p>&nbsp;</p>
<h3>Learn Another Templating Language ? &#8211; No Need</h3>
<p>OK, new framework/CMS, get ready to learn a new set of rules for configuring the various files needed to make your template with css and scripts right? <strong>Not at all.  MODx lets you start with pure HTML, including doc declaration tags and head element.</strong> You can(and should) then segement pieces of the template into <em>chunks</em>.  Various templates can share chunks and likewise the opposite.Your <em>blog</em> pages can look radically different, or identical to your <em>support</em> pages, but share the same header, modules, etc.  It is basically an &lt;include&gt; statement. So each chunk is just more html.  The result is a pure HTML based template, that is clean to maintain.</p>
<p>Think of the power here!</p>
<ul>
<li>Take HTML/CSS mockup directly from your designer</li>
<li>Apply the template to some or all of your content</li>
<li> No new languages needed</li>
</ul>
<p>&nbsp;</p>
<h3>Letting &#8220;users&#8221; add special content (meta data)</h3>
<p>OK, that seems dandy, but the problem with such an open and free model is that if a user wants to include some special content or script I have to let them hack at the base template?!  Well that would be crazy! Instead <strong>the concept of Template Variables (TVs) allow you to extend that idea of &lt;include&gt; to content</strong>.  You specify placeholders in the template or chunk, and the user can fill out additional fields in the content manager.   This allows meta data, widgets, or anything else you want at presentation time to be added to content easily.</p>
<p>[[+fieldUserAdded]]</p>
<h3>And what about more powerful features, I want to code!</h3>
<p>If you need more then static content then MODx will not disappoint. The concepts of <em>snippets</em> allows PHP code  and libraries to be included with ease.  Some snippets are very simple, say display the current time formated in the locale style.  Other snippets are just the interface for more elaborate solutions spanning many files.  Snippets except named arguments and will print to screen any output from the code.</p>
<pre>[[!SayHello? &amp;name=`mike`]]</pre>
<p>in your document,chunk, or template, AND</p>
<pre>&lt;?php
echo "Well, Hello There " . $name . "!";
?&gt;</pre>
<p>As a <em>snippet</em> would result in:</p>
<p>Well, Hello There mike!</p>
<h3>And what about plugins?</h3>
<p>You&#8217;ll need contact forms and comment widgets and polling solutions and &#8230;.</p>
<p>Well, sort of..  Most solutions you&#8217;ll leverage are packaged <em>snippets</em>.  <a href="http://rtfm.modx.com/display/ADDON/FormIt" rel="nofollow" title="Form Handling in MODx"  target="_blank">FormIt</a> for example will take post data, perform validation, send email, etc.  But you still get to design whatever form you want, as long as the form&#8217;s action is a page that calls the appropriate FormIt snippet.  <a href="http://rtfm.modx.com/display/ADDON/Quip" rel="nofollow"  target="_blank">Quip</a> is a full solution for comment management, adding the snippet to any page will attach comments to that resource.</p>
<p>There is also add-ons for handling searches,  listing content summaries, and data access.</p>
<p>&nbsp;</p>
<h3>What Else?</h3>
<p>Oh Man! there are so many more <a href="http://modx.com/revolution/product/features/" rel="nofollow" >features in MODx Revolution</a> including message queues, internationalization, logging, acl based authorization, and xPDO, an easy ORM api for custom and system objects.</p>
<p>.</p>
<p>I plan to add the (little) code from my recent site, to help illustrate the points above. Meanwhile let me know if you have thoughts.</p>
<p>If you need a new site including custom development then MODx is a great solution. There is strong documentation, clean architecture, and fast results.</p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/modx-revolution-bring-change/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Custom JSF Input Validation Styling for any Component</title>
		<link>http://edwardawebb.com/web-development/custom-jsf-input-validation-styling-component</link>
		<comments>http://edwardawebb.com/web-development/custom-jsf-input-validation-styling-component#comments</comments>
		<pubDate>Fri, 29 Oct 2010 22:49:59 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[style]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=863</guid>
		<description><![CDATA[We didn&#8217;t have room on our pages for individual message boxes, and also had the need to style specific fields on our JSF pages whenever validation failed on the server, with user friendly field names in the message. Example:  &#8221;User Name is Required&#8221; , and the field for User Name is highlighted red. Unfortunately there are [...]]]></description>
			<content:encoded><![CDATA[<p>We didn&#8217;t have room on our pages for individual message boxes, and also had the need to <strong>style specific fields on our JSF pages whenever validation failed on the server,</strong> with <strong>user friendly field names in the message. </strong></p>
<p>Example:  &#8221;User Name is Required&#8221; , and the field for User Name is highlighted red.</p>
<div id="attachment_864" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2010/10/jsf_jquery_validation.png"><img class="size-medium wp-image-864" title="jsf_jquery_validation" src="http://edwardawebb.com/wp-content/uploads/2010/10/jsf_jquery_validation-300x68.png" alt="jsf jquery validation 300x68 Custom JSF Input Validation Styling for any Component" width="300" height="68" /></a><p class="wp-caption-text">Custom field styling and nicer field names for JSF validation</p></div>
<p>Unfortunately there are times when jsf insists on inserting field ids into the message.</p>
<h3>Here&#8217;s the scenario;</h3>
<ul>
<li>If any jsf converter validation fails (like a string in an int field) JSF will throw a warning like &#8220;jid17:jid34: Values must be type numeric&#8221; &#8211; The form id and page id prepend any internal messages &#8211; gross.</li>
<li>If any page custom validation fails (like min and max lengths) JSF will throw our custom message</li>
<li>If custom validators fail(like the format of a zip code based on the province as US or CA) throw  a custom message</li>
<li>If any DB rule issues fail (like name in use by other user) then our Manager throws a custom message (but it is not hooked to any component)</li>
</ul>
<p>The troubles is that without overriding JSF components or classes we do not have access to the component when every message is thrown, and would be unable to change its style class.</p>
<p>Rather than relying on some tricky JSF or Java code to intercept and update classes I decided to take a simpler approach (or so I think).  <strong>Using jQuery, the preprendId=&#8221;false&#8221; attribute, and specific Messages for every field we can do ANY custimaztion we want to ANY failed field, input, checkbox, etc on the page.</strong></p>
<p><span id="more-863"></span></p>
<h2>Here&#8217;s the Solution</h2>
<p>There is actually a few pieces to the puzzle, but all very simple.</p>
<ul>
<li>Set prependId=&#8221;false&#8221; on the &lt;h:form&gt; elements of your page (optional  but must be consistent for all forms that will use this validation)</li>
<li>Give your fields User Friendly names (well sort of, we use JQuery to replace any &#8220;_&#8221; with spaces )</li>
<li>If your ever throwing a custom message, prepend the user friendly(almost) id to your message (we use jquery to strip it off)</li>
<li>Give your &lt;h:messages /&gt; element a specific ID.</li>
<li>Insert The jQuery client side fixer upper and styl-o-matic to your template. (its like 5 lines)</li>
</ul>
<h2>Hiding the default form ID in JSF</h2>
<p>This is something you will only want to do if all forms can be treated equally in your code elsewhere. Other the id may be important. If you want to leave the form ID in tact, skip this section. But you will need to modify the steps below to accomidate</p>
<p>Hiding the form&#8217;s id is simple, just insert the attrinute prependID=&#8221;false&#8221; in your forms.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h:form prependId=&quot;false&quot;&gt;
... components, etc...
&lt;/h:form&gt;</pre></div></div>

<h2>Giving JSF Components User Friendly field names that include spaces</h2>
<p>By the law of html element ids must be alphanumeric, no spaces. So when you name a field &#8220;frstNme&#8221; in JSF, there&#8217;s a good chance a user will see it on some failed validation at some point.</p>
<p>To compensate, give all your fields nice names that would be pleasant to users, if only for spaces.  &#8220;First_Name&#8221; is prettier, but not what the user will see. The jQuery code replaces all underscores with spaces, so the user would see &#8220;First Name&#8230;.&#8221;  You could also user hypens.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h:inputText id=&quot;First_Name&quot; value=&quot;#{bean.firstName}&quot; required=&quot;true&quot;
requiredMessage=&quot;First_Name:is required&quot; 
size=&quot;19&quot;&gt;
&lt;/h:inputText&gt;</pre></div></div>

<h2>Include field names when passing custom messages from Java code</h2>
<p>This one seems weird, but allows for the most consistency aligning our custom messages with JSF&#8217;s defaults.</p>
<p>In my managers I throw messages like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> saveUserAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
	 ...
	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>searchString.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&gt;</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		addMessage<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;First_Name:Must be between 2 and 16 characters&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	...
	<span style="color: #000000; font-weight: bold;">return</span> navString<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> addMessage<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> messageStr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	FacesMessage message <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FacesMessage<span style="color: #009900;">&#40;</span> messageStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	FacesContext.<span style="color: #006633;">getCurrentInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;errorTag&quot;</span>, message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Give your Message components a specific ID</h2>
<p>All pages that you want to apply this to should have a message element like;</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h:messages id=&quot;messageList&quot; /&gt;</pre></div></div>

<p>We will need that so jQuery knows where to looks for messages.</p>
<h2>jQuery code to cleanup JSF messages and apply field level styling</h2>
<p>The jQuery snippet (well plain JS too) is where this all comes together.   We iterate through all the
<li> elements in the
<ul> element with our messages ID.  Each list item may be a field message, and have the format &#8220;field_name:message to show user&#8221;. We check for a colon, and if present split on that as a delimiter, getting an id in the first bucket, and the message in the second. We can then apply styling to a field matching that id before finally fixing the ID to contain spaces, and showing the complete message to user.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#messageList li'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// for each li in ul </span>
        <span style="color: #003366; font-weight: bold;">var</span> id<span style="color: #339933;">=</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// split on colon</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>id.<span style="color: #660066;">length</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// if field id was present, go to work</span>
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'color'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'red'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//make faulted field fonts red</span>
                $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'border-color'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'red'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// make faulted fields border red</span>
                id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/_/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// replace any &quot;_&quot; with spaces</span>
                $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> id<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// make new message the nicer way</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>What if I can&#8217;t use prependID=&#8221;false&#8221; ?</h2>
<p>IF you can&#8217;t or do not want to use that attribute, make the following changes:<br />
*Prepend the form&#8217;s Id to your messages (ex: &#8220;jidt23:First_Name:Message to user&#8221;)<br />
*Adjust jQuery to use buckets 1 and 2 sperated by a colon for the field id (jidt23:First_Name), and then discard 1, run replace on 2,  and show 2 and 3 as the message (First Name is required).</p>
<h2>Summary</h2>
<p>That&#8217;s it!  it turned out to be quite simple, and we were able to refactor our existing application of about 25 pages (cleaning up field ids and error messages)  is less than 2 hours.</p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/custom-jsf-input-validation-styling-component/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>A complex data model with JPA &#8211; Inheritance, Stateful Join Tables, and More</title>
		<link>http://edwardawebb.com/web-development/complex-data-model-jpa-inheritance-stateful-join-tables</link>
		<comments>http://edwardawebb.com/web-development/complex-data-model-jpa-inheritance-stateful-join-tables#comments</comments>
		<pubDate>Mon, 13 Sep 2010 23:30:54 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=839</guid>
		<description><![CDATA[I&#8217;ve had the recent pleasure/pain of implementing JPA  a new Java web application. After reading many misleading blog posts and dead-end mailing list threads I have worked out the major kinks, and thought I would share. A few things first: This not using Hibernate API, or the Hibernate implementation of Java Persistence API The project [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had the recent pleasure/pain of implementing JPA  a new Java web application. After reading many misleading blog posts and dead-end mailing list threads I have worked out the major kinks, and thought I would share.</p>
<p>A few things first:</p>
<ul>
<li>This not using Hibernate API, or the Hibernate implementation of Java Persistence API</li>
<li>The project runs on Websphere 6.1 (WAS6.1), using OpenJPA implemenation of JPA 1</li>
<li>Although our application is new, the data model is fixed as it must align with the enterprises larger customer focused data model.</li>
<li>I&#8217;m not saying anything contained herein is correct, but it works.</li>
</ul>
<p>Topics</p>
<ul>
<li>Multi-Level Inheritance with different Primary Key columns (id, org id, client id)</li>
<li>Custom Inheritance discriminators</li>
<li>Stateful Join Tables (ManyToMany relationship with additional payload in the associative table)</li>
<li>Boolean to Char mapping (code sees true/false, DB sees Y/N)</li>
<li>Managed Id&#8217;s</li>
</ul>
<p><span id="more-839"></span></p>
<h2>Introduction</h2>
<p>So first, our data model.  Since our model is pretty well fixed, I had to design the business model around that partially, and partially to the true business needs.</p>
<div id="attachment_840" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2010/09/ObjectDiagram1.png"><img class="size-medium wp-image-840 " title="ObjectDiagram1" src="http://edwardawebb.com/wp-content/uploads/2010/09/ObjectDiagram1-300x198.png" alt="ObjectDiagram1 300x198 A complex data model with JPA   Inheritance, Stateful Join Tables, and More" width="300" height="198" /></a><p class="wp-caption-text">Notice the CLient, element, which inherets from two levels of parents, and the ROLE field in the join table </p></div>
<p>JPA supports inheritance with release 1, and despite some misleading posts in the internet, it is perfectly capable of overriding PK fields on concrete classes. A class may also inherit from one table, persist to another, and still be inherited from. For instance, a client which has an ID, Name, and Contact Number (among other things) will need to select from the Client table, the Org table, the Entity table, and Contact tables to get all relevant fields.</p>
<h2>Inheritance is Endless</h2>
<p>You&#8217;re parents were not abstract, and you&#8217;re likely to have children. What I am saying is that sometime you may need to inherit a few nested classes or levels for a heavily normalized DB.</p>
<p>In my case we have a generic ENTITY that can be a person, place or thing.  Below that are Persons and Organizations that inherit contact info, but hold unique fields (first name vs. Tax ID).  Organizations may be further considered Clients, Vendors or Associations. They in turn inherit all contact info, the tax ID, and such, but add additional attributes.</p>
<p>Each table does not have a generic ID column. Instead we have several, i.e. ENTITY_ID, ORGANIZATION_ID, and CLIENT_ID.</p>
<p>Further more each table uses discriminators of different names and types.  So while the ENTITY tables uses a 2 character code (ENTITY_TYPE_CD (CHAR(2)), the Organization Table uses a 10 character string (ORG_TYPE(CHAR(10)), etc.</p>
<p>The solution looks like this;<br />
(the 3 classes for client, org, entity)</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ENTITY&quot;</span><span style="color: #009900;">&#41;</span>
@Inheritance<span style="color: #009900;">&#40;</span>strategy<span style="color: #339933;">=</span>JOINED<span style="color: #009900;">&#41;</span>
@DiscriminatorColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ENTITY_TYPE_CD&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AbstractEntity<span style="color: #009900;">&#123;</span>
&nbsp;
@Id
@Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ENTITY_ID&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #666666; font-style: italic;">//wont work for children, need ot be overridden</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">long</span> key<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// this is the only class in this tree to have an id field</span>
...
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ORGANIZATION&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #666666; font-style: italic;">//handle relationship to parent</span>
@DiscriminatorValue<span style="color: #009900;">&#40;</span>value<span style="color: #339933;">=</span>ENTITY_TYPE_CD_ORG<span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//string for type &quot;organization&quot; as appose to &quot;person&quot;</span>
@PrimaryKeyJoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ORGANIZATION_ID&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// override PK id for this table, no id field needed in class</span>
<span style="color: #666666; font-style: italic;">//define inheritance for children</span>
@Inheritance<span style="color: #009900;">&#40;</span>strategy<span style="color: #339933;">=</span>JOINED<span style="color: #009900;">&#41;</span><span style="color: #666666; font-style: italic;">//we could use a different type..</span>
@DiscriminatorColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ENTITY_TYPE_CD&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// new discrimoianbtor column</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Organization <span style="color: #000000; font-weight: bold;">extends</span> AbstractEntity<span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// look NO id field or @id annotation, just the additional fields in this table</span>
@Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ORG_NAME&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> organizationName<span style="color: #339933;">;</span>
...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CLIENT&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #666666; font-style: italic;">//handle relationship to parent</span>
@DiscriminatorValue<span style="color: #009900;">&#40;</span>value<span style="color: #339933;">=</span>ORG_TYPE_CLIENT<span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//string for type &quot;client&quot; (not assc, or vendor)</span>
@PrimaryKeyJoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CLIENT_ID&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// override PK id for this table, no id field needed in class</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Client <span style="color: #000000; font-weight: bold;">extends</span> Organization<span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// look NO id field or @id annotation, just the additional fields in this table</span>
@Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CLIENT_ACCT_NO&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> clientAccountNumber<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// not PK or Id, just a random string that relates to client table</span>
...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>Continue to page 2 for more on persisting this model.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/complex-data-model-jpa-inheritance-stateful-join-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plugins for a Full Featured WordPress Content Manager</title>
		<link>http://edwardawebb.com/web-development/plugins-full-featured-wordpress-content-manager</link>
		<comments>http://edwardawebb.com/web-development/plugins-full-featured-wordpress-content-manager#comments</comments>
		<pubDate>Tue, 04 May 2010 14:06:05 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[bookmarks]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[sharing]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=738</guid>
		<description><![CDATA[More and more clients are asking for dynamic sites that allow them to edit specials and pages at will. This is great because it surely means they will come back for more questions and changes as they use the site. (read : more income). What they want are CMS, or content management systems. What I [...]]]></description>
			<content:encoded><![CDATA[<p>More and more <strong>clients are asking for dynamic sites that allow them to edit specials and pages at will</strong>. This is great because it surely means they will come back for more questions and changes as they use the site. (read : more income).</p>
<p>What they want are CMS, or content management systems.  <strong>What I give them is usually wordpress loaded with useful plugins</strong>. (If custom business logic is needed i turn to CakePHP). </p>
<p>ANd why not? The WordPress engine provides post and page management, RSS feeds and discussion features, and customizable &#8220;widgets.&#8221;  But a few key features are needed to make the leap to a decent CMS. </p>
<p><Strong>Read This</Strong><br />
(<strong>Update</strong>:<strong> FInally a CMS that clients can use! &#8211; found <a href="http://www.concrete5.org/" rel="nofollow"  title="concrete5 - FInally a CMS that clients can use!">concrete5 CMS</a> very recently, and first impression is wow!- trust me its worth a demo </strong>)</p>
<p>Besides, no matter how many times I explain creating a new page in drupal, or how to add a side box in joomla. There is just too many steps and switches for the average small business owner. (is that a huge stereotype? yes, I apologize..)  <strong> But honestly, most non-technical users don&#8217;t think in terms of elements like footer, and side bars, and such. they think of pages!  (and conrete5 does that in a spectaciular manner)</strong></p>
<p>..but if you don&#8217;t want to give that a shot first, read on.</p>
<p>The plugins handle 4 critical areas for any decent site:</p>
<ul>
<li><strong>Page and Menu Management</strong></li>
<li><strong>SEO and Meta data</strong></li>
<li><strong>Sitemaps</strong></li>
<li><strong>Web 2.0 / Bookmarking / Sharing</strong></li>
</ul>
<p><strong>SO what plugins come standard on a Edward A Webb hosted WordPress install</strong>? <a href="/web-development/7-plugins-full-featured-wordpress-content-manager#more-738" rel="nofollow" >Read more</a> to bathe in the glory of these awesome plugins.</p>
<p><span id="more-738"></span></p>
<h2>Page Management</h2>
<p>WordPress has great page management, but the connection to Menus is lacking.  Clients need to hide  and reorder pages constantly, and explaining the &#8220;weighted order&#8221; field is not worth the effort.</p>
<ol>
<li><a href="http://wordpress.org/extend/plugins/pagemash/" rel="nofollow" title="PageMash - Ajax page sorting plugin for WordPress" >PageMash</a><br />
<blockquote><p>Customise the order your pages are listed in and manage the parent  structure with this simple ajax drag-and-drop administrative interface  with an option to toggle the page to be hidden from output. Great tool  to quickly re-arrange your page menus.</p></blockquote>
</li>
</ol>
<h2>SEO Enhancement</h2>
<p>Yes I can use buzz words. But SEO is legitimately important when administering a site for any business.  So to maximize client click-throughs and search ranking I use a few plugins to add clean urls and descriptive tags to everything!</p>
<ol>
<li> <a href="http://wordpress.org/extend/plugins/all-in-one-seo-pack/" rel="nofollow" title="All in One SEO Pack - get your meta tags in line!" >All in One SEO Pack</a><br />
<blockquote><ul>
<li>Support for CMS-style WordPress installations</li>
<li>Automatically optimizes your <strong>titles</strong> for search  engines</li>
<li>Generates <strong>META tags automatically</strong></li>
<li>Avoids the typical duplicate content found on WordPress blogs</li>
<li>For beginners, you don&#8217;t even have to look at the options, it works  out-of-the-box. Just install.</li>
</ul>
</blockquote>
</li>
<li><a href="http://wordpress.org/extend/plugins/seo-image/" rel="nofollow" title="SEO Friendly Images - add title attributes to all images" >SEO Friendly Images</a><br />
<blockquote><p>SEO Friendly Images is a WordPress optimization plugin which  automatically updates all images with proper ALT and TITLE attributes.  If your images do not have ALT and TITLE already set, SEO Friendly  Images will add them according the options you set. Additionally this  makes the post W3C/xHTML valid as well.</p></blockquote>
</li>
<li><a href="http://wordpress.org/extend/plugins/seo-slugs/" rel="nofollow" title="SEO Slugs - removes words liek at or the from urls" >SEO Slugs</a><br />
<blockquote><p>The SEO Slugs WordPress plugin removes common words like &#8216;a&#8217;, &#8216;the&#8217;,  &#8216;in&#8217; from post slugs to improve search engine optimization.</p></blockquote>
</li>
</ol>
<h2>Sitemaps</h2>
<p>Technically a perk for SEO, but the plugin I use exposes a nice user readable sitemap as well.</p>
<ol>
<li><a href="http://wordpress.org/extend/plugins/google-sitemap-generator/" rel="nofollow" title="Google XML Sitemaps - generates xml sitemaps for google, yahoo, bing and your readers!" >Google XML Sitemaps</a><br />
<blockquote><p>This plugin will generate a special XML sitemap which will help search  engines like Google, Bing, Yahoo and Ask.com to better index your blog.  With such a sitemap, it&#8217;s much easier for the crawlers to see the  complete structure of your site and retrieve it more efficiently.</p></blockquote>
</li>
</ol>
<h2>Social Media / Bookmarking</h2>
<p>If you have a group of dedicated followers &#8211; they can be your biggest tool for grabbing more readers. But you have to make their job easy!  That&#8217;s why<strong> I recommend a simple sharing plugin for any wordpress site</strong>.</p>
<ol>
<li><a href="http://wordpress.org/extend/plugins/sexybookmarks/" rel="nofollow" title="SexyBookmarks - Sharing is sexy .. and easy!" >SexyBookmarks</a><br />
<blockquote><p>Though the name may be a little &#8220;edgy&#8221; for some, SexyBookmarks has  proven time and time again to be an extremely useful and successful tool  in getting your readers to actually <strong>submit your articles</strong> to numerous social bookmarking sites.</p></blockquote>
</li>
<li><a href="http://wordpress.org/extend/plugins/wp-to-twitter/" rel="nofollow" title="WP to Twitter - automatically shorten and post your titles to Twitter" >WP to Twitter</a><br />
<blockquote><p>The WP-to-Twitter plugin posts a Twitter status update from your  WordPress blog using either the Cli.gs or Bit.ly URL shortening services  to provide a link back to your post from Twitter.<br />
<em>You can also use WordPress&#8217; built in ?p=529 for short urls.</em></p></blockquote>
</li>
</ol>
<p>That&#8217;s it!  Just install those 7 plugins and you&#8217;ll be running the next Tumblr.. I swear. Ok well that might be an overstatement, or understatement.. but it&#8217;s a good goal to shoot for.</p>
<h2>Feedback</h2>
<p>How about you? Am I missing any great ones, have you found ones that work better than my listed choices? Please share!</p>
<h2>Script It?</h2>
<p>You didn&#8217;t honestly expect me to expect you to download 7 or ore zip files and upload them to a wp install did you?  Hell no, I won&#8217;t even make you curl them individually from your server, just add the scripts you want to the plugins array and run the bash script below against your wp install!</p>
<pre lang="">$ sh wp_plugins.sh path/to/wp/root</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># upload plugins to wordpress site</span>
<span style="color: #666666; font-style: italic;"># edward a webb - May 7, 2010</span>
<span style="color: #666666; font-style: italic;">#  http://edwardawebb.com/web-development/7-plugins-full-featured-wordpress-content-manager</span>
&nbsp;
<span style="color: #007800;">plugins</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> all-in-one-seo-pack google-sitemap-generator.3.2.3 pagemash <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">wproot</span>=<span style="color: #007800;">$1</span>
<span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: $0 path/to/wp/root&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$wproot</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#plugins[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">do</span>
		curl http:<span style="color: #000000; font-weight: bold;">//</span>downloads.wordpress.org<span style="color: #000000; font-weight: bold;">/</span>plugin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${plugins[$i]}</span>.zip <span style="color: #660033;">-o</span> <span style="color: #800000;">${plugins[$i]}</span>.zip
		<span style="color: #c20cb9; font-weight: bold;">unzip</span> <span style="color: #800000;">${plugins[$i]}</span>.zip <span style="color: #660033;">-d</span> <span style="color: #007800;">$wproot</span><span style="color: #000000; font-weight: bold;">/</span>wp-content<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>
		<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> <span style="color: #800000;">${plugins[$i]}</span>.zip
&nbsp;
&nbsp;
	<span style="color: #000000; font-weight: bold;">done</span>  
<span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span> Could not locate <span style="color: #007800;">$wproot</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/plugins-full-featured-wordpress-content-manager/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Running Pligg on Nginx &#8211; Rewrite rules</title>
		<link>http://edwardawebb.com/web-development/running-pligg-nginx-rewrite-rules</link>
		<comments>http://edwardawebb.com/web-development/running-pligg-nginx-rewrite-rules#comments</comments>
		<pubDate>Fri, 19 Feb 2010 18:56:00 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[pligg]]></category>
		<category><![CDATA[rewrite rules]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=663</guid>
		<description><![CDATA[As I mentioned in my article &#8220;Migrate form Apache to Nginx and keep rewrite rules intact&#8221;, Nginx is an awesome and lightweight web server. The only trouble I have ran into since the switch is Pligg. The htaccess file is ridiculously complex, and I suspect some of the rewrite rules to be repetitive or overlapping [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned in my article <a href="http://edwardawebb.com/site-news/migrate-apache-nginx-rewrites-intact">&#8220;Migrate form Apache to Nginx and keep rewrite rules intact&#8221;</a>, Nginx is an awesome and lightweight web server.</p>
<p>The only trouble I have ran into since the switch is Pligg. The htaccess file is ridiculously complex, and I suspect some of the rewrite rules to be repetitive or overlapping in areas.<br />
<strong><br />
Using the rules from my past article though I was able to get nginx rules in place that seem to work.</strong></p>
<p><span id="more-663"></span></p>
<h4>Pliggs default htaccess file</h4>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">AddDefaultCharset UTF-8
&nbsp;
## 404 Error Page
## If Pligg is installed in a subfolder, change the below line to ErrorDocument 404 /name-of-subfolder/404error.php
ErrorDocument 404 /404error.php
&nbsp;
## Re-directing Begin
Options +FollowSymlinks -MultiViews
RewriteEngine on
## If Pligg is installed in a subfolder, change the below line to RewriteBase /name-of-subfolder
RewriteBase /
## If installed in a subfolder you may need to add ## to the beginning of the next line
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*index\.php\ HTTP/
&nbsp;
## Remove these two lines if you have a sub-domain like  http://subdomain.pligg.com  or http://localhost
## Keep if your site it like   http://www.pligg.com
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
##### Re-directing End #####
&nbsp;
## You can find the below lines pre-made for you in the category management section of the admin panel ##
RewriteRule ^(all)/([^/]+)/?$ story.php?title=$2 [L]
RewriteRule ^(all)/?$ ?category=$1 [L]
##
&nbsp;
## The settings that you should configure are all above this line.
## Continue below only if you are an advanced user.
&nbsp;
##### URL Method 2 Begin #####
RewriteRule ^/?$ index.php [L]
RewriteRule ^advanced-search/?$ advancedsearch.php [L]
RewriteRule ^cache/([0-9]+)/?$ index.php [L]
RewriteRule ^cache/admin_c([0-9]+)/?$ index.php [L]
RewriteRule ^cache/templates_c/([0-9]+)/?$ index.php [L]
RewriteRule ^category/([^/]+)/?$ index.php?category=$1 [L]
RewriteRule ^category/([^/]+)/([^/]+)/?$ story.php?title=$2 [L]
RewriteRule ^live/?$ live.php [L]
RewriteRule ^login/?$ login.php [L]
RewriteRule ^login/([a-zA-Z0-9-]+)/?$ login.php?return=$1 [L]
RewriteRule ^login/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)/?$ login.php?return=$1/$2 [L]
RewriteRule ^logout/?$ login.php?op=logout&amp;return=index.php [L]
RewriteRule ^logout/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)/?$ login.php?op=logout&amp;return=$1/$2 [L]
RewriteRule ^out/([\d]+)/?$ out.php?id=$1 [L]
RewriteRule ^out/(https?:.+)$ out.php?url=$1 [L]
RewriteRule ^out/([^/]+)/?$ out.php?title=$1 [L]
RewriteRule ^profile/?$ profile.php [L]
RewriteRule ^recommend/([a-zA-Z0-9-]+)/?$ recommend.php?id=$1 [L]
RewriteRule ^register/?$ register.php [L]
RewriteRule ^search/([^/]+)/page/(\d+)/?$ search.php?search=$1&amp;page=$2 [L]
RewriteRule ^search/(.+)/?$ search.php?search=$1 [L]
RewriteRule ^searchurl/(.+)/?$ search.php?url=$1 [L]
RewriteRule ^settemplate/?$ settemplate.php [L]
RewriteRule ^story/([0-9]+)/?$ story.php?id=$1 [L]
RewriteRule ^story/([^/]+)/?$ story.php?title=$1 [L]
RewriteRule ^story/([0-9]+)/editcomment/([0-9]+)/?$ edit.php?id=$1&amp;commentid=$2 [L]
RewriteRule ^story/([0-9]+)/edit/?$ editlink.php?id=$1 [L]
RewriteRule ^submit/?$ submit.php [L]
RewriteRule ^tag/(.+)/(.+)/?$ search.php?search=$1&amp;tag=true&amp;from=$2 [QSA,NC,L]
RewriteRule ^tag/(.+)/?$ search.php?search=$1&amp;tag=true [QSA,NC,L]
RewriteRule ^tagcloud/?$ cloud.php [L]
RewriteRule ^tagcloud/range/([0-9]+)/?$ cloud.php?range=$1 [L]
RewriteRule ^topusers/?$ topusers.php [L]
RewriteRule ^trackback/([0-9]+)/?$ trackback.php?id=$1  [L]
RewriteRule ^upcoming/?$ upcoming.php [L]
RewriteRule ^upcoming/category/([^/]+)/?$ upcoming.php?category=$1 [L]
RewriteRule ^upcoming/category/([^/]+)/page/(\d+)/?$ upcoming.php?category=$1&amp;page=$2 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/?$ upcoming.php?part=$1 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/?$ upcoming.php?part=$1&amp;category=$2 [L]
RewriteRule ^upcoming/page/([0-9]+)/?$ upcoming.php?page=$1 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/page/(\d+)/?$ upcoming.php?part=$1&amp;page=$2 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/page/(\d+)/?$ upcoming.php?part=$1&amp;category=$2&amp;page=$3 [L]
RewriteRule ^user/?$ user.php [L]
RewriteRule ^user/search/([^/]+)/?$ user.php?view=search&amp;keyword=$1 [L]
RewriteRule ^user/([^/]+)/?$ user.php?view=$1 [L]
RewriteRule ^user/([^/]+)/([^/]+)/?$ user.php?view=$1&amp;login=$2 [L]
RewriteRule ^user/([^/]+)/link/([0-9+]+)/?$ user_add_remove_links.php?action=$1&amp;link=$2 [L]
&nbsp;
## Admin
RewriteRule ^admin/?$ admin/admin_index.php [L]
RewriteRule ^admin_comments/page/([^/]+)/?$ admin/admin_comments.php?page=$1 [L]
RewriteRule ^admin_links/page/([^/]+)/?$ admin/admin_links.php?page=$1 [L]
RewriteRule ^admin_users/page/([^/]+)/?$ admin/admin_users.php?page=$1 [L]
RewriteRule ^story/([0-9]+)/modify/([a-z]+)/?$ admin/linkadmin.php?id=$1&amp;action=$2 [L]
RewriteRule ^view/([^/]+)/?$ admin/admin_users.php?mode=view&amp;user=$1 [L]
&nbsp;
## Groups
RewriteRule ^groups/?$ groups.php [L]
RewriteRule ^groups/submit/?$ submit_groups.php [L]
RewriteRule ^groups/(members|name|oldest|newest)/?$ groups.php?sortby=$1 [L]
RewriteRule ^groups/([^/]+)/?$ group_story.php?title=$1 [L]
RewriteRule ^groups/([^/]+)/page/([0-9]+)?$ group_story.php?title=$1&amp;page=$2 [L]
RewriteRule ^groups/([^/]+)/?$ group_story.php?title=$1&amp;view=published [L]
RewriteRule ^groups/([^/]+)/(published|upcoming|shared|members)/?$ group_story.php?title=$1&amp;view=$2 [L]
RewriteRule ^groups/([^/]+)/(published|upcoming|shared|members)/page/([0-9]+)?$ group_story.php?title=$1&amp;view=$2&amp;page=$3 [L]
RewriteRule ^groups/([^/]+)/(published|upcoming|shared|members)/category/([^/]+)/?$ group_story.php?title=$1&amp;view=$2&amp;category=$3 [L]
RewriteRule ^groups/([^/]+)/(published|upcoming|shared|members)/category/([^/]+)/page/([0-9]+)?$ group_story.php?title=$1&amp;view=$2&amp;category=$3&amp;page=$4 [L]
RewriteRule ^groups/delete/([0-9]+)/?$ deletegroup.php?id=$1 [L]
RewriteRule ^groups/edit/([0-9]+)/?$ editgroup.php?id=$1 [L]
RewriteRule ^groups/id/([0-9]+)/?$ group_story.php?id=$1 [L]
RewriteRule ^groups/join/([0-9]+)/? join_group.php?id=$1&amp;join=true [L]
RewriteRule ^groups/member/admin/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ groupadmin.php?id=$1&amp;role=admin&amp;userid=$3 [L]
RewriteRule ^groups/member/normal/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ groupadmin.php?id=$1&amp;role=normal&amp;userid=$3 [L]
RewriteRule ^groups/member/moderator/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ groupadmin.php?id=$1&amp;role=$2&amp;userid=$3 [L]
RewriteRule ^groups/member/flagged/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ groupadmin.php?id=$1&amp;role=flagged&amp;userid=$3 [L]
RewriteRule ^groups/member/banned/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ groupadmin.php?id=$1&amp;role=banned&amp;userid=$3 [L]
RewriteRule ^groups/page/([0-9]+)/?$ groups.php?page=$1 [L]
RewriteRule ^groups/unjoin/([0-9]+)/? join_group.php?id=$1&amp;join=false [L]
RewriteRule ^groups/withdraw/([0-9]+)/user_id/([0-9]+)/?$ join_group.php?group_id=$1&amp;user_id=$2&amp;activate=withdraw [L]
RewriteRule ^join_group/action/(published|queued|discard)/link/(\d+)/?$ join_group.php?action=$1&amp;link=$2 [L]
&nbsp;
## Live
RewriteRule ^comments/?$ live_comments.php [L]
RewriteRule ^comments/page/([^/]+)/?$ live_comments.php?page=$1 [L]
RewriteRule ^live_published/?$ live_published.php [L]
RewriteRule ^published/page/([^/]+)/?$ live_published.php?page=$1 [L]
RewriteRule ^unpublished/?$ live_unpublished.php [L]
RewriteRule ^unpublished/page/([^/]+)/?$ live_unpublished.php?page=$1 [L]
&nbsp;
## Modules
RewriteRule ^inbox/?$ module.php?module=simple_messaging&amp;view=inbox [L]
RewriteRule ^sitemapindex.xml module.php?module=xml_sitemaps_show_sitemap [L]
RewriteRule ^sitemap-([a-zA-Z0-9]+).xml module.php?module=xml_sitemaps_show_sitemap&amp;i=$1 [L]
RewriteRule ^status/([0-9]+)/?$ modules/status/status.php?id=$1 [L]
RewriteRule ^toolbar/(\d+)/?$ modules/pligg_web_toolbar/toolbar.php?id=$1
RewriteRule ^sitemapindex.xml module.php?module=xml_sitemaps_show_sitemap [L]
RewriteRule ^sitemap-([0-9a-z]+).xml module.php?module=xml_sitemaps_show_sitemap&amp;i=$1 [L]
&nbsp;
## Pages
RewriteRule ^about/?$ page.php?page=about [L]
RewriteRule ^static/([^/]+)/?$ page.php?page=$1 [L]
&nbsp;
## Pagination
RewriteRule ^category/([^/]+)/page/([^/]+)/?$ index.php?category=$1&amp;page=$2 [L]
RewriteRule ^page/([^/]+)/?$ index.php?page=$1 [L]
RewriteRule ^page/([^/]+)/([^/]+)category/([^/]+)/?$ index.php?page=$1&amp;part=$2&amp;category=$3 [L]
RewriteRule ^published/page/([^/]+)/?$ index.php?page=$1 [L]
RewriteRule ^published/page/([^/]+)/category/([^/]+)/?$ index.php?page=$1&amp;category=$2 [L]
RewriteRule ^published/page/([^/]+)/([^/]+)category/([^/]+)/?$ index.php?page=$1&amp;part=$2&amp;category=$3 [L]
RewriteRule ^published/page/([^/]+)/([^/]+)/?$ index.php?page=$1&amp;part=$2 [L]
RewriteRule ^published/page/([^/]+)/range/([^/]+)/?$ ?page=$1&amp;range=$2 [L]
RewriteRule ^search/page/([^/]+)/([^/]+)/?$ search.php?page=$1&amp;search=$2 [QSA,NC,L]
RewriteRule ^topusers/page/([^/]+)/?$ topusers.php?page=$1 [L]
RewriteRule ^topusers/page/([^/]+)/sortby/([^/]+)?$ topusers.php?page=$1&amp;sortby=$2 [L]
RewriteRule ^user/page/([^/]+)/([^/]+)/([^/]+)/?$ user.php?page=$1&amp;view=$2&amp;login=$3 [L]
RewriteRule ^user/([^/]+)/([^/]+)/page/(\d+)/?$ user.php?page=$3&amp;view=$1&amp;login=$2 [L]
&nbsp;
## Sort
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/?$ index.php?part=$1 [L]
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/?$ index.php?part=$1&amp;category=$2 [L]
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/page/(\d+)/?$ index.php?part=$1&amp;page=$2 [L]
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/page/(\d+)/?$ index.php?part=$1&amp;category=$2&amp;page=$3 [L]
&nbsp;
## RSS
RewriteRule ^([^/]+)/rss/?$ storyrss.php?title=$1 [L]
RewriteRule ^rss/?$ rss.php [L]
RewriteRule ^rss/([a-zA-Z0-9-]+)/?$ rss.php?status=$1 [L]
RewriteRule ^rss/category/([^/]+)/?$ rss.php?category=$1 [L]
RewriteRule ^rss/category/upcoming/([^/]+)/?$ rss.php?status=queued&amp;category=$1 [L]
RewriteRule ^rss/category/published/([^/]+)/?$ rss.php?status=published&amp;category=$1 [L]
RewriteRule ^rss/category/([^/]+)/queued/?$ rss.php?status=queued&amp;category=$1 [L]
RewriteRule ^rss/category/([^/]+)/published/?$ rss.php?status=published&amp;category=$1 [L]
RewriteRule ^rss/category/([^/]+)/group/([^/]+)/?$ rss.php?category=$1&amp;group=$2 [L]
RewriteRule ^rss/category/upcoming/([^/]+)/([^/]+)/?$ rss.php?status=queued&amp;category=$1&amp;group=$2 [L]
RewriteRule ^rss/category/published/([^/]+)/([^/]+)/?$ rss.php?status=published&amp;category=$1&amp;group=$2 [L]
RewriteRule ^rss/search/([^/]+)/?$ rss.php?search=$1 [L]
RewriteRule ^rss/user/([^/]+)/?$ userrss.php?user=$1 [L]
RewriteRule ^rss/user/([^/]+)/([a-zA-Z0-9-]+)/?$ userrss.php?user=$1&amp;status=$2 [L]
RewriteRule ^rssfeeds/?$ rssfeeds.php [L]
&nbsp;
RewriteRule ^upcoming/([^/]+)/?$ upcoming.php?category=$1 [L]
RewriteRule ^upcoming/([^/]+)/page/(\d+)/?$ upcoming.php?category=$1&amp;page=$2 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/?$ upcoming.php?part=$1&amp;category=$2 [L]
RewriteRule ^upcoming/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/page/(\d+)/?$ upcoming.php?part=$1&amp;category=$2&amp;page=$3 [L]
RewriteRule ^published/page/([^/]+)/([^/]+)/?$ index.php?page=$1&amp;category=$2 [L]
RewriteRule ^published/page/([^/]+)/([^/]+)/([^/]+)/?$ index.php?page=$1&amp;part=$2&amp;category=$3 [L]
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/([^/]+)/?$ index.php?part=$1&amp;category=$2 [L]
RewriteRule ^(year|month|week|today|yesterday|recent|alltime)/([^/]+)/page/(\d+)/?$ index.php?part=$1&amp;category=$2&amp;page=$3 [L]
&nbsp;
## 9.9.5 compatibility
RewriteRule ^user/view/([a-zA-Z0-9-]+)/?$ user.php?view=$1 [L]
RewriteRule ^user/view/([a-zA-Z0-9+]+)/([a-zA-Z0-9+]+)/?$ user.php?view=$1&amp;login=$2 [L]
RewriteRule ^user/view/([a-zA-Z0-9+]+)/login/([a-zA-Z0-9+]+)/?$ user.php?view=$1&amp;login=$2 [L]
RewriteRule ^published/([a-zA-Z0-9-]+)/?$ index.php?part=$1
RewriteRule ^published/([a-zA-Z0-9-]+)/category/([^/]+)/?$ index.php?part=$1&amp;category=$2
RewriteRule ^about/([a-zA-Z0-9-]+)/?$ page.php?page=about [L]
RewriteRule ^upcoming/page/([^/]+)/category/([^/]+)/?$ upcoming.php?page=$1&amp;category=$2 [L]
RewriteRule ^upcoming/page/([^/]+)/upcoming=([^/]+)category/([^/]+)/?$ upcoming.php?page=$1&amp;part=upcoming&amp;order=$2&amp;category=$3 [L]
RewriteRule ^statistics/page/([^/]+)/?$ module.php?module=pagestatistics&amp;page=$1
&nbsp;
&nbsp;
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/?$ index.php?category=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/page/([^/]+)/?$ index.php?category=$1&amp;page=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ story.php?title=$2 [L]
##### URL Method 2 End #####
&nbsp;
## Disable directory browsing
Options All -Indexes
&nbsp;
## Gzip Begin ##
## To enable Gzip and decrease the load times of your Pligg site
## change /home/path/to to your absolute server path and remove the # from the lines below
# php_value auto_prepend_file /home/path/to/begin_gzip.php
# php_value auto_append_file /home/path/to/end_gzip.php
# AddType &quot;text/javascript&quot; .gz
# AddEncoding gzip .gz
# RewriteCond %{HTTP:Accept-encoding} gzip
# RewriteCond %{THE_REQUEST} ^(.*).js
# RewriteCond %{SCRIPT_FILENAME}.gz -f
# RewriteRule ^(.*)\.js $1.js.gz [L]
## Gzip End ##
&nbsp;
## Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
## Block out any script trying to base64_encode stuff to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
## Block out any script that includes a &lt;script&gt; tag in URL
RewriteCond %{QUERY_STRING} (\&lt;|%3C).*script.*(\&gt;|%3E) [NC,OR]
## Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
## Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
&nbsp;
## Block pycurl bot
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^pycurl/ [NC]
RewriteRule .* - [F]</pre></div></div>

<h4> NEW Pligg rules for Nginx</h4>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># convetefd from default pligg rules to nginx
&nbsp;
## 404 Error Page
## If Pligg is installed in a subfolder, change the below line to ErrorDocument 404 /name-of-subfolder/404error.php
#ErrorDocument 404 /404error.php
error_page 404 502 = /404error.php;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
if (!-e $request_filename){
	## Re-directing Begin
	## You can find the below lines pre-made for you in the category management section of the admin panel ##
	rewrite ^(all)/([^/]+)/?$ story.php?title=$2 last;
	rewrite ^(all)/?$ ?category=$1 last;
	##
&nbsp;
	## The settings that you should configure are all above this line.
	## Continue below only if you are an advanced user.
&nbsp;
	##### URL Method 2 Begin #####
	rewrite ^/?$ /index.php last;
	rewrite ^/advanced-search/?$ /advancedsearch.php last;
	rewrite ^/cache/([0-9]+)/?$ /index.php last;
	rewrite ^/cache/admin_c([0-9]+)/?$ /index.php last;
	rewrite ^/cache/templates_c/([0-9]+)/?$ /index.php last;
	rewrite ^/category/([^/]+)/?$ /index.php?category=$1 last;
	rewrite ^/category/([^/]+)/([^/]+)/?$ /story.php?title=$2 last;
	rewrite ^/live/?$ /live.php last;
	rewrite ^/login/?$ /login.php last;
	rewrite ^/login/([a-zA-Z0-9-]+)/?$ /login.php?return=$1 last;
	rewrite ^/login/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)/?$ /login.php?return=$1/$2 last;
	rewrite ^/logout/?$ /login.php?op=logout&amp;return=index.php last;
	rewrite ^/logout/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)/?$ /login.php?op=logout&amp;return=$1/$2 last;
	rewrite ^/out/([\d]+)/?$ /out.php?id=$1 last;
	rewrite ^/out/(https?:.+)$ /out.php?url=$1 last;
	rewrite ^/out/([^/]+)/?$ /out.php?title=$1 last;
	rewrite ^/profile/? /profile.php last;
	rewrite ^/recommend/([a-zA-Z0-9-]+)/?$ /recommend.php?id=$1 last;
	rewrite ^/register/? /register.php last;
	rewrite ^/search/([^/]+)/page/(\d+)/?$ /search.php?search=$1&amp;page=$2 last;
	rewrite ^/search/(.+)/?$ /search.php?search=$1 last;
	rewrite ^/searchurl/(.+)/?$ /search.php?url=$1 last;
	rewrite ^/settemplate/? /settemplate.php last;
	rewrite ^/story/([0-9]+)/?$ /story.php?id=$1 last;
	rewrite ^/story/([^/]+)/?$ /story.php?title=$1 last;
	rewrite ^/story/([0-9]+)/editcomment/([0-9]+)/?$ /edit.php?id=$1&amp;commentid=$2 last;
	rewrite ^/story/([0-9]+)/edit/?$ /editlink.php?id=$1 last;
	rewrite ^/submit/? /submit.php last;
	rewrite ^/tag/(.+)/(.+)/?$ /search.php?search=$1&amp;tag=true&amp;from=$2 last;
	rewrite ^/tag/(.+)/?$ /search.php?search=$1&amp;tag=true last;
	rewrite ^/tagcloud/? /cloud.php last;
	rewrite ^/tagcloud/range/([0-9]+)/?$ /cloud.php?range=$1 last;
	rewrite ^/topusers/? /topusers.php last;
	rewrite ^/trackback/([0-9]+)/?$ /trackback.php?id=$1  last;
	rewrite ^/upcoming/? /upcoming.php last;
	rewrite ^/upcoming/category/([^/]+)/?$ /upcoming.php?category=$1 last;
	rewrite ^/upcoming/category/([^/]+)/page/(\d+)/?$ /upcoming.php?category=$1&amp;page=$2 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/?$ /upcoming.php?part=$1 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/?$ /upcoming.php?part=$1&amp;category=$2 last;
	rewrite ^/upcoming/page/([0-9]+)/?$ /upcoming.php?page=$1 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/page/(\d+)/?$ /upcoming.php?part=$1&amp;page=$2 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/page/(\d+)/?$ /upcoming.php?part=$1&amp;category=$2&amp;page=$3 last;
	rewrite ^/user/? /user.php last;
	rewrite ^/user/search/([^/]+)/?$ /user.php?view=search&amp;keyword=$1 last;
	rewrite ^/user/([^/]+)/?$ /user.php?view=$1 last;
	rewrite ^/user/([^/]+)/([^/]+)/?$ /user.php?view=$1&amp;login=$2 last;
	rewrite ^/user/([^/]+)/link/([0-9+]+)/?$ /user_add_remove_links.php?action=$1&amp;link=$2 last;
&nbsp;
	## Admin
	rewrite ^/admin/?$ /admin/admin_index.php last;
	rewrite ^/admin_comments/page/([^/]+)/?$ /admin/admin_comments.php?page=$1 last;
	rewrite ^/admin_links/page/([^/]+)/?$ /admin/admin_links.php?page=$1 last;
	rewrite ^/admin_users/page/([^/]+)/?$ /admin/admin_users.php?page=$1 last;
	rewrite ^/story/([0-9]+)/modify/([a-z]+)/?$ /admin/linkadmin.php?id=$1&amp;action=$2 last;
	rewrite ^/view/([^/]+)/?$ /admin/admin_users.php?mode=view&amp;user=$1 last;
&nbsp;
	## Groups
	rewrite ^/groups/?$ /groups.php last;
	rewrite ^/groups/submit/?$ /submit_groups.php last;
	rewrite ^/groups/(members|name|oldest|newest)/?$ /groups.php?sortby=$1 last;
	rewrite ^/groups/([^/]+)/?$ /group_story.php?title=$1 last;
	rewrite ^/groups/([^/]+)/page/([0-9]+)?$ /group_story.php?title=$1&amp;page=$2 last;
	rewrite ^/groups/([^/]+)/?$ /group_story.php?title=$1&amp;view=published last;
	rewrite ^/groups/([^/]+)/(published|upcoming|shared|members)/?$ /group_story.php?title=$1&amp;view=$2 last;
	rewrite ^/groups/([^/]+)/(published|upcoming|shared|members)/page/([0-9]+)?$ /group_story.php?title=$1&amp;view=$2&amp;page=$3 last;
	rewrite ^/groups/([^/]+)/(published|upcoming|shared|members)/category/([^/]+)/?$ /group_story.php?title=$1&amp;view=$2&amp;category=$3 last;
	rewrite ^/groups/([^/]+)/(published|upcoming|shared|members)/category/([^/]+)/page/([0-9]+)?$ /group_story.php?title=$1&amp;view=$2&amp;category=$3&amp;page=$4 last;
	rewrite ^/groups/delete/([0-9]+)/?$ /deletegroup.php?id=$1 last;
	rewrite ^/groups/edit/([0-9]+)/?$ /editgroup.php?id=$1 last;
	rewrite ^/groups/id/([0-9]+)/?$ /group_story.php?id=$1 last;
	rewrite ^/groups/join/([0-9]+)/? /join_group.php?id=$1&amp;join=true last;
	rewrite ^/groups/member/admin/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ /groupadmin.php?id=$1&amp;role=admin&amp;userid=$3 last;
	rewrite ^/groups/member/normal/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ /groupadmin.php?id=$1&amp;role=normal&amp;userid=$3 last;
	rewrite ^/groups/member/moderator/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ /groupadmin.php?id=$1&amp;role=$2&amp;userid=$3 last;
	rewrite ^/groups/member/flagged/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ /groupadmin.php?id=$1&amp;role=flagged&amp;userid=$3 last;
	rewrite ^/groups/member/banned/id/([0-9]+)/role/([a-zA-Z0-9_-]+)/userid/([0-9]+)/?$ /groupadmin.php?id=$1&amp;role=banned&amp;userid=$3 last;
	rewrite ^/groups/page/([0-9]+)/?$ /groups.php?page=$1 last;
	rewrite ^/groups/unjoin/([0-9]+)/? /join_group.php?id=$1&amp;join=false last;
	rewrite ^/groups/withdraw/([0-9]+)/user_id/([0-9]+)/?$ /join_group.php?group_id=$1&amp;user_id=$2&amp;activate=withdraw last;
	rewrite ^/join_group/action/(published|queued|discard)/link/(\d+)/?$ /join_group.php?action=$1&amp;link=$2 last;
&nbsp;
	## Live
	rewrite ^/comments/? /live_comments.php last;
	rewrite ^/comments/page/([^/]+)/?$ /live_comments.php?page=$1 last;
	rewrite ^/live_published/? /live_published.php last;
	rewrite ^/published/page/([^/]+)/?$ /live_published.php?page=$1 last;
	rewrite ^/unpublished/? /live_unpublished.php last;
	rewrite ^/unpublished/page/([^/]+)/?$ /live_unpublished.php?page=$1 last;
&nbsp;
	## Modules
	rewrite ^/inbox/?$ /module.php?module=simple_messaging&amp;view=inbox last;
	rewrite ^/sitemapindex.xml module.php?module=xml_sitemaps_show_sitemap last;
	rewrite ^/sitemap-([a-zA-Z0-9]+).xml module.php?module=xml_sitemaps_show_sitemap&amp;i=$1 last;
	rewrite ^/status/([0-9]+)/?$ /modules/status/status.php?id=$1 last;
	rewrite ^/toolbar/(\d+)/?$ modules/pligg_web_toolbar/toolbar.php?id=$1;
	rewrite ^/sitemapindex.xml module.php?module=xml_sitemaps_show_sitemap last;
	rewrite ^/sitemap-([0-9a-z]+).xml module.php?module=xml_sitemaps_show_sitemap&amp;i=$1 last;
&nbsp;
	## Pages
	rewrite ^/about/?$ /page.php?page=about last;
	rewrite ^/static/([^/]+)/?$ /page.php?page=$1 last;
&nbsp;
	## Pagination
	rewrite ^/category/([^/]+)/page/([^/]+)/?$ /index.php?category=$1&amp;page=$2 last;
	rewrite ^/page/([^/]+)/?$ /index.php?page=$1 last;
	rewrite ^/page/([^/]+)/([^/]+)category/([^/]+)/?$ /index.php?page=$1&amp;part=$2&amp;category=$3 last;
	rewrite ^/published/page/([^/]+)/?$ /index.php?page=$1 last;
	rewrite ^/published/page/([^/]+)/category/([^/]+)/?$ /index.php?page=$1&amp;category=$2 last;
	rewrite ^/published/page/([^/]+)/([^/]+)category/([^/]+)/?$ /index.php?page=$1&amp;part=$2&amp;category=$3 last;
	rewrite ^/published/page/([^/]+)/([^/]+)/?$ /index.php?page=$1&amp;part=$2 last;
	rewrite ^/published/page/([^/]+)/range/([^/]+)/?$ ?page=$1&amp;range=$2 last;
	rewrite ^/search/page/([^/]+)/([^/]+)/?$ /search.php?page=$1&amp;search=$2 last;
	rewrite ^/topusers/page/([^/]+)/?$ /topusers.php?page=$1 last;
	rewrite ^/topusers/page/([^/]+)/sortby/([^/]+)?$ /topusers.php?page=$1&amp;sortby=$2 last;
	rewrite ^/user/page/([^/]+)/([^/]+)/([^/]+)/?$ /user.php?page=$1&amp;view=$2&amp;login=$3 last;
	rewrite ^/user/([^/]+)/([^/]+)/page/(\d+)/?$ /user.php?page=$3&amp;view=$1&amp;login=$2 last;
&nbsp;
	## Sort
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/?$ /index.php?part=$1 last;
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/?$ /index.php?part=$1&amp;category=$2 last;
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/page/(\d+)/?$ /index.php?part=$1&amp;page=$2 last;
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/category/([^/]+)/page/(\d+)/?$ /index.php?part=$1&amp;category=$2&amp;page=$3 last;
&nbsp;
	## RSS
	rewrite ^/([^/]+)/rss/?$ /storyrss.php?title=$1 last;
	rewrite ^/rss/? /rss.php last;
	rewrite ^/rss/([a-zA-Z0-9-]+)/?$ /rss.php?status=$1 last;
	rewrite ^/rss/category/([^/]+)/?$ /rss.php?category=$1 last;
	rewrite ^/rss/category/upcoming/([^/]+)/?$ /rss.php?status=queued&amp;category=$1 last;
	rewrite ^/rss/category/published/([^/]+)/?$ /rss.php?status=published&amp;category=$1 last;
	rewrite ^/rss/category/([^/]+)/queued/?$ /rss.php?status=queued&amp;category=$1 last;
	rewrite ^/rss/category/([^/]+)/published/?$ /rss.php?status=published&amp;category=$1 last;
	rewrite ^/rss/category/([^/]+)/group/([^/]+)/?$ /rss.php?category=$1&amp;group=$2 last;
	rewrite ^/rss/category/upcoming/([^/]+)/([^/]+)/?$ /rss.php?status=queued&amp;category=$1&amp;group=$2 last;
	rewrite ^/rss/category/published/([^/]+)/([^/]+)/?$ /rss.php?status=published&amp;category=$1&amp;group=$2 last;
	rewrite ^/rss/search/([^/]+)/?$ /rss.php?search=$1 last;
	rewrite ^/rss/user/([^/]+)/?$ /userrss.php?user=$1 last;
	rewrite ^/rss/user/([^/]+)/([a-zA-Z0-9-]+)/?$ /userrss.php?user=$1&amp;status=$2 last;
	rewrite ^/rssfeeds/? /rssfeeds.php last;
&nbsp;
	rewrite ^/upcoming/([^/]+)/?$ /upcoming.php?category=$1 last;
	rewrite ^/upcoming/([^/]+)/page/(\d+)/?$ /upcoming.php?category=$1&amp;page=$2 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/?$ /upcoming.php?part=$1&amp;category=$2 last;
	rewrite ^/upcoming/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/page/(\d+)/?$ /upcoming.php?part=$1&amp;category=$2&amp;page=$3 last;
	rewrite ^/published/page/([^/]+)/([^/]+)/?$ /index.php?page=$1&amp;category=$2 last;
	rewrite ^/published/page/([^/]+)/([^/]+)/([^/]+)/?$ /index.php?page=$1&amp;part=$2&amp;category=$3 last;
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/?$ /index.php?part=$1&amp;category=$2 last;
	rewrite ^/(year|month|week|today|yesterday|recent|alltime)/([^/]+)/page/(\d+)/?$ /index.php?part=$1&amp;category=$2&amp;page=$3 last;
&nbsp;
	## 9.9.5 compatibility
	rewrite ^/user/view/([a-zA-Z0-9-]+)/?$ /user.php?view=$1 last;
	rewrite ^/user/view/([a-zA-Z0-9+]+)/([a-zA-Z0-9+]+)/?$ /user.php?view=$1&amp;login=$2 last;
	rewrite ^/user/view/([a-zA-Z0-9+]+)/login/([a-zA-Z0-9+]+)/?$ /user.php?view=$1&amp;login=$2 last;
	rewrite ^/published/([a-zA-Z0-9-]+)/?$ index.php?part=$1;
	rewrite ^/published/([a-zA-Z0-9-]+)/category/([^/]+)/?$ index.php?part=$1&amp;category=$2;
	rewrite ^/about/([a-zA-Z0-9-]+)/?$ /page.php?page=about last;
	rewrite ^/upcoming/page/([^/]+)/category/([^/]+)/?$ /upcoming.php?page=$1&amp;category=$2 last;
	rewrite ^/upcoming/page/([^/]+)/upcoming=([^/]+)category/([^/]+)/?$ /upcoming.php?page=$1&amp;part=upcoming&amp;order=$2&amp;category=$3 last;
	rewrite ^/statistics/page/([^/]+)/?$ module.php?module=pagestatistics&amp;page=$1;
&nbsp;
&nbsp;
	##### URL Method 2 End #####
&nbsp;
}
&nbsp;
if (!-e $request_filename){
	rewrite ^/([^/]+)/?$ /index.php?category=$1 last;
}
if (!-e $request_filename){
	rewrite ^/([^/]+)/page/([^/]+)/?$ /index.php?category=$1&amp;page=$2 last;
}
if (!-e $request_filename){
	rewrite ^/([^/]+)/([^/]+)/?$ /story.php?title=$2 last;
}
&nbsp;
## Gzip Begin ##
## To enable Gzip and decrease the load times of your Pligg site
## change /home/path/to to your absolute server path and remove the # from the lines below
# php_value auto_prepend_file /home/path/to/begin_gzip.php
# php_value auto_append_file /home/path/to/end_gzip.php
# AddType &quot;text/javascript&quot; .gz
# AddEncoding gzip .gz
# RewriteCond %{HTTP:Accept-encoding} gzip
# RewriteCond %{THE_REQUEST} ^(.*).js
# RewriteCond %{SCRIPT_FILENAME}.gz -f
# rewrite ^(.*)\.js $1.js.gz last;
## Gzip End ##
&nbsp;
&nbsp;
if ($query_string ~* 'mosConfig_[a-zA-Z_]{1,21}(=|\%3D)' ){
 return 405;
}
if ($query_string ~* base64_encode.*\(.*\) ){
 return 405;
}
if ($query_string ~* (\&lt;|%3C).*script.*(\&gt;|%3E) ){
 return 405;
}
if ($query_string ~* 'GLOBALS(=|\[|\%[0-9A-Z]{0,2})' ){
 return 405;
}
if ($query_string ~* '_REQUEST(=|\[|\%[0-9A-Z]{0,2})' ){
 return 405;
}
## Block out any script trying to set a mosConfig value through the URL
## RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
## Block out any script trying to base64_encode stuff to send via URL
## RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
## Block out any script that includes a &lt;script&gt; tag in URL
## RewriteCond %{QUERY_STRING} (\&lt;|%3C).*script.*(\&gt;|%3E) [NC,OR]
## Block out any script trying to set a PHP GLOBALS variable via URL
## RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
## Block out any script trying to modify a _REQUEST variable via URL
## RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
&nbsp;
## Block pycurl bot by returnhing a forbidden
if ($http_user_agent ~* ^pycurl/){
	return 405;
}</pre></div></div>

<p>So most of the major functionality seems to work, but my Pligg install is used enough to verify that it is 100%</p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/running-pligg-nginx-rewrite-rules/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiple SSL Domains on Apache without Unique IPs</title>
		<link>http://edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips</link>
		<comments>http://edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips#comments</comments>
		<pubDate>Tue, 01 Sep 2009 13:19:40 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=565</guid>
		<description><![CDATA[So you host 13 domains on one server and want SSL certs for each domain. The cost of unique IPs is an obstacle indeed, but what if you didn't need any unique IP addresses?


IMpossible you say? Not with the release of Apache 2.2.13!

I stumbled on this nice little feature called SNI (or Server Name Indication) that allows multiple domains to share an IP and implement SSL without showing warnings to users or confusing Apache. ]]></description>
			<content:encoded><![CDATA[<p>So you host 13 domains on one server and want SSL certs for each domain.  The cost of unique IPs is an obstacle indeed, but what if you didn&#8217;t need any unique IP addresses?</p>
<p>IMpossible you say? Not with the release of Apache 2.2.13!</p>
<p>I stumbled on this nice little feature called SNI (or <em>Server Name Indication</em>) that allows multiple domains to share an IP and implement SSL without showing warnings to users or confusing Apache.  I found this beauty after reading another great article on Linux Magazine, <a href="http://www.linux-mag.com/cache/7480/1.html" rel="nofollow"  target="_blank">Ten Things You Didn&#8217;t KNow Apache (2.2) Could Do </a></p>
<p>So those of you running your own servers can take advantage by upgrading today!</p>
<p>For those of you relying on a Host you should start bombarding them with requests immediately. <strong>DreamHost members can <a href="https://panel.dreamhost.com/index.cgi?tree=home.sugg&amp;category=_all&amp;search=Support%20for%20name-bas" rel="nofollow" title="Vote for this Feature on all DreamHost servers."  target="_blank">vote up the already created suggestion  to implement this</a>.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automatically subscribe users to DreamHost announce lists</title>
		<link>http://edwardawebb.com/web-development/automatically-subscribe-users-dreamhost-announce-lists</link>
		<comments>http://edwardawebb.com/web-development/automatically-subscribe-users-dreamhost-announce-lists#comments</comments>
		<pubDate>Wed, 19 Aug 2009 18:58:01 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[dreamhost]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=560</guid>
		<description><![CDATA[This is a response to a question on the DreamHost wiki posted by anonymous. &#8220;I have a Contact page using form mail, and want to include a checkbox that enable visitors, to also subscribe to our Announce List when posting their form mail. Is there a facility for adding users to the Announce List without [...]]]></description>
			<content:encoded><![CDATA[<p>This is a response to a question on the DreamHost wiki posted by anonymous.</p>
<blockquote><p>&#8220;I have a Contact page using form mail, and want to include a checkbox that enable visitors, to also subscribe to our Announce List when posting their form mail.</p>
<p>Is there a facility for adding users to the Announce List without using form POST&#8221;</p></blockquote>
<p>Without using POST? I am not sure about that.. but using a checkbox to subscribe users is a snap.</p>
<p><span id="more-560"></span>Your resources;</p>
<ul>
<li>DreamHost Panel API</li>
<li>PHP curl methods</li>
</ul>
<p>So it goes like this;</p>
<p>Your user registers a new account, or sends you a contact message. As part of the form they submit their email address and name.  We in turn pass that email and name onto DreamHost&#8217;s panel API thereby adding the user to future announcements.</p>
<p>The code I will explain needs to go in the form&#8217;s receiving code. We will check for the checkbox&#8217;s value, and if necessary handle the additional choir. This code should be pasted into your contact form or registration form wherever the initial data is received and handled.</p>
<p style="text-align: center;">
<div class="mceTemp mceIEcenter">
<dl id="attachment_561" class="wp-caption aligncenter" style="width: 682px;">
<dt class="wp-caption-dt">
<div class="mceTemp mceIEcenter">
<dl id="attachment_562" class="wp-caption aligncenter" style="width: 682px;"><a href="http://edwardawebb.com/wp-content/uploads/2009/08/process1.png"><img class="size-full wp-image-562  " title="process" src="http://edwardawebb.com/wp-content/uploads/2009/08/process1.png" alt="process1 Automatically subscribe users to DreamHost announce lists" width="672" height="504" /></a>
<dd class="wp-caption-dd">The red boundary denotes new code for the announce submission</dd>
</dl>
</div>
</dt>
</dl>
</div>
<p>Since every cms, site and blog are different, I am unable to provide specifics, but yu should be able to track down the code for your form and find the portion that handles the submission. (Most obviously denoted with $_POST or $_GET variable use.)  I will also assume your email field is named &#8216;email&#8217; and your name field is two fields; &#8216;firstName&#8217;, &#8216;lastName&#8217;;</p>
<h3> Details on the API command</h3>
<p>Below is a link to details on the command, needed parameters and possible responses.<br />
<a href="http://wiki.dreamhost.com/Application_programming_interface#announcement_list-add_subscriber" rel="nofollow" >Add Subscriber API Command</a></p>
<h3> The Announce Submission Code</h3>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'subscribeMe'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'subscribeMe'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//get the values we need from form(this should in aprt already be somewhere in the code your editing)</span>
       <span style="color: #000088;">$email</span><span style="color: #339933;">=</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
       <span style="color: #000088;">$fullName</span><span style="color: #339933;">=</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'firstName'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lastName'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//set values we shoudl know, and are constant</span>
       <span style="color: #000088;">$domain</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;domain of this form&quot;</span><span style="color: #339933;">;</span>
       <span style="color: #000088;">$listname</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;list-name&quot;</span><span style="color: #339933;">;</span>
       <span style="color: #000088;">$apiKey</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;666666666666&quot;</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">// using curl and passing 5 critical values to the api</span>
       <span style="color: #666666; font-style: italic;">// list, domain, email, name and API Key</span>
&nbsp;
&nbsp;
		<span style="color: #000088;">$ch</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'https://api.dreamhost.com/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 		<span style="color: #990000;">curl_setopt</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_POST<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 		<span style="color: #990000;">curl_setopt</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_POSTFIELDS<span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;key=<span style="color: #006699; font-weight: bold;">$apiKey</span>&amp;cmd=announcement_list-add_subscriber&amp;listname=<span style="color: #006699; font-weight: bold;">$listname</span>&amp;domain=<span style="color: #006699; font-weight: bold;">$domain</span>&amp;email=<span style="color: #006699; font-weight: bold;">$email</span>&amp;name=<span style="color: #006699; font-weight: bold;">$fullName</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 		<span style="color: #000088;">$result</span><span style="color: #339933;">=</span><span style="color: #990000;">curl_exec</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 		<span style="color: #990000;">curl_close</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$result</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'success'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;h2&gt;Congrats! &lt;/h2&gt;&lt;p&gt;You have been added to our Mailing List&lt;/p&gt;&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;h2&gt; Ooops! &lt;/h2&gt;&lt;p&gt;Unable to add your email to our announcement list please contact site administrator.&lt;/p&gt;&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Code: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #666666; font-style: italic;">// end if subscribe box checked</span></pre></div></div>

<h3> Getting a DreamHost API key</h3>
<p><a href="http://wiki.dreamhost.com/Application_programming_interface#What_values_does_DreamHost.27s_API_use.3F" rel="nofollow" >More info on DreamHost API</a></p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/automatically-subscribe-users-dreamhost-announce-lists/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Running with Rails on Dreamhost</title>
		<link>http://edwardawebb.com/web-development/running-rails-dreamhost</link>
		<comments>http://edwardawebb.com/web-development/running-rails-dreamhost#comments</comments>
		<pubDate>Wed, 05 Aug 2009 18:35:15 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=542</guid>
		<description><![CDATA[A quick and dirty tutorial to get a new Ruby on Rails application running on your DreamHost server.  In am going to concentrate on the easiest method, which is to use the Phusion Passenger module, a.k.a. &#8216;mod_rails&#8217;. Introduction Some wise warnings from the DreamHost Passenger Wiki page; &#8220;Passenger and Mongrel fulfill very much the same [...]]]></description>
			<content:encoded><![CDATA[<p>A quick and dirty tutorial to get a new <strong>Ruby on Rails application running on your <a href="http://www.dreamhost.com/r.cgi?488244/hosting.html|EDDIESAVES" rel="nofollow" title="Save $50 off the yearly cost of hosting with Promo Code &quot;EDDIESAVES&quot;"  target="_blank">DreamHost</a> </strong>server.  In am going to concentrate on the easiest method, which is to use the Phusion Passenger module, a.k.a. &#8216;mod_rails&#8217;.</p>
<h2>Introduction</h2>
<p>Some wise warnings from the <a href="http://wiki.dreamhost.com/Passenger" rel="nofollow" title="View the Support Wiki article on Rails for more great info."  target="_self">DreamHost Passenger Wiki</a> page;</p>
<ul>
<li>&#8220;Passenger and <a href="http://wiki.dreamhost.com/Mongrel" rel="nofollow" title="Mongrel" >Mongrel</a> fulfill very much the same roles so you most likely do NOT want to be using both of them on the same domain or website.&#8221;</li>
<li>&#8220;Passenger disables some mod_rewrite functionality.&#8221;</li>
</ul>
<p>&nbsp;</p>
<p>Alright, so without further adue I will jump into the process of<strong> getting a Ruby on Rails application to run on DreamHost </strong>servers.</p>
<p>&nbsp;</p>
<p>Special thanks to members of the <a href="http://wiki.dreamhost.com/" rel="nofollow"  target="_blank">DreamHost support wiki </a>and <a href="http://rubydreams.dreamhosters.com/2009/05/running-an-application-using-passenger-mod_rails/" rel="nofollow"  target="_blank">RubyDreams</a> for inspiration and guidance.</p>
<p><span id="more-542"></span></p>
<h2>7 Steps to get Ruby on Rails moving with  DreamHost hosting</h2>
<ol>
<li><strong>Sign up with DreamHost</strong><br />
I imagine if your reading this article then you&#8217;ve done this step &#8211; Congratualtions!<br />
But just in case <a href="http://www.dreamhost.com/r.cgi?488244/hosting.html|EDDIESAVES" rel="nofollow" title="$50 off your first year of DreamHost web hosting."  target="_blank">here&#8217;s $50 towards your first year</a>.
<p>&nbsp;</p>
</li>
<li><strong>Activate mod_rails</strong><br />
This is very easy, and very important. When you are setting up a new domain, be sure to check the &#8216;mod_rails&#8217; checkbox.<br />
<em>DreamHost Panel &gt; Manage Domains &gt; (Add or Edit)</em></p>
<div id="attachment_546" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/08/dh_passenger.PNG"><img class="size-medium wp-image-546" title="dh_passenger" src="http://edwardawebb.com/wp-content/uploads/2009/08/dh_passenger-300x171.PNG" alt=" Running with Rails on Dreamhost" width="300" height="171" /></a><p class="wp-caption-text">Setting up the domain to use Passenger</p></div>
<p>DreamHost will yell at you and say something about a public directory. Just append the word &#8216;public&#8217; to the end of the path, e.g. &#8220;/home/username/mynewdomain.com/public&#8221;.  This directory will be populated in the following steps.
<p>&nbsp;</p>
</li>
<li><strong>Create DB</strong> &#8211; will be ready by the completion of next step<br />
Use the DreamHost web panel to create a new DB.<br />
<em>Goodies &gt; MySQL Databases &gt; Create New</em></p>
<p><div id="attachment_547" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/08/dh_db.PNG"><img class="size-medium wp-image-547" title="dh_db" src="http://edwardawebb.com/wp-content/uploads/2009/08/dh_db-300x288.PNG" alt=" Running with Rails on Dreamhost" width="300" height="288" /></a><p class="wp-caption-text">Setting up a new DB on DreamHost</p></div>
<p>&nbsp;</p>
</li>
<li><strong>Create Rails app</strong><br />
For this you&#8217;ll need to open up your favorite console and ssh to your DreamHost account.<br />
Navigate to your webroot directory and type the following;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ rails <span style="color: #660033;">-d</span> mysql mynewdomain.com</pre></div></div>

<p>(I have a standard of putting all domains in a folder called webroot, so my full path is /home/username/webroot/mynewdomain.com )<br />
You can browse around now and notice several created directories and files including the &#8216;public&#8217; folder required above.
<p>&nbsp;</p>
</li>
<li><strong>Edit DB Connection Strings<br />
</strong>Of course we need to tell our Ruby app about the DB, and how to connect.<br />
Open the file /yourapp/config/database.yml</p>
<p>Edit the parameters;</p>
<pre>development:
adapter: mysql
encoding: utf8
database: my_ruby_app_db
pool: 5
username: unsername
password:dbpassowrd
host: mysql.host
</pre>
<p>&nbsp;</p>
</li>
<li><strong>Prepare the DB for use<br />
</strong>By now the new DB should be up and running thanks to one of many  Happy DreamHost Robots.<br />
cd into the directory created in the last step;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> mynewdomain.com
$ rake db:migrate</pre></div></div>

<p>This will ensure your connections strings are correct and the DB is ready.
<p>&nbsp;</p>
</li>
<li><strong>Restart Rails</strong><br />
This is the area that was unknown to me as a total Rails newbie. You can always<strong> restart your application</strong> and clear any cached configuration information by throwing a special file into the tmp directory.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">touch</span> tmp<span style="color: #000000; font-weight: bold;">/</span>restart.txt</pre></div></div>

</li>
</ol>
<p>Hooray!   That&#8217;s it.  In about 15 minutes you have created a new Ruby on Rails application.  At this point it is a pretty <em>useless</em> application. But don&#8217;t let that dishearten you, there are lots of great tutorials that will show you how to make something useful!</p>
<p>Like this one for example. You can skip the DB and basic setup and jump right into the coding &#8211; <a href="http://guides.rubyonrails.org/getting_started.html" rel="nofollow" title="Create a simple Blog using Ruby."  target="_blank">http://guides.rubyonrails.org/getting_started.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/running-rails-dreamhost/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP</title>
		<link>http://edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp</link>
		<comments>http://edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp#comments</comments>
		<pubDate>Sun, 10 May 2009 14:54:04 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[pageant]]></category>
		<category><![CDATA[passwordless]]></category>
		<category><![CDATA[PuTTY]]></category>
		<category><![CDATA[remote server]]></category>
		<category><![CDATA[scp]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[ssh-agent]]></category>
		<category><![CDATA[WinSCP]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=460</guid>
		<description><![CDATA[<strong>Tools like PuTTY and Cygwin allows users trapped in a window's world to retain some of the power and functionality of 'nix platforms</strong>.  Together or independently they allow users on windows machines to SSH, SCP and interface with Linux, Unix, Solaris, or even AIX nodes.  The absolute best part?  You can generate a pair of keys to make remembering passwords a thing of a the past.   This is especially important to one's sanity if you work in an environment with 10s or 100s of different nodes that all have rotating IDs on different schedules.  

So my goal in the article that follows is to setup a powerful workstation that includes Cygwin, PuTTY, and WinSCP.  WinSCP is not a necessary tool, but I'll admit I like to resort to a graphical SCP tool every now and again.  <strong>Unlike a few other articles I have read I will not encourage you to use passphrase-less keys, just too risky in my mind. </strong> Instead we will just limit the number of times we need to enter that password to say about.... 1.

To recap, our Goals are;
<ul>
	<li>Install powerful windows based tools. (Cygwin, PuTTY and WinSCP)</li>
	<li>Generate a pair of 2048 bit RSA keys (With a passphrase)</li>
	<li>Disseminate the public key to all the nodes we know (or connect to)</li>
	<li>Employ Pageant and SSH-Agent to limit the need to enter that single passphrase.</li>
</ul>]]></description>
			<content:encoded><![CDATA[<p><strong>Tools like PuTTY and Cygwin allows users trapped in a window&#8217;s world to retain some of the power and functionality of &#8216;nix platforms</strong>.  Together or independently they allow users on windows machines to SSH, SCP and interface with Linux, Unix, Solaris, or even AIX nodes.  The absolute best part?  You can generate a pair of keys to make remembering passwords a thing of a the past.   This is especially important to one&#8217;s sanity if you work in an environment with 10s or 100s of different nodes that all have rotating IDs on different schedules.  </p>
<p>So my goal in the article that follows is to setup a powerful workstation that includes Cygwin, PuTTY, and WinSCP.  WinSCP is not a necessary tool, but I&#8217;ll admit I like to resort to a graphical SCP tool every now and again.  <strong>Unlike a few other articles I have read I will not encourage you to use passphrase-less keys, just too risky in my mind. </strong> Instead we will just limit the number of times we need to enter that password to say about&#8230;. 1.</p>
<p>To recap, our Goals are;</p>
<ul>
<li>Install powerful windows based tools. (Cygwin, PuTTY and WinSCP)</li>
<li>Generate a pair of 2048 bit RSA keys (With a passphrase)</li>
<li>Disseminate the public key to all the nodes we know (or connect to)</li>
<li>Employ Pageant and SSH-Agent to limit the need to enter that single passphrase.</li>
</ul>
<p>So let&#8217;s get started.<br />
<span id="more-460"></span><br />
<h2>Installing the Tools</h2>
<p>Most anyone who works with Unix nodes from a window&#8217;s desktop knows the joy of PuTTY. Perhaps a few less know about Cygwin.  These tools are a must have in any IT toolbox.</p>
<h3>Cygwin</h3>
<p>Cygwin, available <a href="http://www.cygwin.com/" rel="nofollow" title="Learn more about Cygwin and download a copy for yourself."  target="_blank">here</a>, allows Unix like commands to run in a windows command console.   When installing the utility we need to make sure to check off a few extras that are not part of the default install.</p>
<p>Kick off the install until you get to a list of the components to install. Expand the Net category and check off OpenSSH and OpenSSL.<br />
<a href="http://edwardawebb.com/wp-content/uploads/2009/05/cygwin_install.png"><img class="aligncenter size-medium wp-image-462" title="Cygwin Install Options" src="http://edwardawebb.com/wp-content/uploads/2009/05/cygwin_install-300x146.png" alt="cygwin install 300x146 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="146" /></a> Let the installation complete normally otherwise.</p>
<h3>PuTTY</h3>
<p>You know all about PuTTY I am sure.  My only real advice here is to download the complete PuTTY suite of tools with the installer. There are two main perks to this.  1) You get all the goodies like PuTTYGen and Pageant. 2) If your running Vista you won&#8217;t get those annoying UAC alerts every time you kick it off.</p>
<p>You can find the PuTTY suite <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" rel="nofollow" title="Download all the PuTTY tools."  target="_blank">here</a>. Be sure to grab the one listed under &#8220;A Windows installer for everything except PuTTYtel.&#8221;</p>
<p>Don&#8217;t worry, if you already had the stand alone utility installed, it will preserve all yoru settings so long as you install to the same folder.</p>
<h3>WinSCP</h3>
<p>WinSCP is a graphical interface for moving files between your local machine and remote servers.  If you want to stay true to your terminals you can just stick with Cygwin and the SCP utility (which we&#8217;ve already installed).</p>
<p>Grab WinSCP from <a href="http://winscp.net/eng/download.php" rel="nofollow" title="Download WinSCP, an open source graphical SCP tool."  target="_blank">here</a>, no special install needed.</p>
<h2>Generating our Keys</h2>
<p>OK!  So now we can connect to our remote servers any way conceivable to man. Well maybe that&#8217;s an over statement, but I think our bases are pretty well covered.</p>
<p>The next hurdle is to create a pair of digital keys.  We keep one key (the private key) on our local machine, and never share it with anyone.  We disseminate (or distribute) the other key (public) out to any server we want to connect to.  The key pair will be reunited on connection allow us to authenticate without entering our password for the remote server.</p>
<p>First open up Cygwin.  Ahh isn&#8217;t she beautiful.</p>
<p>Type <em>ssh-keygen -t rsa</em> at the prompt and follow the queues entering information.  <strong>Be sure to enter a passphrase! </strong>You may accept the default path for a key location.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh-keygen</span> <span style="color: #660033;">-t</span> rsa
Generating public<span style="color: #000000; font-weight: bold;">/</span>private rsa key pair.
Enter <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #c20cb9; font-weight: bold;">which</span> to save the key <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa<span style="color: #7a0874; font-weight: bold;">&#41;</span>:
Created directory <span style="color: #ff0000;">'/home/Eddie/.ssh'</span>.
Enter passphrase <span style="color: #7a0874; font-weight: bold;">&#40;</span>empty <span style="color: #000000; font-weight: bold;">for</span> no passphrase<span style="color: #7a0874; font-weight: bold;">&#41;</span>:
Enter same passphrase again:
Your identification has been saved <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.
Your public key has been saved <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub.
The key fingerprint is:
<span style="color: #000000;">74</span>:<span style="color: #000000;">17</span>:ef:<span style="color: #000000;">24</span>:e6:5f:1b:f3:e0:6a:1b:fe:ae:a6:fe:<span style="color: #000000;">24</span> Eddie<span style="color: #000000; font-weight: bold;">@</span>HP-dv6z-<span style="color: #000000;">420</span>
The key<span style="color: #ff0000;">'s randomart image is:
+--[ RSA 2048]----+
|  .-o.           |
|+ .o*  .         |
|+F .o . o        |
|..o  + .         |
|  -     S        |
|   -             |
|   +-  F  o      |
|.  .G . .        |
| o+*+o     o     |
+-----------------+</span></pre></div></div>

<p>Now since you should be in your home directory you can type <em> ls -a</em> and you should notice a new directory <em>.ssh</em> inside their will be your public (id-rsa.pub) and private (id-rsa) keys. If you chose an alternate path while generating the keys, be sure to move the private key into this folder.</p>
<h3>Disseminate our Public Key</h3>
<p>We&#8217;ll stick with Cygwin for a bit longer and use it&#8217;s scripting abilities to share our public key with any servers we want to connect to. If you only have one remote server in mind than a script is probly overkill, but you will want to follow the steps within the script. In my case I have about 20 servers, so I&#8217;ll take all the automation I can get.</p>
<h4>The Dissemination Scripts</h4>
<p>There are two scripts. One runs locally, and the other gets sent over SCP and then runs as our remote henchmen before being purged like a failed hitman.</p>
<h5>Script 1 &#8211; Called Locally </h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/bash</span>
<span style="color: #666666; font-style: italic;"># Author: Eddie Webb - edwardawebb.com</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Deploys a public SSH key to multiple remote nodes. It will convert from Putty Format</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Calls Script:</span>
<span style="color: #666666; font-style: italic;">#	addPublicKeyRemotely.sh</span>
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">## Check arghuments</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Usage: <span style="color: #000099; font-weight: bold;">\n</span> %s PuttyPubKey<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#create a log file</span>
<span style="color: #007800;">LOGFILE</span>=Results.log
&nbsp;
&nbsp;
&nbsp;
<span style="color: #007800;">SERVERS</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> server1 server2 funnyname anotherserver <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #666666; font-style: italic;">#NOte: if your username is different on each node - make an array below that correspoinds to the node list above</span>
<span style="color: #007800;">USER</span>=YOUREMOTEUSERNAME
&nbsp;
<span style="color: #007800;">SSHKEY</span>=<span style="color: #007800;">$1</span>
<span style="color: #007800;">SSHKEYBASE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$1</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">SCRIPTPATH</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;">## loop thorugh all servers sending key and remote script - purges afer script runs.</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#SERVERS[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> Sending to Host <span style="color: #800000;">${SERVERS[$i]}</span>
	<span style="color: #c20cb9; font-weight: bold;">scp</span> <span style="color: #007800;">$SSHKEY</span> <span style="color: #007800;">$SCRIPTPATH</span><span style="color: #000000; font-weight: bold;">/</span>addPublicKeyRemotely.sh <span style="color: #007800;">$USER</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${SERVERS[$i]}</span>:~<span style="color: #000000; font-weight: bold;">/</span>
	<span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #007800;">$USER</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #ff0000;">&quot;~/addPublicKeyRemotely.sh <span style="color: #007800;">$SSHKEYBASE</span>;rm -f ~/addPublicKeyRemotely.sh&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> Key successfully pushed to <span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> SUCCESS
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> FAILED pushing key to <span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> FAILED
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p> </p>
<h5>Script 2 &#8211; Called remotely &#8211; Name important (addPublicKeyRemotely.sh)</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Author: Eddie Webb - edwardawebb.com</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Called by Script:</span>
<span style="color: #666666; font-style: italic;">#		promotePublicKey.sh</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Arguments:</span>
<span style="color: #666666; font-style: italic;">#		name of converted SSH key </span>
&nbsp;
<span style="color: #666666; font-style: italic;"># this file is uplaoded to remote serveres and called to handle remote work before being deleted.</span>
&nbsp;
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-d</span> .ssh <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> .ssh
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #c20cb9; font-weight: bold;">touch</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">chmod</span> 0600 .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> <span style="color: #007800;">$1</span></pre></div></div>

<p> </p>
<p>Run the first script specifying your <strong>PUBLIC</strong> key as the only parameter.<br />
Now the downside is that you will still need to enter your remote passwords for each server, but hey it will be the last time.<br />
The result should look something like;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">&nbsp;
$ scripts<span style="color: #000000; font-weight: bold;">/</span>promotePublicKey.sh .ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub
Sending to Host domain.com
YOURUSER<span style="color: #000000; font-weight: bold;">@</span>domain.com<span style="color: #ff0000;">'s password:
id_rsa.pub                                    100%  399     0.4KB/s   00:00
addPublicKeyRemotely.sh                       100%  387     0.4KB/s   00:00
YOURUSER@domain.com'</span>s password:
SUCCESS</pre></div></div>

<p> </p>
<h3>Testing Cygwin</h3>
<p>You should now be able to make a remote connection entering only your new key passphrase(the passwordless part is yet to come).</p>
<p> </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> YOURUSER<span style="color: #000000; font-weight: bold;">@</span>domain.com
Enter passphrase <span style="color: #000000; font-weight: bold;">for</span> key <span style="color: #ff0000;">'/home/Eddie/.ssh/id_rsa'</span>:</pre></div></div>

<p>Don&#8217;t worry, you won&#8217;t always enter the passphrase, that was a test. Be patient with me <img src='http://edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" class='wp-smiley' title="Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" /> </p>
<p> </p>
<p> </p>
<h3>Importing to PuTTY</h3>
<p>Putty uses its own format for private keys (PPK) so we need to import our openSSH private key and convert it to a PPK for Putty to use. We&#8217;ll do this without overwritting the private key we have (still needed by Cygwin).</p>
<p>Open up PuTTYgen from your start menu.</p>
<p>First <em>Load</em> your existing private key (C:\cygwin\home\&lt;YOURNAME&gt;\.ssh\id-rsa)</p>
<div id="attachment_464" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen1.png"><img class="size-medium wp-image-464" title="Import existing key to PuTTYgen" src="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen1-300x289.png" alt="puttygen1 300x289 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="289" /></a><p class="wp-caption-text">Import existing key to PuTTYge</p></div>
<p> After you import the key you will be asked for your key&#8217;s passphrase before seeing the screen below. It lists the details about your public key.</p>
<div id="attachment_465" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen2.png"><img class="size-medium wp-image-465" title="The imported key in PuTTYgen" src="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen2-300x287.png" alt="puttygen2 300x287 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="287" /></a><p class="wp-caption-text">The imported key in PuTTYgen</p></div>
<p>Finally click the <em>Save private key</em> button (highlighted in Yellow)  this will save the priavte key as a PPK file. I typically save this in my PuTTY installation directory under a folder names <em>Keys.</em> <strong>Do not overwrite your existing key</strong>, and keep the PPK extension. </p>
<p> </p>
<p> </p>
<h2>Repetitive Entry Avoidance (A.K.A. Enter the passphrase once, and only once)</h2>
<p>Now we need to modify PuTTY and Cygwin to keep our keys in memory so we only enter the passphrase once per session.</p>
<h3>Using Pageant</h3>
<p>Pageant, which installed with PuTTY, will hold the keys open for PuTTy and WinSCP.</p>
<p>Find the shortcut to Pageant in your start menu. Make a copy of the shortcut and paste it into your <em>Startup</em> menu. This will kick off pageant every time windows boots. However, we need to tell the shortcut to load our private key.</p>
<p>Now right-click that icon and select properties. <br />
<a href="http://edwardawebb.com/wp-content/uploads/2009/05/pageant1.png"><img class="aligncenter size-medium wp-image-467" title="Pageant Startup Properties" src="http://edwardawebb.com/wp-content/uploads/2009/05/pageant1-300x300.png" alt="pageant1 300x300 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="300" /></a>Edit the entry that says <em>Target</em> and change it from;</p>
<p>&#8220;C:\Program Files (x86)\PuTTY\pageant.exe&#8221;</p>
<p>To;</p>
<p>&#8220;C:\Program Files (x86)\PuTTY\pageant.exe&#8221; &#8220;C:\Program Files (x86)\PuTTY\Keys\id-rsa.ppk&#8221; </p>
<p>Click <em>Apply</em> and then close the properties window.  </p>
<p>Now try clicking the icon. It should immediately ask you for your passphrase. This is the same prompt you will see next time you boot windows.</p>
<p>Go ahead an test out PuTTY now.  You will not be prompted for a password, and instead will see something like&#8217;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Using username <span style="color: #ff0000;">&quot;YOURUSER&quot;</span>.
Authenticating with public key <span style="color: #ff0000;">&quot;imported-openssh-key&quot;</span> from agent</pre></div></div>

<h3>Using SSH-Agent for Cygwin</h3>
<p>Cygwin doesn&#8217;t use PuTTY&#8217;s ppk file, so we need a manner to retain the private id-rsa key within our Cygwin sessions.</p>
<p>Add the following script to your <em>.bash_profile</em>;</p>
<p> </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">## only ask for my SSH key passphrase once!</span>
<span style="color: #666666; font-style: italic;">#use existing ssh-agent if possible</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
   . <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SSH_AGENT_PID</span>&quot;</span> <span style="color: #660033;">-o</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #780078;">`/usr/bin/ps -a|/usr/bin/egrep \&quot;^[ ]+$SSH_AGENT_PID\&quot;`</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
   <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">ssh-agent</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent
   . <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #c20cb9; font-weight: bold;">ssh-add</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa</pre></div></div>

<p> </p>
<p>Save the file and hop back to Cygwin.  You can either restart Cygwin, or source the profile file to test this feature out. Since I left Cygwin open I&#8217;ll just source the file.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ . .bash_profile
Enter passphrase <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa:
Identity added: <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Now you SSH to eighty different servers and not enter the passphrase again!</p>
<h2>Conclusion</h2>
<p>We&#8217;re done! Thanks for bearing with my article, I know it was not too concise, but I hope you forged through it. If you have any questions, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

