Web Development

Limit Characters or Words in ExpressionEngine

The more I use ExpressionEngine, the more I love it as there’s a solution for anything that I can find a need for.

I couldn’t find a parameter that I could use in ExpressionEngine (that was already built in) that limited how many characters were used from a variable. In PHP, you could use substr() and trim(), but I wanted to avoid using PHP in ExpressionEngine as much as possible. So after a bit of searching I found this ExpressionEngine plugin called “Character Limiter” which allows me to use the following expression:

{exp:char_limit total="100"}
    {variable}
{/exp:char_limit}

Simple as that.

You may find that you would rather limit the number of words outputted. To do this, use the ExpressionEngine plugin called “Word Limit Plus“. Upload “pi.word_limit_plus.php” to the /system/plugins/ directory, and use the following expression to limit the amount of words outputted:

{exp:word_limit_plus if_exceeds="600" stop_after="500" the_link="<a href='{title_permalink=weblog/comments}'>MORE...</a>"}
   {variable}
{/exp:word_limit_plus}

I haven’t used this plugin yet, but from the “Word Limit Plus” plugin documentation, the “if_exceeds” parameter is the amount of words that need to be met before the text is triggered to be truncated. The amount of words that the text string would be truncated TO is the “stop_after” parameter. 

Again I haven’t confirmed this, but if I am correct, then a paragraph that has more than 600 words would be truncated to only be 500 words, while a paragraph of 599 words would not be truncated at all. I imagine this is to prevent from having blogs posts that truncate and leave out only a few words (obviously if there’s only a few more words left to display of a blog post, why not just display them rather than truncate the extra words out).

The “the_link” parameter is not required, but from what I can tell, its tacked onto the end of the outputted text and serves as a way to display a “Read more…” link at the end of a blog post.

A good side note is through my research of the “Word Limit Plus” ExpressionEngine plugin, I did find that because the “Word Limit Plus” looks for spaces (to determine the word count), consecutive spaces may cause an error.

None-the-less, the ExpressionEngine “Word Limit Plus” plugin could be useful for summarizing blog posts on your home page, building a custom RSS feed to be used for feeding data to Twitter, or simply feeding data to another portion of your site. I won’t go into too much detail about it, but I’m sure the possibilities are fairly endless.

Random Fields Extension in ExpressionEngine

Early last month I posted two different ways to have random fields in ExpressionEngine stating that “…in ExpressionEngine, a ‘random number’ expression has yet to exist”. Well I hate to say but I was wrong! In fact, ExpressionEngine comes with a “Randomizer” plugin built right in. Simply navigate to: Admin > Utilities > Plugin Manager.

However, there is an inconvenience with the “Randomizer” plugin. It’s a pain to use! 

The instructions state:
-Open this file: /plugins/pi.randomizer.php
-Fill the array with as many quotes as you want.
-Then place the following tag in any of your templates: {exp:randomizer:set_one}

A friendly no thanks to that plugin. So I did a bit of searching and found a plugin (by a different author) called “Randomizer Plus” and its the best solution I’ve found so far to randomization within ExpressionEngine’s template system.

Setting it up is also really easy. Take the pi.randomizer_plus.php file from the downloaded zip archive file, and upload it into your ‘plugins’ directory, located in /system/plugins. 

From there, its just a matter of using the appropriate tag in your page template, and to specify the seperator (delimiter):

{exp:randomizer_plus separator="{OR}"}
Random Value 1
{OR}
Random Value 2
{OR}
Random Value 3
{/exp:randomizer_plus}

Looks clean and super easy to use! It makes you just love ExpressionEngine just that much more.

Random Number in ExpressionEngine With & Without PHP

The rand() function in PHP is a quick and easy way to have a nice random number generated. Without it, faking randomization can quickly become cumbersome. After all, a random number has so many uses. Maybe you want to display a random testimonial on each page load, a featured blog post, or even use a different stylesheet. 

To get a random number with ExpressionEngine, we can go the PHP route, or the non-PHP route. Going the PHP route is obviously easier to output and write the markup for (not to mention, is truely “random”), but enabling PHP in your templates may not be your answer; especially if you don’t want users [who have the ability to create/edit blog posts] have the power to do anything that PHP would allow them to do (such as outputting normally unobtainable data from the database).

Unfortunately, in ExpressionEngine, a “random number” expression has yet to exist; however, one of the nice things about ExpressionEngine is the ability to process PHP at the flip of a switch. 

