<?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:admin="http://webns.net/mvcb/"
	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"	
	>

    	<channel>
    
    	<title>Evan Black&#039;s Blog</title>
    	<link>http://www.evanblack.com/blog/</link>
    	<description>The Blog of Evan Black, a web designer and developer from Indianapolis, IN.</description>
    	<dc:language>en</dc:language>
    	<dc:creator>evanmblack@gmail.com</dc:creator>
    	<dc:rights>Copyright 2010</dc:rights>
    	<dc:date>2010-01-06T22:44:07+00:00</dc:date>
    	<admin:generatorAgent rdf:resource="http://expressionengine.com/" />
    	<atom:link href="http://www.evanblack.com/blog/feed" rel="self" type="application/rss+xml" />


    	<item>
      		<title>New Year, New Site</title>
      		<link>http://www.evanblack.com/blog/new-year-new-site/</link>
      		<author><![CDATA[Evan]]></author>
      		<comments>http://www.evanblack.com/blog/new-year-new-site/#comments</comments>
      		<pubDate>Wed, 06 Jan 2010 22:44:07 -0800</pubDate>
      		<guid>http://www.evanblack.com/blog/new-year-new-site/#When:22:44:07</guid>
      		<description>Five months ago when I decided to go about a much&#45;needed redesign of my portfolio site, I didn&#8217;t expect it to be nearly as difficult or take as much time as it has. Fortunately, it became much more of a priority when I parted ways with MediaSauce at the end of October. I also needed to write some good articles for the new blog in addition to basically generating all new content for the site.</description>
      		<content:encoded><![CDATA[<a href="http://www.evanblack.com/blog/new-year-new-site/"><img src="/images/sized/uploads/images/blog_new-site-280x190.jpg" width="280" height="190"  alt="New Year, New Site" /></a><p>Five months ago when I decided to go about a much-needed redesign of my portfolio site, I didn't expect it to be nearly as difficult or take as much time as it has. Fortunately, it became much more of a priority when I parted ways with <a href="http://www.mediasauce.com">MediaSauce</a> at the end of October. I also needed to write some good articles for the new blog in addition to basically generating all new content for the site.</p>
<p>When I looked at my old site I saw something that hadn't really been updated in 2 years. It also didn't portray what I wanted to show as my online presence or how I'd grown personally and professionally since graduating. This is the 2nd version of my portfolio and I decided to switch directions from the dark design of <a href="/v1/">version 1</a> to something light and simple. Most of the portfolio work is from projects I've worked on in the last 2 years while working at <a href="http://www.hirons.com" title="Hirons &amp; Company">Hirons &amp; Company</a> and MediaSauce.</p>
<p>Over the next several months, I will be continuing to make slight design changes and tweaks to enhance the site, for example, using <a href="http://typekit.com/" title="typekit">TypeKit</a> for the some of the headings. For now, take a look around and let me know what you think!</p>
<p>If you'd like to know more about the technologies behind the site, check out the <a href="/about/" title="About this site">About</a> page.</p>]]></content:encoded>
      		<dc:subject>Notes</dc:subject>
      		<dc:date>2010-01-06T22:44:07+00:00</dc:date>
    	</item>

    	<item>
      		<title>Change ExpressionEngine Image Sizer Plugin to Crop From the Top</title>
      		<link>http://www.evanblack.com/blog/change-expressionengine-image-sizer-plugin-to-crop-from-the-top/</link>
      		<author><![CDATA[Evan]]></author>
      		<comments>http://www.evanblack.com/blog/change-expressionengine-image-sizer-plugin-to-crop-from-the-top/#comments</comments>
      		<pubDate>Mon, 23 Nov 2009 23:33:58 -0800</pubDate>
      		<guid>http://www.evanblack.com/blog/change-expressionengine-image-sizer-plugin-to-crop-from-the-top/#When:23:33:58</guid>
      		<description>For those of you that don&#8217;t know, ExpressionEngine&#8217;s ImageSizer Plugin is awesome. Anytime you have a client that will be uploading content images to a site that need to be certain dimensions this plugin is crucial. It will dynamically resize the image to whatever dimensions you need, and even cache the resized image for you. Also, if you specify a width and a height for the image in the plugin parameters, and the source&#8217;s dimensions are different, it will even crop the image for you. This is great, but it also has a downside.</description>
      		<content:encoded><![CDATA[<a href="http://www.evanblack.com/blog/change-expressionengine-image-sizer-plugin-to-crop-from-the-top/"><img src="/images/sized/uploads/images/blog_imagesizer-280x160.jpg" width="280" height="160"  alt="Change ExpressionEngine Image Sizer Plugin to Crop From the Top" /></a><p>For those of you that don't know, ExpressionEngine's <a href="http://www.lumis.com/page/imgsizer/" title="ImageSizer Plugin">ImageSizer Plugin</a> is awesome. Anytime you have a client that will be uploading content images to a site that need to be certain dimensions this plugin is crucial. It will dynamically resize the image to whatever dimensions you need, and even cache the resized image for you. Also, if you specify a width and a height for the image in the plugin parameters, and the source's dimensions are different, it will even crop the image for you. This is great, but it also has a downside.</p>
<p>By default, the plugin will crop the image to the specified width and height from the center of the image. This works great in some cases, but recently (on this site actually) I wanted the plugin to crop my images from the top of the image. This, for example, would be desirable if web screenshots were going to be uploaded and used.</p>
<p>I would've expected this to be a simple parameter passed to the plugin, but unfortunately, it wasn't. I decided to take matters into my own hands and popped open the plugin code. Around line <strong>595</strong> I found this:</p>
<pre class="brush: php;">if ($crop) 
{   
	imagecopyresampled($image_resized, $image, -$int_width, -$int_height, 0, 0, $adjusted_width, $adjusted_height, $width_old, $height_old);
}
</pre>
<h4>Now to Crop from the Top</h4>
<p>I quickly diagnosed that the <strong>-$int_height</strong> variable was forcing the crop from the center. Changing that variable to a 0 would have the plugin cropping from the top. Here's the code with the change:</p>
<pre class="brush: php;">if ($crop) 
{   
	imagecopyresampled($image_resized, $image, -$int_width, 0, 0, 0, $adjusted_width, $adjusted_height, $width_old, $height_old);
}
</pre>
<p>You could also have the plugin crop from the top left corner if you also changed the <strong>-$int_width</strong> variable to 0. Ideally, you could make some updates to the plugin to pass in a <strong>crop_from</strong> parameter and have it accept a "topleft", "topcenter", "topright", "bottomleft", "bottomcenter", "bottomright", or "center" string.</p>]]></content:encoded>
      		<dc:subject>Quick Tips</dc:subject>
      		<dc:date>2009-11-23T23:33:58+00:00</dc:date>
    	</item>

    	<item>
      		<title>CodeIgniter Image Upload and Resize</title>
      		<link>http://www.evanblack.com/blog/codeigniter-image-upload-and-resize/</link>
      		<author><![CDATA[Evan]]></author>
      		<comments>http://www.evanblack.com/blog/codeigniter-image-upload-and-resize/#comments</comments>
      		<pubDate>Fri, 20 Nov 2009 17:06:15 -0800</pubDate>
      		<guid>http://www.evanblack.com/blog/codeigniter-image-upload-and-resize/#When:17:06:15</guid>
      		<description>One common thing that most developers will want to do when creating a web application with CodeIgniter is to give their users the ability to upload a profile image. Your code should be able to resize that profile image to the standard size that your design calls for. CodeIgniter provides two great classes to help make this a piece of cake. The two library classes we will be working with are the File Uploading and Image Manipulation classes. With these two classes and the CodeIgniter&#8230;</description>
      		<content:encoded><![CDATA[<a href="http://www.evanblack.com/blog/codeigniter-image-upload-and-resize/"><img src="/images/sized/uploads/images/blog_codeigniter-280x180.jpg" width="280" height="180"  alt="CodeIgniter Image Upload and Resize" /></a><p>One common thing that most developers will want to do when creating a web application with <a href="http://codeigniter.com/" title="CodeIgniter PHP Framework">CodeIgniter</a> is to give their users the ability to upload a profile image. Your code should be able to resize that profile image to the standard size that your design calls for. CodeIgniter provides two great classes to help make this a piece of cake.</p>
<p>The two library classes we will be working with are the <strong>File Uploading</strong> and <strong>Image Manipulation</strong> classes. With these two classes and the <a href="http://codeigniter.com/user_guide/" title="CodeIgniter User Guide">CodeIgniter User Guide</a> you can probably figure out most of what you need, but I'll make it even easier for you. First, we will start with what you need in the View. This will create your file upload field:</p>
<h4>The View</h4>
<pre class="brush: php;">$Fdata = array('name' =&gt; 'user_avatar', 'class' =&gt; 'file');
echo form_upload($Fdata);
</pre>
<p>Also, make sure your form is using '<strong>form_open_multipart</strong>'. Now we will move on to the Controller, where the bulk of the code is. The process here is to configure the upload, do the upload, configure the image resizing and then do the image resize. Here's what you should end up with:</p>
<h4>The Controller</h4>
<pre class="brush: php;">if($_FILES['user_avatar']['error'] == 0){
	//upload and update the file
	$config['upload_path'] = './images/profile/';
	$config['allowed_types'] = 'gif|jpg|png';
	$config['overwrite'] = false;
	$config['remove_spaces'] = true;
	//$config['max_size']	= '100';// in KB
	
	$this-&gt;load-&gt;library('upload', $config);

	if ( ! $this-&gt;upload-&gt;do_upload('user_avatar'))
	{
		$this-&gt;session-&gt;set_flashdata('message', $this-&gt;upload-&gt;display_errors('<p class="error">', '</p>'));
		redirect('profile');
	}	
	else
	{
		//Image Resizing
		$config['source_image'] = $this-&gt;upload-&gt;upload_path.$this-&gt;upload-&gt;file_name;
		$config['maintain_ratio'] = FALSE;
		$config['width'] = 40;
		$config['height'] = 40;

		$this-&gt;load-&gt;library('image_lib', $config);

		if ( ! $this-&gt;image_lib-&gt;resize()){
			$this-&gt;session-&gt;set_flashdata('message', $this-&gt;image_lib-&gt;display_errors('<p class="error">', '</p>'));				
		}
		
		$this-&gt;MUser-&gt;updateProfile($this-&gt;input-&gt;post('user_id'));
		//Need to update the session information if email was changed
		$this-&gt;session-&gt;set_userdata('email', $this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_email')));
		$this-&gt;session-&gt;set_flashdata('message', '<p class="message">Your Profile has been Updated!</p>');
		redirect('profile');
	}
}
</pre>
<p>You may need to make some changes to a couple of the configuration options to get what you want. You'll also notice at the bottom that I update some of my user session information afterwards. Next up, we'll handle the <strong>updateProfile</strong> function within the User Model. This part is pretty simple:</p>
<h4>The Model</h4>
<pre class="brush: php;">function updateProfile($user_id){
	$profile_data = array(
	'name' =&gt; $this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_name')),
	'email' =&gt; $this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_email')),
	'role' =&gt; $this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_role')),
	'website' =&gt; $this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_website'))
	);
	//check if password was updated
	if($this-&gt;input-&gt;post('user_password') != ''){
		$profile_data['password'] = md5($this-&gt;input-&gt;xss_clean($this-&gt;input-&gt;post('user_password')));
	}
	if($_FILES['user_avatar']['error'] == 0){
		$relative_url = 'images/profile/'.$this-&gt;upload-&gt;file_name;
		$profile_data['avatar'] = $relative_url;
	}
	$this-&gt;db-&gt;where('id', $user_id);
	$this-&gt;db-&gt;update('user', $profile_data);
}
</pre>
<p>Normally you would want your path to pull from the configuration options you set using $upload['full_path'], but for some reason I've had issues pulling that data from the upload.</p>]]></content:encoded>
      		<dc:subject>Development</dc:subject>
      		<dc:date>2009-11-20T17:06:15+00:00</dc:date>
    	</item>

    	<item>
      		<title>Getting the ExpressionEngine Member List to Display Custom Member Fields</title>
      		<link>http://www.evanblack.com/blog/getting-expressionengine-member-list-to-display-custom-member-fields/</link>
      		<author><![CDATA[Evan]]></author>
      		<comments>http://www.evanblack.com/blog/getting-expressionengine-member-list-to-display-custom-member-fields/#comments</comments>
      		<pubDate>Thu, 19 Nov 2009 04:11:21 -0800</pubDate>
      		<guid>http://www.evanblack.com/blog/getting-expressionengine-member-list-to-display-custom-member-fields/#When:04:11:21</guid>
      		<description>Back when I was working with ExpressionEngine on the NIC Indy website, I needed to display custom member data fields in the member directory list. I actually found it quite surprising that ExpressionEngine didn&#8217;t already have an option that allowed you to do this. After some fiddling around with the &#8220;memberlist&#8221; function, I found a pretty quick and simple way to make this happen.</description>
      		<content:encoded><![CDATA[<a href="http://www.evanblack.com/blog/getting-expressionengine-member-list-to-display-custom-member-fields/"><img src="/images/sized/uploads/images/blog_member-directory-280x180.jpg" width="280" height="180"  alt="Getting the ExpressionEngine Member List to Display Custom Member Fields" /></a><p>Back when I was working with ExpressionEngine on the <a href="http://www.nicindy.org/" title="NIC Indy">NIC Indy website</a>, I needed to display custom member data fields in the member directory list. I actually found it quite surprising that ExpressionEngine didn't already have an option that allowed you to do this. After some fiddling around with the "memberlist" function, I found a pretty quick and simple way to make this happen.</p>
<p>First of all, you will need to open up the <strong>mod.member_memberlist.php </strong>file. It will be in the Member Management module, usually located here: "/system/modules/member". Go down to around line number 510. It should look something like this:</p>
<h4>Before</h4>
<pre class="brush: php;">$f_sql="SELECT m.member_id, m.username, m.screen_name, m.email, m.url, m.location, m.icq, m.aol_im, m.yahoo_im, m.msn_im, m.location, m.join_date, m.last_visit, m.last_activity, m.last_entry_date, m.last_comment_date, m.last_forum_post_date, m.total_entries, m.total_comments, m.total_forum_topics, m.total_forum_posts, m.language, m.timezone, m.daylight_savings, m.bday_d, m.bday_m, m.bday_y, m.accept_user_email, m.avatar_filename, m.avatar_width, m.avatar_height, (m.total_forum_topics + m.total_forum_posts) AS total_posts, g.group_title ";		
$p_sql="SELECT COUNT(member_id) AS count ";
$sql="FROM exp_members m, exp_member_groups g 
WHERE m.group_id = g.group_id 
AND g.group_id != '3' 
AND g.group_id != '4' 
AND g.site_id = '".$DB-&gt;escape_str($PREFS-&gt;ini('site_id'))."'
AND g.include_in_memberlist = 'y' ";
</pre>
<p>You will be adding to these SQL select statements so that it also pulls from the <strong>exp_member_data</strong> table. Here is what you'll need to change the SQL statements to:</p>
<h4>After</h4>
<pre class="brush: php;">$f_sql="SELECT m.member_id, m.username, m.screen_name, m.email, m.url, m.location, m.icq, m.aol_im, m.yahoo_im, m.msn_im, m.location, m.join_date, m.last_visit, m.last_activity, m.last_entry_date, m.last_comment_date, m.last_forum_post_date, m.total_entries, m.total_comments, m.total_forum_topics, m.total_forum_posts, m.language, m.timezone, m.daylight_savings, m.bday_d, m.bday_m, m.bday_y, m.accept_user_email, m.avatar_filename, m.avatar_width, m.avatar_height, (m.total_forum_topics + m.total_forum_posts) AS total_posts, g.group_title, md.m_field_id_1, md.m_field_id_2, md.m_field_id_3, md.m_field_id_4, md.m_field_id_5, md.m_field_id_6, md.m_field_id_7, md.m_field_id_8, md.m_field_id_9, md.m_field_id_10, md.m_field_id_11, md.m_field_id_12, md.m_field_id_13, md.m_field_id_14 ";       
$p_sql="SELECT COUNT(m.member_id) AS count ";
$sql="FROM exp_members m, exp_member_groups g, exp_member_data md 
WHERE m.group_id = g.group_id 
AND m.member_id = md.member_id 
AND g.group_id != '3' 
AND g.group_id != '4' 
AND g.site_id = '".$DB-&gt;escape_str($PREFS-&gt;ini('site_id'))."'
AND g.include_in_memberlist = 'y' ";
</pre>
<p>The important changes here are on lines 1, 3 and 5. Unfortunately, you will need to manually add as many "m_field_id_x"s for as many custom member fields that have been created.</p>
<h4>Now to Display the Custom Fields</h4>
<p>To display the newly selected custom fields on the front-end of the member list, you will need to edit the <strong>Member Templates</strong>. You can do this in the Control Panel by going to your Member Profile Theme and finding the <strong>Member List Rows</strong> template. You can display the custom member fields simply by using the normal ExpressionEngine template tags like this - {m_field_id_x} - replacing "x" with whichever member profile field you want. Here is a section of mine:</p>
<pre class="brush: html;">&lt;ul&gt;
    &lt;li&gt;&lt;h6&gt;Contact Information&lt;/h6&gt;&lt;/li&gt;
    &lt;li&gt;title: &lt;span&gt;{m_field_id_8}&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;phone: &lt;span&gt;{m_field_id_5}&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>That's pretty much it. The only bad thing here is if Custom Member Fields are ever added you will also need to add them to the SQL statement.</p>
<h4>The Result</h4>
<p>As you can see from the image below, I was able to pull out the data I needed for the directory from these custom member fields.</p>
<p><img height="356" src="/uploads/images/nic_result.png" width="600" /></p>]]></content:encoded>
      		<dc:subject>Development</dc:subject>
      		<dc:date>2009-11-19T04:11:21+00:00</dc:date>
    	</item>

    	<item>
      		<title>Semantic Inline Form Labels with JQuery</title>
      		<link>http://www.evanblack.com/blog/semantic-inline-form-labels-with-jquery/</link>
      		<author><![CDATA[Evan]]></author>
      		<comments>http://www.evanblack.com/blog/semantic-inline-form-labels-with-jquery/#comments</comments>
      		<pubDate>Mon, 02 Nov 2009 23:45:53 -0800</pubDate>
      		<guid>http://www.evanblack.com/blog/semantic-inline-form-labels-with-jquery/#When:23:45:53</guid>
      		<description>A very common thing I see in designs I get these days are form labels that are written within the value of their associated input field. This is handy way for designers to save space and make their designs cleaner all&#45;around. Unfortunately for us developers, simply setting the input value isn&#8217;t very semantic or usable.</description>
      		<content:encoded><![CDATA[<a href="http://www.evanblack.com/blog/semantic-inline-form-labels-with-jquery/"><img src="/images/sized/uploads/images/blog_inline-labels-280x150.jpg" width="280" height="150"  alt="Semantic Inline Form Labels with JQuery" /></a><p>A very common thing I see in designs I get these days are form labels that are written within the value of their associated input field. This is handy way for designers to save space and make their designs cleaner all-around. Unfortunately for us developers, simply setting the input value isn't very semantic or usable. Thanks to JQuery there's plenty of easy ways to take care of this.</p>
<h4>The HTML</h4>
<p>We'll start with the HTML. Nothing fancy here, just your standard form with labels and inputs.</p>
<pre class="brush: html;">&lt;form id="signup" name="signup"&gt;
	&lt;label for="email"&gt;Email Address&lt;/label&gt;
	&lt;input class="text" name="email" type="text" /&gt;
	&lt;label for="zip"&gt;Zip Code&lt;/label&gt;
	&lt;input class="text zip" name="zip" type="text" /&gt;
	&lt;input class="btn" type="submit" value="Sign Up" /&gt;
&lt;/form&gt;
</pre>
<p>The CSS isn't important at all to what we're trying to accomplish, so I won't cover any of that. The JQuery on the other hand, is what does most of the work. First of all, we will want to loop through our label elements and assign their values to the inputs that immediately follow. Then you'll want to hide those labels. After that, we will handle the focus and blur events to get rid of those values when people click the form input. Here's the JQuery:</p>
<h4>The JQuery</h4>
<pre class="brush: js;">$(document).ready(function() {
    $("#signup label").each(function (i) {
        $(this).next("input").attr("value",$(this).html()+"...");
        $(this).hide();
    });
    $("#signup input").focus(function() {
        if($(this).prev("label").html()+"..." == this.value){
            this.value = "";
        }
    });
    $("#signup input").blur(function() {
        if(this.value == ""){
            this.value = $(this).prev("label").html()+"...";
        }
    });
});
</pre>
<p>Now this is by no means is a new or innovative technique. There are plenty of solutions out there that will accomplish the same goal. This tip is simply what I tend to use to sematically code the designs I get.</p>
<p><strong>Update (12-18-2009): </strong>Smashing Magazine recently published an article by <a href="http://www.zurb.com/">Zurb</a> called <a href="http://www.smashingmagazine.com/2009/12/16/stronger-better-faster-design-with-css3/">Stronger, Better, Faster Design with CSS3</a> that expands on this technique and makes it even better with CSS3 by just masking the label so even when you click into the input you can still read the label.</p>]]></content:encoded>
      		<dc:subject>Quick Tips</dc:subject>
      		<dc:date>2009-11-02T23:45:53+00:00</dc:date>
    	</item>

    
    	</channel>
</rss>