The PHP Solution:
First, turn on PHP processing in: Templates (tab) > Template Preferences Manager (link) > Allow PHP (dropdown)

Then we simply assign the rand() to a variable, and check against that variable to output accordingly.

<?php 

$random_number = rand(0,6); 

if ($random_number == 1) { echo '<img src="/assets/images/image1.png" />'; }
elseif ($random_number == 2) { echo '<img src="/assets/images/image2.png" />'; }
elseif ($random_number == 3) { echo '<img src="/assets/images/image3.png" />'; }
elseif ($random_number == 4) { echo '<img src="/assets/images/image4.png" />'; }
elseif ($random_number == 5) { echo '<img src="/assets/images/image5.png" />'; }
elseif ($random_number == 6) { echo '<img src="/assets/images/image6.png" />'; }

// ensures an image is displayed even when no other conditions are met (in this case, it really only displays when random_number = 0)
else { echo '<img src="\/assets\/images\/image0.png" \/>'; } 

?>

For those that prefer to avoid PHP, here’s a quick way to (in a way) fake a random number. I figured a good way to do this was using the {current_time}, but only the seconds portion. Granted, its not the most elegant solution, but it gets the job done.

The Non-PHP Solution:

{!-- Sets current time (seconds) to the variable 'current_time_seconds' --}
{assign_variable:current_time_seconds="{current_time format="%s"}"}

{!-- %s = Seconds range: 00-59 --}
{!-- Check current time in seconds and displays a different image based on current time in seconds --}

{!-- displays if 1-9 --}
{if {current_time_seconds} > 0 && {current_time_seconds} < 10}
<img src="/assets/images/image1.png" />

{!-- displays if 11-19 --}
{if:elseif {current_time_seconds} > 10 && {current_time_seconds} < 20}
<img src="/assets/images/image2.png" />

{!-- displays if 21-29 --}
{if:elseif {current_time_seconds} > 20 && {current_time_seconds} < 30}
<img src="/assets/images/image3" />

{!-- displays if 31-39 --}
{if:elseif {current_time_seconds} > 30 && {current_time_seconds} < 40}
<img src="/assets/images/image4.png" />

{!-- displays if 41-49 --}
{if:elseif {current_time_seconds} > 40 && {current_time_seconds} < 50}
<img src="/assets/images/image5.png" />

{!-- displays if 51-59 --}
{if:elseif {current_time_seconds} > 50 && {current_time_seconds} < 60}
<img src="/assets/images/image6.png" />

{!-- displays if seconds don't match any of the conditions above (basically the following times in seconds: 00,10,20,30,40,50) --}
{if:else}
<img src="/assets/images/image0.png" />

{/if}

The non-PHP solution can be a great solution for someone who doesn’t want a random image “every single time” (for the visitors who are clicking through pages within seconds of eachother).

CSS Coders. It’s Time To Clean-up Your Markup!

It’s so easy to write CSS without laying out a single comment. After all, in those glorious moments of coding, everything is understood. You know what your coding because, well frankly, you’ve been coding it! Don’t get me wrong, I’m a true believer in balancing time constraints and code quality. I’m also a true believer in finding the perfect balance between code simplicity and code expandability. But quite frankly, I’ve mopped up too many messy stylesheets recently that I felt obligated to encourage good practices.

So time goes by and lucky for you, your all done with that site so your markup doesn’t really matter. After all, it works, and if it ain’t broke, don’t fix it. But then comes the day where you get that phone call, and you’ll need to make changes to that spreadsheet you coded so mindlessly way back when. Oops! I guess it doesn’t make as much sense as it did when you were coding it. “What was I thinking!?” -or maybe its more along the lines of “What in the world was this guy thinking!?” 

Thank goodness for Firefox Add-ons like Firebug! Oh where would I be without it. But regardless, I am finding more and more that CSS markup conventions are just lacking, and designers are the ones responsible!

Here’s some practices that may save you (or anyone else for that matter) a fair amount of time when editing those stylesheets.

Though I don’t like resetting styles when I don’t have to, I tend to like defaulting specific elements to have no padding, margin, and border. Until all browsers conform to the exact same “default browser spreadsheet”, resetting styles is beneficial in the sense that it overrides specific properties to be the same across all browsers.

/*********************
  RESET STYLES
*********************/
img, table, tr, td, tbody, ul, li, ol {
	padding: 0;
	margin: 0;
	border: 0;
}

I always like to keep “tag specified” styles in its own section at the top of my file (they can always be overwritten by compound CSS):

/*********************
  TAG SPECIFIC STYLES
*********************/
body {
	background: url('../graphics/design/body-bg.jpg');
	font: .9em normal Arial, Verdana, Tahoma;
	color: #666666;
}
a {
	color: #666666;
}
a:hover {
	color: #000000;
}
a:active {
	color: #666666;
}
fieldset {
	border-color:#999999;
	border-style:solid none none;
	border-width:1px;
	padding:0.75em;
}

It’s also nice to have “general classes” for those rogue elements that you don’t know what to do with:

/*********************
  CLASS SPECIFIC STYLES
*********************/

.noborder {	border: 0; }
.nomargin { margin: 0; }
.nopadding { padding: 0; }

.floatleft { float: left; }
.floatright { float: right; }
.block { display: block; }
.inlineblock { display: inline-block; }
.inline { display: inline; }

… and finally some general advise for your CSS properties:

/*
##	COLOR MAPPING - to help with managing frequently used colors
##
##		Mango Orange: CE882D
##		Dark Red: 621817
*/

/*  Comments next to specific properties along with author notes
      help you remember why the "value" is coded a particular way */
	#newsletter h3 {
		color: #ce882d; /* Orange */
		margin: 10px 0;
	}
#footer {
	width: 100%;
	height: 13px; /* absolute height is specified for all footer items for IE6 compatibility - jbarnett@mc2design.com */
	display: block;
	vertical-align: top;
}

A technique that I sometimes use (when colors are not specified) is obtaining a color code of a certain element using the Firefox Add-On ColorZilla, and simply performing a CTRL+F[ind] (or CMD+F in OSX) and searching for the color code in the stylesheet. However, its actually more useful to use the “Inspect” tool in Firebug and to obtain the exact line you need to modify.

Some might be thinking, “Well with all that time trying to comment-up my stylesheets, I could of just spent it figuring it out sometime in the future”. Wrong! The time you spend making your spreadsheet understandable is nothing compared to the time you’ll waste trying to figure your spreadsheet out later on. I find that the best way to comment your stylesheets, is to comment as you code. Not after your done writing it. But while you write it!

Useful Knowledge About the Internet Explorer 6 “PNG Fix”

As a web designer constantly dealing with deadlines, I’m constantly managing the time I spend on implementing features, fixing bugs, creating markup, you name it. More recently I’ve had to deal with PNG issues in Internet Explorer 6 a lot more than I would have liked to. Having worked on a project that required a large amount of PNG transparent images, I was quickly reminded of how the PNG fix for IE6 actually works. 

When I wrote the markup for a recent project, I did what felt right. I made use of background images for things like the logo, borders, and corners. I did everything possible to keep everything in the stylesheet. But that doesn’t work when it comes to IE6.

When I first got my hands dirty with the IE6 PNG Fix, it wasn’t an easy implementation for me some 2 years a go, but I included the pngfix.js file as I was supposed to (which can be found here: http://homepage.ntlworld.com/bobosola/) and was ready to move on. Unfortunately, the transparent part of the PNG images were a pastel blue. So thinking that perhaps I didn’t implement the javascript correctly, I went through the troubleshooting process. After about 15 minutes, and still staring at PNG images with pastel blue instead of transparency, I found myself cursing Internet Explorer 6, about ready to create an IF statement that kicked IE6 users to the curb. But as so many users were on IE6 at the time (and a decent number still using IE6 to this day), I pushed myself to nail down the specifics of the PNG fix.

What I learned?
The PNG fix doesn’t fix background images specified using CSS. Rather, you need to actually have the PNG image in the markup.

For example, the following markup would result in the transparent portions of the image to not be transparent at all:

/* CSS Stylesheet */
#footer {
   background-image: url('/assets/graphics/footer-bottom.png');
   height: 10px;
   width: 980px;
}
<!-- XHTML Markup -->
<div id="footer">
</div>

To have the PNG fix actually work, the image needs to be in the markup. I also created a new CSS selector to specify the dimensions of the image (so I wouldn’t have to specify the dimensions in the markup):

/* CSS Stylesheet */
#footer {
   height: 10px;
   width: 980px;
}
   /* For PNG Fix to work properly, image dimensions need to be specified.
       I prefer to keep everything in my external stylesheet, rather than
       having it in the <img> element */
   #footer img {
      height: 10px;
      width: 980px;
   }
<!-- XHTML Markup -->
<div id="footer">
   <img src="/assets/graphics/footer-bottom.png" />
</div>

It’s also good to remember that in general, IE6 doesn’t follow the “inherit” value (nor does it automatically assume to inherit the parent). Therefore its a good rule of thumb that in order to minimize IE6 problems, specify dimensions for every “selector”. It does make it a little inconvenient as you’ll need to change both parent and child element dimensions (rather than simply changing the parent element dimensions). But at least it keeps your IE6 css only file minimal (and in many cases, found that I didn’t need one).

Code it right! YO!

Widont for the Zend Framework – automatically remedies text widows

When I came across Shaun Inman’s clever Widon’t wordpress plug-in this morning, I thought to myself “What the heck is an unwanted browser window?”, as I read on I realized it said
“widow”. If you have never heard of a widow, you’ve likely never worked in the print industry. On the web, most of us have gotten rather sloppy when it comes to good typography, but in our defense, our medium doesn’t really lend itself to good practices. A widow is a lone word on the end of a header or paragraph. The header of this post would have had a widow, had I not used Shaun’s plugin (for a better explanation of a widow, refer to this article).

Since I’ve been using the Zend Framework so much lately, I figured why not add this functionality into it? Here’s a view helper to do just that. Enjoy!

class Zend_View_Helper_Widont {
 
    public $view;
 
    public function widont($str = '', $escape = false) {
 
        if ($escape) $str = $this->view->escape($str);
        return preg_replace( '|([^\s])\s+([^\s]+)\s*$|', '$1&nbsp;$2', $str);
 
    }
 
    public function setView($view) {
 
        $this->view = $view;
 
    }
 
}

Refer to the Zend Framework’s view helper documentation if you don’t know how to install view helpers.

To use this helper, call $this->widont($str) from inside of a view. If you pass a true value as the second argument, the string will be escaped before being output.

PHP Csv Utilities – new version coming soon!

It has been months since there was any kind of update on PHP Csv Utilities (or even the blog for that matter). I released the last version (0.2) prematurely, which resulted in a poor release and a lot of bugs. I’d like to let anybody interested in the library know that I am working on version 0.3 right now as well as a much improved build / release process. If there are any bugs or issues you have with the library please leave a comment or shoot me an email and I’ll do my best to make sure it’s addressed. 

Detecting if user is logged in with Miva Store Morph

As I was working on a Miva Merchant store today, I needed to show the user a link, but only if they were currently logged in. I know I have done this before, but I couldn’t find the code for the life of me. So I went to trusty ol’ Google and typed in “Miva Merchant detect if user logged in” and several other terms only to come up with nothing. So I dug through several other Merchant sites to find the code. I finally found it and have decided to post it here in case somebody else has the same problem.

UPDATE: Apparently you need to check that g.Basket:CUST_ID is not equal to zero. At first my solution only checked that it wasn’t null which was flawed.

<mvt:if expr="NOT ISNULL g.Basket:CUST_ID AND g.Basket:CUST_ID NE 0">
    Welcome back, &mvte:global:customer:login;!
<mvt:else>
    Hello anonymous user!
</mvt:if>

Zend Framework version 1.5 officially released

The Zend Framework has always been my favorite PHP framework. The thing I love about this framework is that its components are loosely coupled. That is to say that its components have well-defined, and well-thought out dependencies. If you don’t like certain components, you don’t have to use them. Other frameworks boast this kind of modularity, but honestly I haven’t seen any that really back it up. For our last two or three PHP projects, we gave CakePHP a try. At first I was really happy with cake because of how quickly I was able to wire frame an application, but the more I use it the more I realize that the components in cake are far too coupled and there is just too damn much “auto-magic” going on in cake. I really prefer explicit to implicit code.

The reason we decided to leave Zend and go to CakePHP was because it lacked two main components that made it very difficult to wire frame applications quickly and easily. Those components are a layout system, and a form manager. I am happy to announce that Zend has tackled both of these problems in this release, and has actually done a decent job on them. Neither of them are 100% yet (at least not in my opinion), but both are very usable and helpful at the very least. Go grab a copy of the new release and give it a go. I think you’ll be quite happy with it!

For a full list of the new features, check out the official release page on zend developer zone.0

UPDATE! – Zend Developer Zone has published a webinar on Zend_View and Zend_Layout by Ralph Schindler. Go check it out!