<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"> <channel><title>SitePoint » Learn CSS | HTML5 | JavaScript | Wordpress | Tutorials-Web Development | Reference | Books and More</title> <link>http://www.sitepoint.com</link> <description /> <lastBuildDate>Sat, 26 May 2012 17:28:52 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/SitepointFeed" /><feedburner:info uri="sitepointfeed" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>HTML5 and the Future of Online Games</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/9RO1I-XoY-8/</link> <comments>http://www.sitepoint.com/html5-and-the-future-of-online-games/#comments</comments> <pubDate>Fri, 25 May 2012 17:30:00 +0000</pubDate> <dc:creator>Jarred Draney</dc:creator> <category><![CDATA[Web Tech]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54549</guid> <description><![CDATA[The Golden Child: Flash Games For several years now Adobe Flash has been the dominate technology used to create online games. It is so popular in fact that the term &#8220;flash games&#8221; has almost become synonymous with browser based games in general. Take a look at all of the major gaming portals; with a few [...]]]></description> <content:encoded><![CDATA[<p></p><h2>The Golden Child: Flash Games</h2><p>For several years now Adobe Flash has been the dominate technology used to create online games. It is so popular in fact that the term &#8220;flash games&#8221; has almost become synonymous with browser based games in general. Take a look at all of the major gaming portals; with a few exceptions, practically all of the games they offer are flash games.</p><p>What&#8217;s so wrong with Flash you ask? Well nothing really. It was an amazing technology that was used to add all sorts of functionality to browsers. Through the use of a plug-in developers could now include all sorts of interactivity and animated graphics to their web pages. However things are changing, and Flash may no longer be the best fit for many online applications.</p><p>Browsers are a lot smarter now and they are only going to continue to get smarter. Rather than relying upon plug-ins to display interactive and graphically intense pages modern browsers can do it all by themselves. Utilizing the W3C, the specification for HTML5, browser makers are including all sorts of functionality into their products<br
/> that web developers can now use to make graphically intensive and interactive websites. This has special  implications for online game designers. Soon (hopefully) designers will no longer be forced to choose from a select few proprietary technologies that not only are expensive, but also obligate their end users to download, install, and regularly update the respective plug-ins.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>The New Kid on the Block: HTML5 Games</h2><p>Traditionally the role of HTML has been used primarily to define and layout the text on web pages. Over the years, however, its role has slowly evolved to be more interactive. The new HTML5 spec furthers this evolution by including definitions for several additional elements aimed at interactivity, multimedia, and graphics. Combine<br
/> these new HTML5 elements with the faster and enhanced JavaScript engines available in modern browsers and you now have a set of tools perfectly suited for online game development.</p><h2>Some advantages of HTML5 for Games</h2><p>Not only are the HTML5 technologies well suited for creating browser based games, they offer several advantages over proprietary options. HTML5 is an open technology. It doesn’t cost anything and technically only requires a simple text editor to code in. Never underestimate the power of free. Flash and other proprietary technologies all cost the developer. While this certainly isn’t the only factor that a game developer would consider, it certainly does play a role, and for the small time indie developer it might be a very big factor. Compatibility is another huge advantage HTML5 has. HTML is the lowest common denominator for all web based devices. By using HTML5 you can target a wider array of devices and gadgets without having to specifically port your game to each different platform. Another often forgotten advantage is ease of use. For the technically savvy, downloading, installing, and updating plug-ins is only a minor hassle. However, for less technically savvy users this can be quite a hurdle and just may turn away users altogether.</p><h2>Some Interesting Charts</h2><p>Above you will find some charts from Google Trends for the search term &#8220;flash games&#8221; and then also the term &#8220;html5 games&#8221;.  It is easy to see that searches for &#8220;flash games&#8221; have been in steady decline for over the past 5 years while searches for HTML5 games have seen some pretty impressive growth in the past 3 years. While this really doesn’t prove anything, it is an interesting metric to help gauge the popularity trends of the two different technologies. It is important to note that these charts show only relative search volume and not overall volume. Per the Google Adwords tool, the monthly global search volume for &#8220;flash games&#8221; is 11,100,000 compared to a measly 49,500 for &#8220;html5 games&#8221;.</p><h2>The Future of online Games</h2><p>Will HTML5 be the end of plug-in based games? If it is, it is pretty safe to say that it won&#8217;t be happening anytime soon. It is estimated that the HTML5 spec will not be fully implemented until 2022. Despite this long time-frame, browser makers are already racing to include all the HTML5 functionality that they can. Game developers have taken advantage of this and created numerous quality games that easily compete with their flash counterparts. Take a look at all these <a
href='http://html5gamer.net '>HTML5 games</a> to see some excellent<br
/> examples of what is already possible with the new technology.</p><p>Given the current search trends and the several advantages HTML5 has over Flash, the future for HTML5 games looks bright. While it is not certain if HTML5 will eventually win out to become the gaming technology of choice, one thing is for certain: the love of online casual gaming has captured the interest of millions and as long as<br
/> that interest exists developers will continue to create fun and exciting games.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=9RO1I-XoY-8:NjR2-W31rSk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=9RO1I-XoY-8:NjR2-W31rSk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=9RO1I-XoY-8:NjR2-W31rSk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=9RO1I-XoY-8:NjR2-W31rSk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/9RO1I-XoY-8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/html5-and-the-future-of-online-games/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/html5-and-the-future-of-online-games/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=html5-and-the-future-of-online-games</feedburner:origLink></item> <item><title>How Start a Newsletter in Minutes With TinyLetter</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/GaOoBq2KXmo/</link> <comments>http://www.sitepoint.com/how-start-a-newsletter-in-minutes-with-tinyletter/#comments</comments> <pubDate>Fri, 25 May 2012 15:00:22 +0000</pubDate> <dc:creator>Lior Levin</dc:creator> <category><![CDATA[Web Tech]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=53895</guid> <description><![CDATA[An email newsletter is a brilliant way to stay connected to your customers or community members. Many people who visit your website may like it. Some may even love it, but if no one reminds them to keep visiting, those people may forget all about it. By inviting them to subscribe to a periodic newsletter, you can [...]]]></description> <content:encoded><![CDATA[<p></p><p>An email newsletter is a brilliant way to <strong><a
href="http://webmasterformat.com/blog/benefits-from-offering-email-newsletter" target="_blank">stay connected</a></strong> to your customers or community members. Many people who visit your website may like it. Some may even love it, but if no one reminds them to keep visiting, those people may forget all about it. By inviting them to subscribe to a periodic newsletter, you can turn those site visitors into regulars, and <strong><a
href="http://tinyletter.com/" target="_blank">TinyLetter</a></strong> makes it easy to get started in a matter of minutes.<strong></p><p></strong>TinyLetter is a free service that makes it extremely easy to setup an email newsletter, share it with subscribers, and even charge them a fee for your high-quality periodical content. TinyLetter is a <strong><a
href="http://blog.mailchimp.com/mailchimp-acquires-tinyletter/" target="_blank">subsidiary of MailChimp</a></strong>, but it uses a simplified interface and is designed for &#8220;distraction free&#8221; mass communication with your subscribers, rather than robust email marketing campaigns.<strong></p><p></strong><strong>Creating a Newsletter</strong><strong></p><p></strong>To get started with TinyLetter, follow these simple instructions:<strong></p><p></strong>1. Point your web browser to <strong><a
href="http://tinyletter.com/" target="_blank">tinyletter.com</a></p><p></strong>2. Click &#8220;Register&#8221;<strong></p><p></strong>3. Fill out the registration form, including your username, real name (yours or your organization’s), newsletter name, a brief description, your email address, and a password.<strong></p><p></strong>4. Click &#8220;create my account&#8221;<strong></p><p></strong>5. Click where it says &#8220;click here to get the embed code&#8221;. This will allow you to publicize it on your website.<strong></p><p></strong>6. Paste the embed code into your website’s code where you want it to appear.<strong></p><p></strong>Users should now be able to subscribe directly from your site. Alternatively, you can give them the direct link (<a
href="http://tinyletter.com/your-username" target="_blank">tinyletter.com/your-username</a>)<wbr>, which is helpful if you want to share it on Facebook, Twitter, etc.<strong></p><p></strong><strong>Sending Your First Message</strong><strong></p><p></strong>Once you have some subscribers, you should start communicating with them. Go back to the TinyLetter website and click “Write A Newsletter”.  Enter a subject, and start writing just like you would with a normal email message. When you are finished, click “Preview” to get a glimpse of what your message will look like, and then click “Send to all” to make it final.<strong></p><p></strong><strong>Other Features</strong><strong><br
/> </strong>If you already have a contact list of users, you can import their email addresses directly into TinyLetter. On the main configuration screen, click &#8220;Import email address.&#8221; Note that it has a limit of 25 email addresses per day, likely to <strong><a
href="http://www.spamhaus.org/whitepapers/mailinglists.html" target="_blank">prevent spammers</a></strong> from using it to quickly build lists. <strong></p><p></strong>Another useful feature is that you can configure the appearance of the subscription page to look more integrated with your website’s theme. By clicking “Design and settings”, you can upload a background image, change the text that appears on the page, add a background pattern to the email subscription box, and configure payment information.<strong></p><p></strong><strong>Payments</strong><strong></p><p></strong>On the same “Design and settings” page, click the red link at the bottom of the first section that says “show even more settings”. Most of these settings allow you to tweak the text of your subscription form, but the bottom three settings allow you to configure payment options.<strong></p><p></strong>The first payment option, ”make money price”, sets the amount that subscribers must pay to get your newsletter. They will be charged monthly for the subscription. Therefore, if you only plan to send four newsletters per year, you should definitely make sure they know that. The “Free trial” setting gives you the option to give users their first month free. The final option is for how payment is collected, either from TinyLetter or directly to your PayPal account.<strong></p><p></strong>When you are finished changing settings, click “Save Changes” at the very bottom.<strong></p><p></strong><strong>Expanding Your Reader Base</strong><strong></p><p></strong>An email newsletter is a great way to extend your website to your readers who may not have time to check your site for updates and may not be accustomed to <strong><a
href="http://searchenginewatch.com/article/2067871/Study-RSS-Still-Not-Widely-Adopted" target="_blank">using RSS</a></strong>. Some users may have Facebook. Some may have Twitter. But all of your users probably have email accounts, and as long as you use some restraint with the frequency of your messages, many of them will love to get mail with <strong><a
href="http://googleblog.blogspot.com/2011/02/finding-more-high-quality-sites-in.html" target="_blank">quality content</a></strong> from you.<strong><br
/> </strong><br
/> </wbr></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=GaOoBq2KXmo:1xufKmbcVjM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=GaOoBq2KXmo:1xufKmbcVjM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=GaOoBq2KXmo:1xufKmbcVjM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=GaOoBq2KXmo:1xufKmbcVjM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/GaOoBq2KXmo" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/how-start-a-newsletter-in-minutes-with-tinyletter/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/how-start-a-newsletter-in-minutes-with-tinyletter/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=how-start-a-newsletter-in-minutes-with-tinyletter</feedburner:origLink></item> <item><title>SitePoint Podcast #163: Man Down</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/heDaLn3NMZ4/</link> <comments>http://www.sitepoint.com/podcast-163-man-down/#comments</comments> <pubDate>Fri, 25 May 2012 12:47:43 +0000</pubDate> <dc:creator>Karn Broad</dc:creator> <category><![CDATA[Podcast]]></category> <category><![CDATA[browsershare]]></category> <category><![CDATA[responsive]]></category> <category><![CDATA[Youtube]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54988</guid> <description><![CDATA[Episode 163 of The SitePoint Podcast is now available! This week the panel is made up of 3 of our 4 our regular hosts, Patrick O&#8217;Keefe (@ifroggy), Kevin Dees (@kevindees) and Stephan Segraves (@ssegraves). Listen in Your Browser Play this episode directly in your browser &#8212; just click the orange “play” button below: Download this Episode You [...]]]></description> <content:encoded><![CDATA[<p></p><div><p>Episode 163 of The SitePoint Podcast is now available! This week the panel is made up of 3 of our 4 our regular hosts, Patrick O&#8217;Keefe (<a
href="http://twitter.com/ifroggy">@ifroggy</a>), Kevin Dees (<a
href="http://twitter.com/kevindees">@kevindees</a>) and Stephan Segraves (<a
href="http://twitter.com/ssegraves">@ssegraves</a>).</p><h2>Listen in Your Browser</h2><p>Play this episode directly in your browser &#8212; just click the orange “play” button below:</p><p></p><h2>Download this Episode</h2><p>You can download this episode as a standalone MP3 file. Here’s the link:</p><ul><li><a
href="http://media.libsyn.com/media/sitepoint/sitepointpodcast163.mp3">SitePoint Podcast #163: Man Down</a> (MP3, 28:24, 27.3MB)</li></ul><h2>Subscribe to the Podcast</h2><p>The SitePoint Podcast is on iTunes! <a
href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=296180681&amp;s=143441">Add the SitePoint Podcast to your iTunes player</a>. Or, if you don’t use iTunes, you can <a
href="http://www.sitepoint.com/blogs/?feed=podcast">subscribe to the feed directly</a>.</p><h2>Episode Summary</h2><p>The panel discuss Google&#8217;s Chrome briefly taking the number one browser spot, Youtube&#8217;s 7th birthday, the thoughts on different possible responsive image standards HTML5 could use and more.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Here are the main topics covered in this episode:</p><ul><li><a
href="http://www.theverge.com/2012/5/21/3033566/chrome-most-popular-browser-weekly-may-2012">Chrome is the most popular browser in the world, says StatCounter | The Verge</a> ref <a
href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers#EWS_Web_Server_at_UIUC_.281996_Q2_to_1998.29">Usage share of Web Browsers</a></li><li><a
href="http://youtube-global.blogspot.com/2012/05/its-youtubes-7th-birthday-and-youve.html">YouTube Blog: It&#8217;s YouTube&#8217;s 7th birthday&#8230; and you’ve outdone yourselves, again</a></li><li><a
href="http://adactio.com/journal/5474/?skin=default">Jeremy Keith on possible Responsive Image Future Standards</a></li><li><a
href="http://coding.smashingmagazine.com/2012/05/15/zocial-button-set-72-css3-buttons/">Free Zocial Button Set: Social CSS3 Buttons | Smashing Coding</a></li></ul><p>Browse the full list of links referenced in the show at <a
href="http://delicious.com/sitepointpodcast/163">http://delicious.com/sitepointpodcast/163</a>.</p><h2>Host Spotlights</h2><ul><li>Patrick: <a
href="http://pointshoarder.com/">PointsHoarder &#8211; Building a Better Trip by Hoarding Points</a></li><li>Stephan: <a
href="http://www.panic.com/coda/">Panic &#8211; Coda &#8211; One-Window Web Development for Mac OS X</a></li><li>Kevin: <a
href="https://workfu.com/">WorkFu + Find work opportunities. Discover talent. The opportunity network.</a></li></ul><h2>Interview Transcript</h2><p>Transcript to follow.</p><p>Theme music by <a
href="http://www.belikewater.ca/">Mike Mella</a>.</p><p>Thanks for listening! Feel free to let us know how we’re doing, or to continue the discussion, using the comments field below.</p></div> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=heDaLn3NMZ4:suIUNE9LrFI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=heDaLn3NMZ4:suIUNE9LrFI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=heDaLn3NMZ4:suIUNE9LrFI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=heDaLn3NMZ4:suIUNE9LrFI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/heDaLn3NMZ4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/podcast-163-man-down/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure url="http://media.libsyn.com/media/sitepoint/sitepointpodcast163.mp3" length="0" type="audio/mpeg" /> <feedburner:origLink>http://www.sitepoint.com/podcast-163-man-down/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=podcast-163-man-down</feedburner:origLink></item> <item><title>Name That Pic</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/hcU5UFx1Y9U/</link> <comments>http://www.sitepoint.com/name-that-pic/#comments</comments> <pubDate>Fri, 25 May 2012 02:41:12 +0000</pubDate> <dc:creator>HAWK</dc:creator> <category><![CDATA[Community]]></category> <category><![CDATA[caption competition]]></category> <category><![CDATA[facebook]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54953</guid> <description><![CDATA[<img
width="37" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/cables-37x50.jpg" class="attachment-thumbnail wp-post-image" alt="Cables" title="Cables" />Over the last month HAWK has run a few spontaneous caption competitions on our Facebook page. Some of the responses have been hilarious so she's throwing it open to the rest of you.]]></description> <content:encoded><![CDATA[<img
width="37" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/cables-37x50.jpg" class="attachment-thumbnail wp-post-image" alt="Cables" title="Cables" /><p></p><p>Over the last month I&#8217;ve run a few spontaneous caption competitions on our <a
title="SitePoint Facebook page" href="http://www.facebook.com/sitepoint" target="_blank">Facebook page</a>. Some of the responses have been hilarious so I&#8217;m going to widen the audience and see what comes out of it.</p><p>I imagine this process will be an evolving one, but for now let&#8217;s keep it simple. Post your caption idea in the comments section and I&#8217;ll pick a couple of winners at my discretion. (Tip: I have an inappropriate sense of humour.) I&#8217;ll run this over the weekend and pick a winner early next week (it&#8217;s currently Friday afternoon here in NZ).</p><p>Here is this week&#8217;s photo:</p><p><img
class="aligncenter size-full wp-image-54964" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/cables.gif" alt="" width="450" height="600" /></p><p>The winning entries from <a
title="SitePoint Facebook page" href="http://www.facebook.com/sitepoint" target="_blank">Facebook</a> were <em>&#8220;Ok, do you see a black cable? Just plug it in to the back of the monitor&#8221;</em> and <em>&#8220;My other computer is a laptop&#8221;</em>. <a
title="Facebook entries" href="https://www.facebook.com/photo.php?fbid=10151175030038712&amp;set=a.178852413711.158463.119345668711&amp;type=1&amp;theater" target="_blank">You can see the rest of the entries here.</a> <strong>The best two entries (in my opinion) will win themselves digital copies of <a
title="PHP Master: Write Cutting Edge Code" href="http://www.sitepoint.com/books/phppro1/" target="_blank">PHP Master: Write Cutting Edge Code.</a></strong></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=hcU5UFx1Y9U:MaJNSONyo14:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=hcU5UFx1Y9U:MaJNSONyo14:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=hcU5UFx1Y9U:MaJNSONyo14:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=hcU5UFx1Y9U:MaJNSONyo14:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/hcU5UFx1Y9U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/name-that-pic/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://www.sitepoint.com/name-that-pic/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=name-that-pic</feedburner:origLink></item> <item><title>Easy CSS3 Animation with Animate.css</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/bRxvFFZVfUw/</link> <comments>http://www.sitepoint.com/animate-css-css3-animation/#comments</comments> <pubDate>Thu, 24 May 2012 16:27:49 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[vendor prefixes]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54838</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/css3-logo-50x50.png" class="attachment-thumbnail wp-post-image" alt="css3-logo" title="css3-logo" />Craig looks at Animate.css, a library of pre-defined CSS animations which handles the convoluted coding for you.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/css3-logo-50x50.png" class="attachment-thumbnail wp-post-image" alt="css3-logo" title="css3-logo" /><p></p><p>Despite my initial reservations over whether animations <em>should</em> be defined in CSS, I have to admit they&#8217;re very useful, faster and slicker than equivalent effects in JavaScript. Building great animations isn&#8217;t easy, though &#8212; it involves a lot of patience, trial, error, testing and vendor-prefix shenanigans.</p><p><a
href="http://daneden.me/animate/"><strong>Animate.css</strong></a> makes coding a little more bearable. Simply choose an effect, watch it in action, download the code and add a couple of classes to your HTML element. You can either download the full 2,500 line CSS file or <a
href="http://daneden.me/animate/build">create a custom build</a> using the effects you need.</p><p>Animate.css was developed by <a
href="http://daneden.me/">Dan Eden</a>, a designer and student based in Manchester, UK:</p><blockquote><p> I was working on a few personal projects with CSS3 animation keyframes and found myself repeating code. So I began creating a library of animations I could drop in at will. After I&#8217;d made something I was happy with, I released the code on GitHub and it took off from there.</p><p>People love animations!</p></blockquote><p>We certainly do. My current favorite is &#8220;hinge&#8221; in the Specials section at the bottom. Very cool. I&#8217;m struggling to think of a use-case, but may apply it to all my links from now on!<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>The Prefix Predicament</h2><p>While prefixes may be a necessary evil, Animate.css illustrates just how clunky they can be. Keyframes and their associated transformation properties must be defined with -webkit, -moz, -ms, -o and non-prefixed values. It results in a lot of browser-specific repeated code which is difficult to maintain and debug, e.g.</p><pre><code>
@-webkit-keyframes rollIn {
	0% { opacity: 0; -webkit-transform: translateX(-100%) rotate(-120deg); }
	100% { opacity: 1; -webkit-transform: translateX(0px) rotate(0deg); }
}
@-moz-keyframes rollIn {
	0% { opacity: 0; -moz-transform: translateX(-100%) rotate(-120deg); }
	100% { opacity: 1; -moz-transform: translateX(0px) rotate(0deg); }
}
@-ms-keyframes rollIn {
	0% { opacity: 0; -ms-transform: translateX(-100%) rotate(-120deg); }
	100% { opacity: 1; -ms-transform: translateX(0px) rotate(0deg); }
}
@-o-keyframes rollIn {
	0% { opacity: 0; -o-transform: translateX(-100%) rotate(-120deg); }
	100% { opacity: 1; -o-transform: translateX(0px) rotate(0deg); }
}
@keyframes rollIn {
	0% { opacity: 0; transform: translateX(-100%) rotate(-120deg); }
	100% { opacity: 1; transform: translateX(0px) rotate(0deg); }
}
</code></pre><p>CSS pre-parsers can ease the situation, but they&#8217;re not for everyone and the projects must be kept up to date as CSS3 evolves. I&#8217;m rapidly coming to the conclusion that <a
href="http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions-2/">Florian Rivoal&#8217;s suggestion of unprefixed properties being supported from day one</a> is a good move.</p><p>For the moment, however, <a
href="http://daneden.me/animate/"><strong>Animate.css</strong></a> is a great option if you want a couple of quick effects without doing the dirty work yourself.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=bRxvFFZVfUw:OTxHhbZhvPw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=bRxvFFZVfUw:OTxHhbZhvPw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=bRxvFFZVfUw:OTxHhbZhvPw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=bRxvFFZVfUw:OTxHhbZhvPw:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/bRxvFFZVfUw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/animate-css-css3-animation/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.sitepoint.com/animate-css-css3-animation/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=animate-css-css3-animation</feedburner:origLink></item> <item><title>Great Ideas—without the Risk!</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/R8ZlX3XLLHc/</link> <comments>http://www.sitepoint.com/remove-risk-from-that-next-great-idea/#comments</comments> <pubDate>Thu, 24 May 2012 05:36:33 +0000</pubDate> <dc:creator>Miles Burke</dc:creator> <category><![CDATA[Business]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54848</guid> <description><![CDATA[So you've come up with an awesome idea, and it might just be the next best thing, but unless you have a market, it’ll be the next big thing for you alone. Miles examines how to remove the risk from your next big idea.]]></description> <content:encoded><![CDATA[<p></p><p>I&#8217;ve written before about how we can end up getting so caught up in our great new idea, that we spend so long getting it just right, before we find out nobody wants it. This could apply to services, or a physical products.</p><p>I learnt this through my own hard experiences – I&#8217;ve been guilty of taking so long to develop and release an idea, that I was either too late, or the idea sounded great, yet nobody actually wants or needs it.</p><p>It could be the next best thing, but unless you have a market, it&#8217;ll only be the next big thing for you alone. Big companies know this, so they invest hundreds of thousands into market research before coming out with that new flavored cola drink or the improved service offering.</p><p>Unless you are very lucky, you don&#8217;t have that option, and to be honest, the way the world is evolving, perhaps it&#8217;s better to think small anyway. A colleague of mine years ago gave me some great advice; she suggested selling it to a few clients and then actually go to the stage of creating it. This seems like a scary move, but it is a far safer one.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Here&#8217;s my take on that advice &#8211; if you&#8217;ve got that next big thing idea, perhaps you should consider a crowd funding approach first? I loved the idea of sites like <a
href="http://www.kickstarter.com/">Kickstarter</a> when they first appeared on the scene a while back. However I always thought of them really as a very small marketplace.</p><p>That&#8217;s until I watched the <a
href="http://www.kickstarter.com/projects/597507018/pebble-e-paper-watch-for-iphone-and-android">Pebble watch</a> explosion. If you&#8217;ve not heard about it, you&#8217;ll want to. This company comes up with a great idea for a watch that interacts with your smartphone. It turns out to be one very exciting bit of wrist appliance. They believe they have the model right, they think it&#8217;ll do well, but where to get that $400,000 they need to make it a reality?</p><p>So, they turn to Kickstarter. They list the project, put high hopes they can raise four hundred thousand dollars (and this has to be spelt out – that is a LOT of money to anyone) and sit back to see if anyone really would pay $100 for a product like this.</p><p>Turns out, a lot of people would. In fact, 68,929 people are so enthusiastic about it, they pre-order over ten million dollars worth of them. That&#8217;s right; I&#8217;ll say it again in figures for you; $10,000,000.</p><p>Now they can start producing them, comfortable in the knowledge their first 68,000 customers are already reaching into their pockets.</p><p>OK, so it&#8217;s not quite as easy as coming up with an idea, listing it on a site like Kick Starter, and sitting back, however it&#8217;s not nearly as hard as it would have been without sites like Kick Starter.</p><p>Maybe you don&#8217;t have a physical product you wish to sell, yet you have a service you want to invest time and energy in, but don&#8217;t want to take the risk in doing all the work to find out that nobody actually wants it (like I have done).</p><p>Let&#8217;s learn from the Pebble watch lesson. Maybe instead of spending the next six months gearing up to offer a service or product that you hope your clients want, perhaps you could ask your existing customers instead.</p><p>One great way to do this (and once again, I&#8217;ve found out by trying this) is to actually approach a number of the ones you believe are most likely to purchase this service, and ask them if they would help you shape this service, and in exchange, you&#8217;ll give them a hefty discount for a period. Consider it your own consumer advice panel.</p><p>You can lean on their thoughts as prospective customers to find out what they are willing to pay, what they want it to do, and how they see you being able to market it. In fact, if you get them involve enough; they will help market it for you too.</p><p>This approach is likely not to make you ten million dollars in a month, but it will give you the confidence to know if it is worth your time and efforts to develop this new service or product or put it in the ‘great ideas that probably wont end up being profitable&#8217; basket.</p><p>Give it a go, see how it works, and if you do find a product or service idea that raises ten million dollars in a month, don&#8217;t forget where you got that inspiration from!</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=R8ZlX3XLLHc:ZIai1NWyMnA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=R8ZlX3XLLHc:ZIai1NWyMnA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=R8ZlX3XLLHc:ZIai1NWyMnA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=R8ZlX3XLLHc:ZIai1NWyMnA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/R8ZlX3XLLHc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/remove-risk-from-that-next-great-idea/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.sitepoint.com/remove-risk-from-that-next-great-idea/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=remove-risk-from-that-next-great-idea</feedburner:origLink></item> <item><title>Repurposing vs Optimized Design: It’s Not a Battle</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/F8wGCeLaNvM/</link> <comments>http://www.sitepoint.com/jakob-nielsen-repurposing-vs-optimized-design-feedback/#comments</comments> <pubDate>Wed, 23 May 2012 16:31:33 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Discussion]]></category> <category><![CDATA[Industry Links]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[Responsive Design]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54843</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/654-resized-image-dimensions-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="654-resized-image-dimensions" title="654-resized-image-dimensions" />Craig analyzes Jakob Nielsen's latest usability article, "Repurposing vs Optimized Design". Does it make a valid case against Responsive Design techniques?]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/654-resized-image-dimensions-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="654-resized-image-dimensions" title="654-resized-image-dimensions" /><p></p><p>Jakob Nielsen of <a
href="http://www.useit.com/">useit.com</a> is no stranger to controversy and his recent <a
href="http://www.useit.com/alertbox/repurposing.html"><em>Repurposing vs Optimized Design</em></a> article makes a bold statement:</p><blockquote><p>It&#8217;s cheap but degrading to reuse content and design across diverging media forms like print vs online or desktop vs mobile. Superior UX requires tight platform integration.</p></blockquote><p>Jakob states there are two opposing schools:</p><ul><li><strong>Repurposing (responsive design):</strong> make as few designs as possible and reuse the same material across platforms. This has cost advantages, but results in a substandard user experience.</li><li><strong>Platform optimization (device-specific design):</strong> create different user interfaces for each platform and integrate the user experience layers as tightly as possible. The result: higher costs but better usability and bigger profits.</li></ul><p>The article resulted in a Tweetstorm:</p><blockquote><p> Jakob Nielsen analyzes Responsive Design and comes up with dumb conclusions. Again.</p><p>For 17 years, Jakob Nielsen has been citing his own work as proof of everything. Somebody make it stop.</p><p>I&#8217;ve thought Jakob Nielsen was a self-important snob for years. Glad to see the Cult of Nielsen crumbling at last.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Do people still pay any attention to Jakob Nielsen or is he hanging around just to annoy web developers?</p><p>Jakob Nielsen is 100% right on mobile. Says Jakob Nielsen.</p><p>It&#8217;s amazing to watch Jakob Nielsen make himself more and more irrelevant with almost every piece he writes.</p></blockquote><h2>The Weaknesses of Responsive Design</h2><p>Jakob claims most responsive websites are too primitive. They rearrange the same content and change dimensions of some elements, but rarely:</p><ul><li>Adapt the content, i.e. provide shorter and simpler articles for mobile.</li><li>Use alternative, cropped or zoomed images.</li><li>Cater for touch input.</li><li>Reduce or modify the feature set to suit smaller devices.</li></ul><p>Websites should consider the user context. Requirements change depending on where a user is, what they&#8217;re doing and what device they&#8217;re using. Consider the website for a bus company; a desktop user may want to browse timetables whereas a mobile user may need to find the nearest station.</p><p>Jakob admits this could be achieved with responsive techniques but, once you account for all these differences, you effectively have two separate designs. But he makes a valid point: if potential revenue is greater than cost, a site designed specifically for mobile devices makes good business sense.</p><h2>Calculating Potential Revenue</h2><p>This is where Jakob&#8217;s argument breaks down. For most websites, the cost of developing a separate mobile site makes no commercial sense whatsoever. This is especially true when you consider Jakob&#8217;s suggestion of creating and maintaining two or more sets of content.</p><p>The majority of websites receive few mobile users &#8212; usually less than 10% of visitors. It may be increasing, but does it make commercial sense to throw money at a problem which does not yet exist and is subject to radical technical changes? I&#8217;m all for being pro-active, but this leads to another point: <em>you cannot make assumptions about user a user&#8217;s habits, desires or requirements</em>.</p><p>Jakob paints a black and white picture: mobile users want less content and simpler features. However, it&#8217;s impossible to determine context when all you actually know is the screen resolution. The situation is made more difficult with newer mobiles which have screen sizes approaching those of tablets and the relatively diminutive iPad 3 exceeds the resolution of a top-end desktop PC. You may be able to make context judgments based on the current time or GPS location but, ultimately, you don&#8217;t know whether the user is rushing for a bus or lying in bed.</p><h2>The Strength of Responsive Design</h2><p>Responsive design provides a solution. A website primarily designed for desktop use can be restructured to provide a mobile-friendly experience at minimal expense. It may not be perfect, but it opens access and your site isn&#8217;t restricted to certain devices or user groups.</p><p>It&#8217;s a starting point &#8212; not the end. It&#8217;s now possible to gather statistics about devices and tie them to typical user journeys. If you can establish that X% of access is from a smartphone and Y% of those users proceed to feature Z, you may be able to justify further development. In extreme cases, a standalone mobile site will aid usability and increase profitability.</p><h2>It&#8217;s Not a Battle</h2><p>Jakob makes two broad assumptions but the reality is not as clear-cut:</p><ol><li><em>You have a mobile context or a desktop context.</em><p>There are thousands of differing devices, screen sizes and situations when they are used. People use their mobile while watching TV &#8212; should they always receive a summarized article? Mobile exceeds desktop usage in many African countries because it&#8217;s cost-effective and reliable &#8212; should they be offered restricted functionality?</li><li><em>Repurposing and optimizing designs are opposing technologies.</em><p>Why? There are an infinite number of ways to develop the same solution. An optimized design can still use responsive techniques and vice versa. Ultimately, either can be used in differing quantities to achieve the same goal.</li></ol><p>Jakob has been accused of bashing responsive design. The tone of his article gives that impression and it detracts from his main point: <em>a dedicated mobile design offers a better mobile experience</em>. If he&#8217;s guilty of anything, it&#8217;s stating the obvious.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=F8wGCeLaNvM:11wKR-Dxp5g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=F8wGCeLaNvM:11wKR-Dxp5g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=F8wGCeLaNvM:11wKR-Dxp5g:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=F8wGCeLaNvM:11wKR-Dxp5g:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/F8wGCeLaNvM" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/jakob-nielsen-repurposing-vs-optimized-design-feedback/feed/</wfw:commentRss> <slash:comments>21</slash:comments> <feedburner:origLink>http://www.sitepoint.com/jakob-nielsen-repurposing-vs-optimized-design-feedback/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=jakob-nielsen-repurposing-vs-optimized-design-feedback</feedburner:origLink></item> <item><title>Scalable Vector Graphics: Drawing Basics</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/dpLfn6aaSqM/</link> <comments>http://www.sitepoint.com/svg-drawing-basics/#comments</comments> <pubDate>Tue, 22 May 2012 16:38:16 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Client Side Coding]]></category> <category><![CDATA[Design]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Responsive Web Design]]></category> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Web Design Tutorials & Articles]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[graphics]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[SVG]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54645</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/672-svg-basics-50x50.png" class="attachment-thumbnail wp-post-image" alt="672-svg-basics" title="672-svg-basics" />Craig's latest tutorial explains how to create SVG images and add simple drawing elements with nothing more than a text editor.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/672-svg-basics-50x50.png" class="attachment-thumbnail wp-post-image" alt="672-svg-basics" title="672-svg-basics" /><p></p><p>In my previous posts we discussed <a
href="http://www.sitepoint.com/svg-scalable-vector-graphics-overview/">what SVGs are</a> and <a
href="http://www.sitepoint.com/7-reasons-to-consider-svgs-instead-of-canvas/">reasons you should consider SVGs for your project</a>. In this article we&#8217;ll look at the basic concepts, document structure and drawing elements.</p><h2>SVG Co-ordinate Space</h2><p>An SVG is defined in whatever co-ordinate space you give it. That space does not necessarily relate to pixels, cm, inches or other units because the images are scalable to any dimension.</p><p>Optionally, you can define a viewbox which determines the co-ordinates your SVG uses. The following SVGs would look identical:</p><ul><li>An SVG with a viewbox of 0,0 to 200,100 with a line from 0,0 to 100,50.</li><li>An SVG with a viewbox of 0,0 to 300,150 with a line from 0,0 to 150,75.</li></ul><p><img
src="http://blogs.sitepointstatic.com/images/tech/675-svg-drawing-space.png" width="300" height="267" alt="SVG drawing space" class="center" /></p><p>Your images are rendered within a viewport, i.e. the whole browser window or a block in an HTML page. By default, an SVG viewbox will stretch in either direction to fill the viewport space. However, you can state that you want the aspect ratio preserved.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Unlike mathematical graphs, the SVG co-ordinate system starts at the top left (usually 0,0) with the x-axis pointing right and y-axis pointing down. Therefore, a point at 100,200 represents 100 units to the right of the left hand edge and 200 units down from the top edge.</p><h2>SVG Length Units</h2><p>Lengths in SVG can be specified either as:</p><ul><li>a relative value in the SVG space, e.g. 10</li><li>an absolute or relative measurement, e.g. 10px. SVG supports em, ex, px, pt, pc, cm, mm, in and percentage units.</li></ul><p>If your image will be scaled, use units which are relative to your viewbox, e.g. a line width of 10 within a 100&#215;100 viewbox will be 10% of the full width/height.</p><h2>SVG XML Document</h2><p>An SVG image is defined as an XML document. Assuming you&#8217;re creating a new SVG file, such as <a
href="http://blogs.sitepointstatic.com/examples/tech/svg-basics/image.svg">image.svg</a>, an XML declaration and doctype must appear at the top of the document:</p><pre><code>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;!DOCTYPE svg PUBLIC &quot;-//W3C//DTD SVG 1.1//EN&quot; &quot;http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&quot;&gt;
</code></pre><p>This is followed by the root SVG element:</p><pre><code>
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
</code></pre><p>Several <a
href="http://www.w3.org/TR/SVG11/struct.html#SVGElement">optional attributes can be applied to the svg element</a>. Two important ones are:</p><ul><li><a
href="http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute">viewBox</a>: establish the dimensions &#8212; a rectangular co-ordinate area used for your image specified as &#8220;min-X min-Y width and height&#8221;, e.g. <code>viewBox="0 0 600 400"</code>. It&#8217;s important to remember this is an abstract space; it does not relate to pixels and your drawing elements are not constrained within these co-ordinates.</li><li><a
href="http://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute">preserveAspectRatio</a>: defines how a viewbox is scaled. There are many options, for example <code>preserveAspectRatio="xMidYMid meet"</code> ensures the middle of an SVG&#8217;s viewbox is aligned with the middle of the viewport (the browser window or HTML element containing the SVG) and the image fits the space available while preserving its aspect ratio.</li></ul><p>An optional title and description can be defined using <code>title</code> and <code>desc</code> elements. Our basic XML document is therefore:</p><pre><code>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;!DOCTYPE svg PUBLIC &quot;-//W3C//DTD SVG 1.1//EN&quot; &quot;http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&quot;&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 600 400&quot; preserveAspectRatio=&quot;xMidYMid meet&quot;&gt;
	&lt;title&gt;My First Scalable Vector Graphic&lt;/title&gt;
	&lt;desc&gt;An experimental SVG from SitePoint.com&lt;/desc&gt;
	&lt;!-- drawing elements to go here --&gt;
&lt;/svg&gt;
</code></pre><h2>Grouping Elements</h2><p>Any set of elements (lines, circles, rectangles, text, etc.) can be grouped using <code>&lt;g&gt; &hellip; &lt;/g&gt;</code> tags. In essence, it&#8217;s identical to grouping drawing objects in a graphics package so they can be manipulated as a single item.</p><p>Personally, I prefer to define a root group node so I can modify the whole image easily via JavaScript or CSS, e.g.</p><pre><code>
&lt;g id=&quot;main&quot;&gt;
	&lt;!-- drawing elements to go here --&gt;
&lt;/g&gt;
</code></pre><p>A single group can have any number of nested inner groups.</p><h2>Lines</h2><p>A single line between two points is drawn using the <code>line</code> element:</p><pre><code>
&lt;line x1=&quot;10&quot; y1=&quot;10&quot; x2=&quot;100&quot; y2=&quot;200&quot;
stroke=&quot;#999&quot; stroke-width=&quot;5&quot; stroke-linecap=&quot;round&quot; /&gt;
</code></pre><p>The stroke-linecap attribute defines the line-end effect and accepts values of butt (the default), round, square or inherit:</p><p><img
src="http://www.w3.org/TR/SVG11/images/painting/linecap.png" alt="SVG stroke-linecap" class="center" /></p><h2>Polylines</h2><p>Polylines define a set of connected straight line segments:</p><pre><code>
&lt;polyline points=&quot;580,10 560,390 540,200 520,390 400,390&quot;
stroke=&quot;#c00&quot; stroke-width=&quot;5&quot; stroke-linecap=&quot;round&quot;
stroke-linejoin=&quot;round&quot; fill=&quot;none&quot; /&gt;
</code></pre><p>The stroke-linejoin attribute defines the line-joining effect and accepts values of miter (the default), round, bevel or inherit:</p><p><img
src="http://www.w3.org/TR/SVG11/images/painting/linejoin.png" alt="SVG stroke-linejoin" class="center" /></p><h2>Polygons</h2><p>Polygons are are similar to polylines except that the resulting shape will always be closed:</p><pre><code>
&lt;polygon points=&quot;350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161&quot;
stroke=&quot;#ff0&quot; stroke-width=&quot;10&quot; fill=&quot;#ff6&quot; /&gt;
</code></pre><h2>Rectangles</h2><p>Square or rounded rectangles are defined using the <code>rect</code> element:</p><pre><code>
&lt;rect x=&quot;100&quot; y=&quot;10&quot; width=&quot;150&quot; height=&quot;100&quot; rx=&quot;10&quot; ry=&quot;20&quot;
stroke=&quot;#060&quot; stroke-width=&quot;8&quot; fill=&quot;#0f0&quot; /&gt;
</code></pre><p>The x and y attributes define the top-left corner. rx and ry specify the horizontal and vertical corner rounding.</p><h2>Circles</h2><p>Circles are defined using a center point and radius:</p><pre><code>
&lt;circle cx=&quot;100&quot; cy=&quot;300&quot; r=&quot;80&quot;
stroke=&quot;#909&quot; stroke-width=&quot;10&quot; fill=&quot;#f6f&quot; /&gt;
</code></pre><h2>Ellipses</h2><p>Ellipses are defined using a center point and two radii values:</p><pre><code>
&lt;ellipse cx=&quot;450&quot; cy=&quot;50&quot; rx=&quot;80&quot; ry=&quot;30&quot;
stroke=&quot;#0cc&quot; stroke-width=&quot;10&quot; fill=&quot;#0ff&quot; /&gt;
</code></pre><h2>Text</h2><p>Basic text can be added using the <code>text</code> element:</p><pre><code>
&lt;text x=&quot;240&quot; y=&quot;390&quot; font-family=&quot;sans-serif&quot; font-size=&quot;50&quot; fill=&quot;#00f&quot;&gt;SVG&lt;/text&gt;
</code></pre><p>The x and y attributes define the bottom-left co-ordinate of the first character in the string.</p><h2>The Result</h2><p>Our final SVG document contains the following XML code:</p><pre><code>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;!DOCTYPE svg PUBLIC &quot;-//W3C//DTD SVG 1.1//EN&quot; &quot;http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&quot;&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 600 400&quot; preserveAspectRatio=&quot;xMidYMid meet&quot;&gt;
	&lt;title&gt;My First Scalable Vector Graphic&lt;/title&gt;
	&lt;desc&gt;An experimental SVG from SitePoint.com&lt;/desc&gt;
	&lt;g id=&quot;main&quot;&gt;
		&lt;line x1=&quot;10&quot; y1=&quot;10&quot; x2=&quot;100&quot; y2=&quot;200&quot; stroke=&quot;#00c&quot; stroke-width=&quot;5&quot; stroke-linecap=&quot;round&quot; /&gt;
		&lt;polyline points=&quot;580,10 560,390 540,200 520,390 400,390&quot; stroke=&quot;#c00&quot; stroke-width=&quot;5&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; fill=&quot;none&quot; /&gt;
		&lt;polygon points=&quot;350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161&quot; stroke=&quot;#ff0&quot; stroke-width=&quot;10&quot; fill=&quot;#ffc&quot; /&gt;
		&lt;rect x=&quot;100&quot; y=&quot;10&quot; width=&quot;150&quot; height=&quot;100&quot; rx=&quot;10&quot; ry=&quot;20&quot; stroke=&quot;#060&quot; stroke-width=&quot;8&quot; fill=&quot;#0f0&quot; /&gt;
		&lt;circle cx=&quot;100&quot; cy=&quot;300&quot; r=&quot;80&quot; stroke=&quot;#909&quot; stroke-width=&quot;10&quot; fill=&quot;#f6f&quot; /&gt;
		&lt;ellipse cx=&quot;450&quot; cy=&quot;50&quot; rx=&quot;80&quot; ry=&quot;30&quot; stroke=&quot;#0cc&quot; stroke-width=&quot;10&quot; fill=&quot;#0ff&quot; /&gt;
		&lt;text x=&quot;240&quot; y=&quot;390&quot; font-family=&quot;sans-serif&quot; font-size=&quot;50&quot; fill=&quot;#00f&quot;&gt;SVG&lt;/text&gt;
	&lt;/g&gt;
&lt;/svg&gt;
</code></pre><p>and renders this image:</p><p><a
href="http://blogs.sitepointstatic.com/examples/tech/svg-basics/image.svg"><br
/> <img
src="http://blogs.sitepointstatic.com/images/tech/675-svg-drawing-screen.png" width="407" height="274" alt="SVG example" class="center" style="block" /><p
class="center">click to view the actual SVG</p><p></a></p><p>While this is a simple example, the file is 1,176 bytes <strong>before</strong> minification and gzipping. The equivalent compressed PNG above is 5,611 bytes &#8212; it&#8217;s almost 5x larger and cannot be scaled above its native 407&#215;274 resolution without losing quality.</p><p>Further Scalable Vector Graphic articles will appear on SitePoint soon&hellip;</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=dpLfn6aaSqM:Tij8rW3f3jo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=dpLfn6aaSqM:Tij8rW3f3jo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=dpLfn6aaSqM:Tij8rW3f3jo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=dpLfn6aaSqM:Tij8rW3f3jo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/dpLfn6aaSqM" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/svg-drawing-basics/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://www.sitepoint.com/svg-drawing-basics/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=svg-drawing-basics</feedburner:origLink></item> <item><title>Beginners Guide to KnockoutJS: Part 1</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/wusvkN75QhU/</link> <comments>http://www.sitepoint.com/beginners-guide-to-knockoutjs-part-1/#comments</comments> <pubDate>Tue, 22 May 2012 15:00:30 +0000</pubDate> <dc:creator>Ivaylo Gerchev</dc:creator> <category><![CDATA[JavaScript]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54137</guid> <description><![CDATA[<img
width="50" height="33" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/Screen-Shot-2012-05-09-at-3.29.29-PM-50x33.png" class="attachment-thumbnail wp-post-image" alt="Screen Shot 2012-05-09 at 3.29.29 PM" title="Screen Shot 2012-05-09 at 3.29.29 PM" />Almost everyone dealing with web technologies knows jQuery, or has heard of it, and while powerful it is not ideal for building Rich Internet Applications. And this is where Knockout.js shines through.]]></description> <content:encoded><![CDATA[<img
width="50" height="33" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/Screen-Shot-2012-05-09-at-3.29.29-PM-50x33.png" class="attachment-thumbnail wp-post-image" alt="Screen Shot 2012-05-09 at 3.29.29 PM" title="Screen Shot 2012-05-09 at 3.29.29 PM" /><p></p><h1>A Beginners Guide to KnockoutJS: Basics and Observables</h1><p>Almost everyone dealing with web technologies knows jQuery, or at least has heard about it. Its unmatched simplicity and conciseness makes the lives of millions of web developers all over the world much easier–and that&#8217;s fantastic.</p><p>Unfortunately jQuery is not solution for every problem. As soon as you decide to create some more complex web apps you encounter a problem &#8211; there is no easy way to make your UI and data communicate each other dynamically. With the low-level DOM manipulation and events handling provided by jQuery this is fairly hard to achieve. You need a library providing you with more sophisticated way of communication between your UI and the underlying data model.</p><p>And here is where <a
href="http://knockoutjs.com/">Knockout</a> comes in. Knockout is a JavaScript library which helps the creation of rich, desktop-like web UIs. It simplifies user interactions and makes interfaces fully responsive to any data source changes. Knockout provides a simple two-way binding mechanism to link a data model to an UI, thus making synchronization between them a breeze.</p><p>Although you will need to use Knockout with jQuery at the same time, in some cases like animated transitions, Knockout itself doesn&#8217;t depend on it. Another thing you need to understand is that Knockout doesn&#8217;t compete with jQuery &#8211; they both do excellent job; each one in its own direction. As you will see if you want to get the most benefits you should use them together.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>In this tutorial, we start with the core concepts and capabilities of Knockout. In part two, we&#8217;ll go deeper exploring the built-in bindings and how to use them. And in the finale, we&#8217;ll go through some advanced features and techniques, such as extended observables and how to create your own custom bindings. Let&#8217;s get started!</p><h2>Basic Concepts</h2><p>Before we go through the code examples, first you may need to grasp some basic concepts. Knockout implements Model-View-View Model (MVVM) design pattern for JavaScript. In this pattern your application is split into three parts:</p><p>A model that holds your application&#8217;s data. This can be data entered by users or JSON data fetched from a web server.</p><p>A view that serves as a connector and communication layer between Model and View. It holds data and operations for manipulating this data and display it in the UI. Every time when data model is changed corresponded UI parts updates, reflecting these changes. View Model in your application is represented by JavaScript code.</p><p>A view that refers to all UI elements in your application. It is a representation of the structure and appearance for given UI. The view is responsible for displaying data and accepting user input. View is represented by HTML/CSS code in your application.</p><p>They are three core concepts upon Knockout is built:</p><p><strong>1. Declarative Bindings:</strong> These allow you to connect parts of your UI to your data model in a simple and convenient way. When use JavaScript directly to manipulates DOM this may cause broken code if you later change the DOM hierarchy or element IDs. With declarative bindings even if you change the DOM all bound pieces stay connected. You can bind data to a DOM by simply including a data-bind attribute to any DOM element.</p><p><strong>2. Dependency Tracking:</strong> Thankfully to the bindings and special type of variables called observables every time when your model data has changed all parts associated with it automatically being updated. No need to worry about adding event handlers and listeners. All that extra work is performed internally by Knockout and observables, which notify listeners when underlying values have changed.</p><p><strong>3. Templating:</strong> This comes in handy when your application becomes more complex and you need a way to display a rich structure of view model data, thus keeping your code simple. Knockout has a native, built-in template engine which you can use right away. But if you want, a third-party template engine, like jquery.tmpl or Underscore, also can be used.</p><p>Don&#8217;t worry if all this theory sounds obscure to you. When we go through the tutorial and the code examples everything will become clearer.</p><h2>Getting Started</h2><p>Before we dive into Knockout you need to <a
href="https://github.com/SteveSanderson/knockout/downloads">download</a> and reference the library in your HTML document.</p><pre>&lt;script type='text/javascript' src='knockout-2.0.0.js'&gt;&lt;/script&gt;
</pre><p>To keep your code separate from your presentation is better to create a JavaScript file to hold all application code. And because we will use jQuery in some cases you need to reference it too.</p><pre>&lt;script type='text/javascript' src='jquery-1.7.1.min.js'&gt;&lt;/script&gt;
&lt;script type='text/javascript' src='knockout-2.0.0.js'&gt;&lt;/script&gt;
&lt;script type='text/javascript' src='application.js'&gt;&lt;/script&gt;
</pre><p>This is considered as best practice but for training purpose and to make things easier you can put the JavaScript code in the same document by either including it in the head tag or place it bellow your markup.</p><p>Now, to create a view model just declare any JavaScript object like this:</p><pre>  function viewModel() {
   // Your code here
  };</pre><p>The data-bind attribute (explained later) isn&#8217;t native to HTML, and the browser doesn&#8217;t know what it means. So in order to take effect Knockout has to be activated by inserting <code>ko.applyBindings()</code> function at the end of the script. Also if you use external JavaScript file or your script is placed in the head tag of your document you need to wrap the Knockout code in a jQuery ready function in order to work properly. Here is the basic template to start:</p><pre>
$(document).ready(function(){
  function viewModel() {
   // Your code here
  };
  ko.applyBindings(new viewModel());
});</pre><p>Calling the <code>ko.applyBindings()</code> method and passing in our view model tells Knockout to bind the specified model to our UI. You can even provide a DOM element if you only want to bind this view model to one part of your overall UI. <code>ko.applyBindings()</code> takes two parameters. The first parameter says what view model object you want to use with the declarative bindings it activates. The second parameter is optional and it defines which part of the document you want to search for data-bind attributes. For example, <code>ko.applyBindings(viewModel, document.getElementById('container'))</code> will restrict the activation to the element with ID container and its descendants. This is useful if you want to have multiple view models and associate each with a different region of the page.</p><h2>How It Works</h2><p>With Knockout, you can bind data to a DOM element by including a data-bind attribute in the markup which specifies the data-binding to perform. The code never has any reference to the DOM structure so you can freely change the HTML without breaking your bindings. In the following example we add text data-bind attribute to <code>span</code> element like this:</p><pre>
// syntax: data-bind=&quot;bindingName: bindingValue&quot;
&lt;p&gt;The day of the week is &lt;span data-bind=&quot;text: dayOfWeek&quot;&gt;&lt;/span&gt;. It's time for &lt;span data-bind=&quot;text: activity&quot;&gt;&lt;/span&gt;&lt;/p&gt;
</pre><p>Then if we want to make the value of text to updates dynamically then we have to declare it in our view model as an observable.</p><pre>function viewModel() {
  this.dayOfWeek = ko.observable('Sunday');
  this.activity = ko.observable('rest');
};
ko.applyBindings(new viewModel());
</pre><p>This will output &quot;The day of the week is Sunday. It&#8217;s time for rest&quot;.</p><h2>Observables</h2><p>Knockout implements observable properties by wrapping object properties with a custom function named <code>ko.observable()</code>.</p><pre>this.property = ko.observable('value')</pre><p>Observables are set as functions. As such you can use them in the following manner:</p><pre>
// To read the observable's current value, just call the observable with no parameters.
// The following will return Sunday
this.dayOfWeek()
// To write a new value to the observable, call the observable and pass the new value as a parameter.
// The following will change the day of week to Monday
this.dayOfWeek('Monday')
// To write values to multiple observable properties on a model object, you can use chaining syntax.
this.dayOfWeek('Monday').activity('work')
</pre><p>Knockout doesn&#8217;t require you to use observable properties. If you want DOM elements to receive values once but then not be updated when the values in the source object change, simple objects will be sufficient. However, if you want your source object and target DOM elements to stay in sync &#8211; two-way binding &#8211; then you&#8217;ll want to consider using observable properties.</p><p>In some cases you may need to combine the values of two or more observables into one new value. This can be done with so-called computed observables. Computed observables are functions that are dependent on one or more other observables, and will automatically update whenever any of these dependencies change. The computed property automatically updates when any of the observables it depends on for its evaluation change. In the following example the computed observable named <code>fullDate</code> will updates every time when one or more of the <code>day</code>, <code>month</code> and <code>year</code> observables change.</p><pre>
&lt;p&gt;Day: &lt;input data-bind=&quot;value: day&quot; /&gt;&lt;/p&gt;&lt;p&gt;Month: &lt;input data-bind=&quot;value: month&quot; /&gt;&lt;/p&gt;&lt;p&gt;Year: &lt;input data-bind=&quot;value: year&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The current date is &lt;span data-bind=&quot;text: fullDate&quot;&gt;&lt;/span&gt;&lt;/p&gt;
function viewModel() {
  this.day = ko.observable('24');
  this.month = ko.observable('02');
  this.year = ko.observable('2012');
  this.fullDate = ko.computed(function() {
   return this.day() + &quot;/&quot; + this.month() + &quot;/&quot; + this.year();
  },this);
};
ko.applyBindings(new viewModel()); </pre><p>The <code>ko.computed()</code> takes a second parameter <code>this</code>. Without passing it in, it would not have been possible to refer to <code>this.day()</code>, <code>this.month()</code> or <code>this.year()</code>. In order to simplify things you can create a variable <code>self</code>, thus avoiding the addition of the second parameter. From now on we will use this approach in the code examples.</p><pre>function viewModel() {
  var self = this;
  self.day = ko.observable('24');
  self.month = ko.observable('02');
  self.year = ko.observable('2012');
  self.fullDate = ko.computed(function() {
   return self.day() + &quot;/&quot; + self.month() + &quot;/&quot; + self.year();
  });
};
ko.applyBindings(new viewModel());
</pre><p>When you dealing with one object you can easily track any changes to it by turn it into an observable. But what if you have multiple objects? In such cases Knockout has a special object called <code>ko.observableArray()</code>, which can detect and respond to changes of a collection of things. This makes possible to display and/or edit multiple values, for example, when you need repeated sections of UI to appear and disappear as items are added and removed.</p><p>You should bear in mind that an observable array tracks which objects are in the array, not the state of those objects. Simply putting an object into an observable array doesn&#8217;t make all of that object&#8217;s properties themselves observable. If you wish you can make those properties observable, but that&#8217;s totally up to you. An observable array just tracks which objects it holds, and notifies listeners when objects are added or removed.</p><pre>this.property = ko.observableArray();</pre><p>When you create an observable array you can leave it empty or populate it with some initial values. In the following example we create an observable array populated with the days of the week:</p><pre>
&lt;p&gt;Today is &lt;span data-bind=&quot;text: daysOfWeek()[0]&quot;&gt;&lt;/span&gt;&lt;/p&gt;
function viewModel() {
  var self = this;
  self.daysOfWeek = ko.observableArray([
  'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
  ]);
  alert(&quot;The week has &quot; + self.daysOfWeek().length + &quot; days&quot;);
};
ko.applyBindings(new viewModel());</pre><p>As you can see, to read and write Knockout array you can use any native JavaScript functions. But Knockout has its own equivalent functions which syntax is a little bit more convenient:</p><pre>array().push('Some value'); // native JavaScript
array.push('Some value'); // Knockout</pre><p>For the full list of available functions you can check out the <a
href="http://knockoutjs.com/documentation/observableArrays.html">documentation</a>.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=wusvkN75QhU:l95Hy0-KNWI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=wusvkN75QhU:l95Hy0-KNWI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=wusvkN75QhU:l95Hy0-KNWI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=wusvkN75QhU:l95Hy0-KNWI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/wusvkN75QhU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/beginners-guide-to-knockoutjs-part-1/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.sitepoint.com/beginners-guide-to-knockoutjs-part-1/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=beginners-guide-to-knockoutjs-part-1</feedburner:origLink></item> <item><title>Get Tweeting and win a Kindle Fire at Web Directions Code!</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/ktfMbll-Yjg/</link> <comments>http://www.sitepoint.com/get-tweeting-and-win-a-kindle-fire-at-web-directions-code/#comments</comments> <pubDate>Tue, 22 May 2012 03:40:52 +0000</pubDate> <dc:creator>Tom Museth</dc:creator> <category><![CDATA[Web Tech]]></category> <category><![CDATA[Community]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Design]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[WordPress]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54794</guid> <description><![CDATA[At SitePoint we live and breathe web tech &#8230; and we love our ebooks. Combining these two passions is a challenge we relish, whether we&#8217;re releasing an all-encompassing guide to the world of WordPress (like The WordPress Anthology), an analysis of cutting-edge design approaches (say, The Principles of Beautiful Web Design) or an introduction to [...]]]></description> <content:encoded><![CDATA[<p></p><p>At SitePoint we live and breathe web tech &#8230; and we love our ebooks. Combining these two passions is a challenge we relish, whether we&#8217;re releasing an all-encompassing guide to the world of WordPress (like <em>The WordPress Anthology</em>), an analysis of cutting-edge design approaches (say, <em>The Principles of Beautiful Web Design</em>) or an introduction to the latest web development standards and methods (for instance, <em>HTML5 &amp; CSS3 For the Real World</em>).</p><p>Which is why we decided we ought to share these passions with our treasured SitePoint community &#8211; especially those of you who are attending the bound-to-be-awesome Web Directions Code conference, taking place in Melbourne on Wednesday, May 23 and Thursday, May 24. We&#8217;re sending a whole bunch of SitePoint staffers along to this two-day festival of all things JavaScript and HTML5 (check out the <a
title="Web Directions Code" href="http://code12melb.webdirections.org/" target="_blank">program</a>) where we&#8217;ll be attending excellent talks from the likes of Max Wheeler, Ryan Seddon and Rob Hawkes, to name a few. But our crew are also going to be hoping you&#8217;ll hook up with them and enter our SitePoint Twitaway Competition! Check out the details on the <a
title="SitePoint Twitaway Competition" href="http://www.sitepoint.com/wdc/" target="_blank">Twitaway Competition page</a>.</p><p>Here&#8217;s how it works.</p><ul><li>When you&#8217;re at the conference, look out for a SitePoint staffer (you can find us wandering around in our T-shirts, probably armed to the teeth with books, mugs and other SitePoint gear we&#8217;re itching to give away). Who&#8217;ll be there? Louis, Tom, Di, Alex, Harley and Ole. We&#8217;re waiting to meet you.</li><li>Grab one of us &#8230; but be gentle.</li><li>Take a photo of yourself with said SitePointer.</li><li>Send a unique, funny tweet, with your photo and the hashtag <strong>#lovesitepoint</strong>.</li><li>That&#8217;s it &#8230; unless, of course, you want to stick around and have a chat with us!</li></ul><p>This will put you in the running for our great giveaway: a Kindle Fire, which we&#8217;ll hand over to the winner on the Thursday afternoon, and happily load up with a whole bunch of SitePoint ebooks.</p><p>But wait &#8230; &#8216;cos there&#8217;s more. Everyone who sends a tweet with a photo and the <strong>#lovesitepoint</strong> hashtag will win an ebook anyway. Why? Well, because you deserve it. And we want you to be awesome developers &#8230; something we hope we can give you a hand with when you choose one ebook from the following: <em>The WordPress Anthology</em>, <em>The Principles of Beautiful Web Design</em>, or <em>HTML5 &amp; CSS3 For the Real World</em>.</p><p>The details are all on the <a
title="SitePoint Twitaway Competition" href="http://www.sitepoint.com/wdc/" target="_blank">promotion page</a>. All you have to do is get to Web Directions Code, hunt us down and get tweeting!</p><p>&nbsp;</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ktfMbll-Yjg:0n7cK3mHyJI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ktfMbll-Yjg:0n7cK3mHyJI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ktfMbll-Yjg:0n7cK3mHyJI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=ktfMbll-Yjg:0n7cK3mHyJI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/ktfMbll-Yjg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/get-tweeting-and-win-a-kindle-fire-at-web-directions-code/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/get-tweeting-and-win-a-kindle-fire-at-web-directions-code/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=get-tweeting-and-win-a-kindle-fire-at-web-directions-code</feedburner:origLink></item> <item><title>Create a Voting Plugin for WordPress</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/o2CI1Vqgnyg/</link> <comments>http://www.sitepoint.com/create-a-voting-plugin-for-wordpress/#comments</comments> <pubDate>Mon, 21 May 2012 15:00:36 +0000</pubDate> <dc:creator>Abbas Suterwala</dc:creator> <category><![CDATA[ajax]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[wordpress]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54290</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2010/06/wordpress-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="Wordpress Logo" title="Wordpress Logo" />Introduction WordPress, as a platform, has moved from only being a blogging platform, to a platform for a wide variety of websites. One major reason for this, is how easily WordPress can be customized and extended. This enables programmers to create far more functional sites than a normal blog. In the following tutorial we are [...]]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2010/06/wordpress-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="Wordpress Logo" title="Wordpress Logo" /><p></p><p><strong>Introduction</strong></p><p>WordPress, as a platform, has moved from only being a blogging platform, to a platform for a wide variety of websites. One major reason for this, is how easily WordPress can be customized and extended. This enables programmers to create far more functional sites than a normal blog. In the following tutorial we are going to create a plugin which will make wordpress an article voting site and also create a widget to display the top voted posts.</p><h2>Creating the Plugin</h2><p>To create a plugin create a file voteme.php in your wp-content/plugins/voteme folder. To create a plugin we have to add the plugin header as follows</p><pre>&lt;?php
/*
Plugin Name: Vote Me
Plugin URI:
Description: This plugin to add vote in posts
Author: Abbas
Version: 0.1
Author URI:
*/</pre><p>We will also define some named constants for our plugin base url, and the plugin path as follows:</p><pre>define('VOTEMESURL', WP_PLUGIN_URL."/".dirname( plugin_basename( __FILE__ ) ) );
define('VOTEMEPATH', WP_PLUGIN_DIR."/".dirname( plugin_basename( __FILE__ ) ) );</pre><p>Also, create a js folder in your voteme folder, and add a file voteme.js file in it.</p><p>The folder structure of the plugin would be as follows.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><a
href="http://www.sitepoint.com/?attachment_id=54291" rel="attachment wp-att-54291"><img
class="alignnone size-medium wp-image-54291" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/1-115x43.png" alt="" width="115" height="43" /></a></p><p>We will now enqueue the scripts by with &#8216;wp_enqueue_scripts&#8217; and enqueue our JS file, and localize it to store the WP Ajax url which we will use for our ajax calls.</p><pre>function voteme_enqueuescripts()
	{
		wp_enqueue_script('voteme', VOTEMESURL.'/js/voteme.js', array('jquery'));
		wp_localize_script( 'voteme', 'votemeajax', array( 'ajaxurl' =&gt; admin_url( 'admin-ajax.php' ) ) );
	}
add_action('wp_enqueue_scripts', voteme_enqueuescripts);</pre><p>After this we should be able to see our plugin in the plugin list and we should activate it.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54292" rel="attachment wp-att-54292"><img
class="alignnone size-full wp-image-54292" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/2.png" alt="" width="600" height="123" /></a></p><h2>Adding the vote link to posts</h2><p>Now we will add a link to all the posts displaying the current votes and a link to add the vote by ajax.<br
/> Following is the code</p><pre>function voteme_getvotelink()
{
$votemelink = "";
$post_ID = get_the_ID();
$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';
$link = $votemecount.' &lt;a onclick="votemeaddvote('.$post_ID.');"&gt;'.'Vote'.'&lt;/a&gt;';
$votemelink = '&lt;div id="voteme-'.$post_ID.'"&gt;';
$votemelink .= '&lt;span&gt;'.$link.'&lt;/span&gt;';
$votemelink .= '&lt;/div&gt;';
return $votemelink;
}
function voteme_printvotelink($content)
{
return $content.voteme_getvotelink();
}
add_filter('the_content', voteme_printvotelink);</pre><p>Here, we create a function <code>voteme_getvote</code> link which first gets the current post id and then reads the post meta <code>_votemecount</code> using <code>get_post_meta</code>. We use the post meta <code>_votemecount</code> to store the votes for a particular post. Then we create a link by adding the JavaScript function <code>votemeaddvote</code> on the click of the link. The function <code>votemeaddvote</code> we will see shortly.</p><p>Next, we use the WordPress filter <code>the_content</code> to hook our function to add this link after each post. You will be able to see the number of votes and vote link below each post now.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54293" rel="attachment wp-att-54293"><img
class="alignnone size-full wp-image-54293" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/3.png" alt="" width="600" height="209" /></a></p><h2>Adding votes using Ajax</h2><p>As we have added the vote link to every posts its time we make it functional to actually add votes. The JavaScript function which does the AJAX vote posting is below</p><pre>function votemeaddvote(postId)
{
	jQuery.ajax({
	type: 'POST',
	url: votemeajax.ajaxurl,
	data: {
	action: 'voteme_addvote',
	postid: postId
},
success:function(data, textStatus, XMLHttpRequest){
	var linkid = '#voteme-' + postId;
	jQuery(linkid).html('');
	jQuery(linkid).append(data);
	},
	error: function(MLHttpRequest, textStatus, errorThrown){
		alert(errorThrown);
		}
	});
}</pre><p>This sends an AJAX request to WordPress, and sends the action as <code>voteme_addvote</code> and the post ID. If the AJAX call is successful it just adds the data in the div for that post. If there is an error it will just display the error.</p><p>To handle the AJAX request we will have to create a function as follows</p><pre>function voteme_addvote()
	{
		$results = '';
		global $wpdb;
		$post_ID = $_POST['postid'];
		$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';
		$votemecountNew = $votemecount + 1;
		update_post_meta($post_ID, '_votemecount', $votemecountNew);
		$results.='&lt;div class="votescore" &gt;'.$votemecountNew.'&lt;/div&gt;';
		// Return the String
		die($results);
	}
		// creating Ajax call for WordPress
		add_action( 'wp_ajax_nopriv_voteme_addvote', 'voteme_addvote' );
		add_action( 'wp_ajax_voteme_addvote', 'voteme_addvote' );</pre><p>In function voteme_addvote we get the post ID from the posted data and then get the current vote count for that post. Then we increment the vote by 1 and update the post meta again. Then we create a div with the new vote details and sent that back by using die($results);</p><p>To register this function to handle AJAX request for action: &#8216;voteme_addvote&#8217; using the following wordpress hooks</p><pre>		// creating Ajax call for WordPress
		add_action( 'wp_ajax_nopriv_voteme_addvote', 'voteme_addvote' );
		add_action( 'wp_ajax_voteme_addvote', 'voteme_addvote' );</pre><p>Now we&#8217;ll be able to click the vote link to add the vote on the post with AJAX.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54295" rel="attachment wp-att-54295"><img
class="alignnone size-full wp-image-54295" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/4.png" alt="" width="600" height="220" /></a></p><h2>Customizing WordPress admin to show post votes</h2><p>It would be very convenient for the admin to be able to see the votes on the post edit page. Then from there he would be able to see the post details, and also the vote details on that page.</p><p>To add the vote details we need to add a hook on the filter &#8216;manage_edit-post_columns&#8217; to add the Votes as a column on the post edit page as follows.</p><pre>add_filter( 'manage_edit-post_columns', 'voteme_extra_post_columns' );
function voteme_extra_post_columns( $columns ) {
$columns[ 'votemecount' ] = __( 'Votes' );
return $columns;
}</pre><p>Now we need to provide the value to display for this column. To do this we need to hook into the filter <code>manage_posts_custom_column</code>. When we hook into this filter our function <code>voteme_post_column_row</code> is called and with the post column name. Here we only process out column <code>votemecount</code> and give the value for it. We read the value from our custom column <code>_votemecount</code> and echo it. The complete code for this is as follows.</p><pre>function voteme_post_column_row( $column ) {
	if ( $column != 'votemecount' )
	return;
	global $post;
	$post_id = $post-&gt;ID;
	$votemecount = get_post_meta($post_id, '_votemecount', true) != '' ? get_post_meta($post_id, '_votemecount', true) : '0';
	echo $votemecount;
}
add_action( 'manage_posts_custom_column', 'voteme_post_column_row', 10, 2 );</pre><p>On the post edit page you should be able to see the vote details column.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54296" rel="attachment wp-att-54296"><img
class="alignnone size-full wp-image-54296" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/5.png" alt="" width="600" height="274" /></a></p><h2>Sorting post on basics of votes in WordPress admin</h2><p>It would be convenient for the admin if we make the vote column sortable. He would be able to see the most voted posts and also the least voted posts. To do this first we must make the Vote column clickable for sorting. To do this we hook into the filter <code>manage_edit-post_sortable_columns</code> and add the vote column to it as follows.</p><pre>add_filter( 'manage_edit-post_sortable_columns', 'voteme_post_sortable_columns' );
function voteme_post_sortable_columns( $columns )
{
	$columns[ 'votemecount' ] = votemecount;
	return $columns;
}</pre><p>Then we add a hook onto the <code>load-edit.php</code> hook when we have the order by request for <code>votemecount</code> we merge the sort parameters with</p><pre>'meta_key' =&gt; '_votemecount',
'orderby' =&gt; 'meta_value_num'</pre><p>So that it sorts on the basics of custom column and considers that column as numeric rather than as a string. The code for it is as follows.</p><pre>add_action( 'load-edit.php', 'voteme_post_edit' );
function voteme_post_edit()
{
	add_filter( 'request', 'voteme_sort_posts' );
}
	function voteme_sort_posts( $vars )
{
	if ( isset( $vars['post_type'] ) &amp;&amp; 'post' == $vars['post_type'] )
	{
		if ( isset( $vars['orderby'] ) &amp;&amp; 'votemecount' == $vars['orderby'] )
		{
			$vars = array_merge(
			$vars,
			array(
			'meta_key' =&gt; '_votemecount',
			'orderby' =&gt; 'meta_value_num'
			)
			);
		}
	}
return $vars;
}</pre><p>Now in the admin page the vote column will be clickable and clicking on it will sort the post on the basics of votes.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54297" rel="attachment wp-att-54297"><img
class="alignnone size-full wp-image-54297" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/6.png" alt="" width="600" height="269" /></a></p><h2>Allowing only Registered users to vote</h2><p>We might want that not anyone can vote on the post. We might want to check that only users who are registered on our site will be able to vote. We&#8217;ll control this via creating a setting page for our plugin as follows</p><pre>// Settings
add_action('admin_menu', 'voteme_create_menu');
function voteme_create_menu() {
add_submenu_page('options-general.php','Vote Me','Vote Me','manage_options', __FILE__.'voteme_settings_page','voteme_settings_page');
}
function voteme_settings_page() {
?&gt;
&lt;div class="wrap"&gt;
&lt;?php
global $blog_id;
if( isset( $_POST['votemeoptionssubmit'] ) )
{
update_option( 'votemelogincompulsory' , $_POST[ 'votemelogincompulsory' ] );
}
?&gt;
&lt;div id="settingsform"&gt;
&lt;form id='votemesettingform' method="post" action=""&gt;
&lt;h1&gt;&lt;?php echo 'Vote Me Settings'; ?&gt;&lt;/h1&gt;
&lt;Input type = 'Radio' Name ='votemelogincompulsory' value= 'yes' &lt;?php if( get_option('votemelogincompulsory') == 'yes' ) echo 'checked';?&gt; &gt;User Must be logged in for voting
&lt;br/&gt;
&lt;Input type = 'Radio' Name ='votemelogincompulsory' value= 'no' &lt;?php if( get_option('votemelogincompulsory') != 'yes' ) echo 'checked';?&gt; &gt;User might not be logged in for voting
&lt;br/&gt;&lt;br/&gt;
&lt;p class="submit"&gt;
&lt;input type="submit" id="votemeoptionssubmit" name="votemeoptionssubmit" class="button-primary" value="&lt;?php echo 'Save'; ?&gt;" /&gt;
&lt;/p&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;?php }</pre><p>Here we hook onto <code>admin_menu</code> and create our setting page to show radio buttons for whether to allow voting for registered users only. Then based on the option selected by the admin we update the option <code>votemelogincompulsory</code>. The settings page will look as follows.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54299" rel="attachment wp-att-54299"><img
class="alignnone size-full wp-image-54299" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/7.png" alt="" width="383" height="517" /></a></p><p>Then, update the <code>voteme_getvotelink</code> function to read the option <code>votemelogincompulsory</code> and to show the votelink or the login link depending on the option selected by the user and wthere the user is logged in or no. The code for it is as follows</p><pre>function voteme_getvotelink()
{
	$votemelink = "";
	if( get_option('votemelogincompulsory') != 'yes' || is_user_logged_in() )
	{
		$post_ID = get_the_ID();
		$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';
		$link = $votemecount.' &lt;a onclick="votemeaddvote('.$post_ID.');"&gt;'.'Vote'.'&lt;/a&gt;';
		$votemelink = '&lt;div id="voteme-'.$post_ID.'"&gt;';
		$votemelink .= '&lt;span&gt;'.$link.'&lt;/span&gt;';
		$votemelink .= '&lt;/div&gt;';
	}
else
{
	$register_link = site_url('wp-login.php', 'login') ;
	$votemelink = '&lt;div class="votelink" &gt;'." &lt;a href=".$register_link."&gt;"."Vote"."&lt;/a&gt;".'&lt;/div&gt;';
}
return $votemelink;
}</pre><h2>Creating a widget to display Top voted posts.</h2><p>Now we will create a widget to display the top voted posts. First we create a function called <code>voteme_get_highest_voted_posts</code> which takes the number of posts and then displays those many post in order of the highest voted posts. It also displays the number of vote for each post.</p><pre>function voteme_get_highest_voted_posts($numberofpost)
{
	$output = '';
	$the_query = new WP_Query( 'meta_key=_votemecount&amp;orderby=meta_value_num&amp;order=DESC&amp;posts_per_page='.$numberofpost );
	// The Loop
	while ( $the_query-&gt;have_posts() ) : $the_query-&gt;the_post();
	$output .= '&lt;li&gt;';
	$output .= '&lt;a href="'.get_permalink(). '" rel="bookmark"&gt;'.get_the_title().'('.get_post_meta(get_the_ID(), '_votemecount', true).')'.'&lt;/a&gt; ';
	$output .= '&lt;/li&gt;';
	endwhile;
	wp_reset_postdata();
	return $output;
}</pre><p>Then we create a widget which takes the number of post and the title from the user and uses the abpve function to display the top voted posts.</p><pre>class VoteMeTopVotedWidget extends WP_Widget {
	function VoteMeTopVotedWidget() {
	// widget actual processes
	$widget_ops = array('classname' =&gt; 'VoteMeTopVotedWidget', 'description' =&gt; 'Widget for top voted Posts.' );
	$this-&gt;WP_Widget('VoteMeTopVotedWidget','VoteMeTopVotedWidget', $widget_ops);
}
function form($instance) {
	// outputs the options form on admin
	$defaults = array( 'title' =&gt; 'Top Voted Posts', 'numberofposts' =&gt; '5' );
	$instance = wp_parse_args( (array) $instance, $defaults );
	?&gt;
	&lt;p&gt;
	&lt;label for="&lt;?php echo $this-&gt;get_field_id( 'title' ); ?&gt;"&gt;&lt;?php echo 'Title:'; ?&gt;&lt;/label&gt;
	&lt;input id="&lt;?php echo $this-&gt;get_field_id( 'title' ); ?&gt;" name="&lt;?php echo $this-&gt;get_field_name( 'title' ); ?&gt;" value="&lt;?php echo $instance['title']; ?&gt;" class="widefat" /&gt;
	&lt;/p&gt;
	&lt;p&gt;
	&lt;label for="&lt;?php echo $this-&gt;get_field_id( 'numberofposts' ); ?&gt;"&gt;&lt;?php echo 'Number of Posts'; ?&gt;&lt;/label&gt;
	&lt;input id="&lt;?php echo $this-&gt;get_field_id( 'numberofposts' ); ?&gt;" name="&lt;?php echo $this-&gt;get_field_name( 'numberofposts' ); ?&gt;" value="&lt;?php echo $instance['numberofposts']; ?&gt;" class="widefat" /&gt;
	&lt;/p&gt;
	&lt;?php
}
function update($new_instance, $old_instance) {
	// processes widget options to be saved
	$instance = $old_instance;
	$instance['title'] = strip_tags( $new_instance['title'] );
	$instance['numberofposts'] = $new_instance['numberofposts'];
	return $instance;
}
function widget($args, $instance) {
	// outputs the content of the widget
	extract( $args );
	$title = apply_filters('widget_title', $instance['title'] );
	echo $before_widget;
	if ( $title )
	echo $before_title . $title . $after_title;
	echo '&lt;ul&gt;';
	echo voteme_get_highest_voted_posts($instance['numberofposts']);
	echo '&lt;/ul&gt;';
	echo $after_widget;
}
}
function voteme_widget_init() {
	// Check for the required API functions
	if ( !function_exists('register_widget') )
	return;
	register_widget('VoteMeTopVotedWidget');
}
add_action('widgets_init', 'voteme_widget_init');</pre><p>The widget will look as follows</p><p><a
href="http://www.sitepoint.com/?attachment_id=54300" rel="attachment wp-att-54300"><img
class="alignnone size-full wp-image-54300" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/8.png" alt="" width="295" height="277" /></a></p><p>On the front, the widget will look as follows</p><p><a
href="http://www.sitepoint.com/?attachment_id=54301" rel="attachment wp-att-54301"><img
class="alignnone size-full wp-image-54301" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/9.png" alt="" width="585" height="239" /></a></p><h2>Conclusion.</h2><p>With custom fields, WordPress makes it easy for us to extend it to use for different purposes. WordPress has good support for AJAX as we have seen in this tutorial. So, happy WordPress development!</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=o2CI1Vqgnyg:zVjdTqb34rQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=o2CI1Vqgnyg:zVjdTqb34rQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=o2CI1Vqgnyg:zVjdTqb34rQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=o2CI1Vqgnyg:zVjdTqb34rQ:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/o2CI1Vqgnyg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/create-a-voting-plugin-for-wordpress/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.sitepoint.com/create-a-voting-plugin-for-wordpress/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=create-a-voting-plugin-for-wordpress</feedburner:origLink></item> <item><title>Ubuntu 12.04 LTS Precise Pangolin: File sharing with Samba.</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/uvmiODqNOp0/</link> <comments>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-file-sharing-with-samba/#comments</comments> <pubDate>Mon, 21 May 2012 15:00:10 +0000</pubDate> <dc:creator>Jonathan Hobson</dc:creator> <category><![CDATA[Web Tech]]></category> <category><![CDATA[WebOS]]></category> <category><![CDATA[Ubuntu]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54695</guid> <description><![CDATA[<img
width="50" height="39" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/ubuntu-50x39.png" class="attachment-thumbnail wp-post-image" alt="ubuntu" title="ubuntu" />Samba is the software package that allows you to share files, printers and other common resources across a network, and in this article I will be showing you how to install, set-up and manage a Samba Server on Ubuntu 12.04.]]></description> <content:encoded><![CDATA[<img
width="50" height="39" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/ubuntu-50x39.png" class="attachment-thumbnail wp-post-image" alt="ubuntu" title="ubuntu" /><p></p><p>Samba is the software package that allows you to share files, printers and other common resources across a network. Delivering full connectivity with the Windows workgroup it is known and respected as an invaluable tool in homes and offices around the world and in this article I will be showing you how to install, set-up and manage a Samba Server on Ubuntu 12.04 LTS Precise Pangolin.<br
/> So let&#8217;s begin &#8230;</p><h2>Prerequisites</h2><p>To get the best out of Samba your system should be running a static IP address and if you happen to be running a firewall, you should open the relevant ports to give the Samba service full access to your network.</p><p>Yes, you can use DHCP, but you will need to ensure that your DHCP server or router is providing you with a &#8216;fixed&#8217; DHCP licence; but for those who wish to learn how to implement a static IP address on Ubuntu 12.04 you can read my previous article on <a
href="http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-networking-tips-and-tricks">networking tips and tricks</a></p><h2>Update your system</h2><p>Installing Samba is a very straight forward process so we shall begin by updating the system.<br
/> In Terminal or in your console type:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre>sudo apt-get update &amp;&amp; apt-get upgrade</pre><p>If there are any updates available to you, do that now before we proceed :-)</p><h2>Installing Samba</h2><p>For the purposes of this article I will have provided you with three different approaches to installing Samba:<br
/> <strong>1. For desktop users</strong>, who want to take advantage of &#8216;winbind&#8217; (winbin) and use the graphical tools (system-config-samba), open Terminal and type:</p><pre>sudo apt-get install samba samba-common system-config-samba winbind</pre><p><strong>2. For desktop users</strong>, who wish to take advantage of &#8216;winbind&#8217; (winbind) but do not wish to use the graphical tools, open Terminal and type:</p><pre>sudo apt-get install samba samba-common winbind</pre><p><strong>3. For server users</strong>, in your console type:</p><pre>sudo apt-get install samba samba-common</pre><h2>Configuring Winbind</h2><p>Before we tackle the subject of Samba itself, desktop users will notice that we have installed Winbin.<br
/> The purpose of this is to ensure that Ubuntu can provide full hostname resolution when viewing your local network and so we will want to configure this before moving on. Don&#8217;t worry, it is very simple as all we need to do is make a quick &#8216;order change&#8217; to the &#8216;nsswitch.conf&#8217; file.<br
/> To begin, open Terminal and type:</p><pre>sudo gedit /etc/nsswitch.conf</pre><p>Find the line that looks like this:</p><pre>osts:          files mdns4_minimal [NOTFOUND=return] dns mdns4</pre><p>Now change it to look like this:</p><pre>hosts:          files mdns4_minimal [NOTFOUND=return] wins dns mdns4</pre><p>Your nsswitch.conf file should now look something like this:</p><pre>passwd:         compat
group:          compat
shadow:         compat
hosts:          files mdns4_minimal [NOTFOUND=return] wins dns mdns4
networks:       files
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       nis</pre><p>When complete, simply &#8216;save&#8217; and close your file before rebooting like so:</p><pre>sudo reboot</pre><p>Having done this you should now be able to select &#8216;GO &gt; Network&#8217; from the desktop menu and view your entire Windows and Linux based network.</p><blockquote><p>From this point onwards the article will act a guide and depending on your needs it should not be viewed as an ordered process or a solution. For example, you may wish to add system users prior to completing any configuration work or you may even need to repeat some processes in order to add multiple users. Remember, everyone&#8217;s network needs are unique :-)</p></blockquote><h2>Using the desktop graphical tools.</h2><p>Before you begin to use the graphical tools (system-config-samba) we will need to &#8216;fine-tune&#8217; the Samba Server Settings.</p><p>To do this, open the dash and use the search bar to find Samba like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54698" rel="attachment wp-att-54698"><img
class="alignnone size-full wp-image-54698" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u11.jpg" alt="" width="500" height="370" /></a></p><p>Launch the Samba configuration tool and choose, &#8216;Preferences &gt; Server Settings&#8217; like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54699" rel="attachment wp-att-54699"><img
class="alignnone size-full wp-image-54699" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u21.jpg" alt="" width="500" height="370" /></a></p><p>In most cases the &#8216;default settings&#8217; may be exactly what you need but in some instances you may need to make a few changes.</p><p>Complete the &#8216;basic&#8217; tab settings and click &#8216;OK&#8217; when done:</p><ul><li><strong>Workgroup.</strong>This field should be the same value as that used by your Windows Workgroupi.e if your WIndows Users are members of the &#8216;Home&#8217; workgroup, type &#8216;Home&#8217; in this field.</li><li><strong>Description.</strong>This is the name of your computer as seen by Windows Users.i.e.<br
/> keep it simple, use a name similar to that of your actual computer name and do not use spaces on non-internet friendly characters.</li></ul><p><a
href="http://www.sitepoint.com/?attachment_id=54704" rel="attachment wp-att-54704"><img
class="alignnone size-full wp-image-54704" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u31.jpg" alt="" width="500" height="370" /></a></p><p>As it is not advisable to allow &#8216;Guests&#8217; there should be no reason to change the &#8216;security&#8217; settings tab unless you wish to do so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54705" rel="attachment wp-att-54705"><img
class="alignnone size-full wp-image-54705" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u41.jpg" alt="" width="500" height="370" /></a></p><p>Now click &#8216;OK&#8217; to close the &#8216;Server Settings&#8217; window.<br
/> To manage your current users simply choose &#8216;Preferences &gt; Samba Users&#8217; like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54707" rel="attachment wp-att-54707"><img
class="alignnone size-full wp-image-54707" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u22.jpg" alt="" width="500" height="370" /></a></p><p>Now launch the &#8216;Samba Users&#8217; dialogue box. Select your username and click &#8216;Edit User&#8217; to launch the &#8216;Create New Samab User&#8217; dialogue box.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54708" rel="attachment wp-att-54708"><img
class="alignnone size-full wp-image-54708" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u51.jpg" alt="" width="500" height="370" /></a></p><p>Complete the fields as required:</p><ul><li><strong>Windows Username.</strong> Confirm the username to be used by Windows users when accessing your share folder(s).</li><li><strong>Samba Password.</strong> Use this field to confirm the password to be used by Windows users when accessing your share folder(s).</li><li><strong>Confirm Samba Password. </strong>Use this field to re-confirm the password to be used by Windows users when accessing your share folder(s).</li></ul><blockquote><p>Although you may see &#8216;stars&#8217; in the password field(s) prior to doing this. Delete them and re-type the password.</p></blockquote><p>When complete, click &#8216;OK&#8217; to close both dialogue boxes before restarting the Samba service like so.</p><p>Open Terminal and type:</p><pre>sudo restart smbd &amp;&amp; sudo restart nmbd</pre><h2>Adding a new (Linux) user account with the desktop graphical tools.</h2><p>If you want to add a new Linux user account, simply:</p><ul><li>Open &#8216;System Settings&#8217;.</li><li>Choose &#8216;User Accounts&#8217; and unlock the panel using your administration password.</li><li>Use the + (plus) icon to create a new user.</li><li>Enter the new user&#8217;s full name (the username will be filled in automatically based on the full name).</li></ul><p>As this folder is for &#8216;sharing purposes only&#8217; do not assign &#8216;administrative rights&#8217; to this user account.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54709" rel="attachment wp-att-54709"><img
class="alignnone size-full wp-image-54709" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u8.jpg" alt="" width="500" height="370" /></a></p><p>When finished, click &lt;Create&gt;.<br
/> As the account is initially disabled, we now need to set the users password.</p><p>To do this, simply:</p><ul><li>Ensure the &#8216;User Accounts&#8217; panel is still unlocked.</li><li>Click &#8216;Account Disabled&#8217; and complete the resulting dialogue box.</li></ul><p><a
href="http://www.sitepoint.com/?attachment_id=54710" rel="attachment wp-att-54710"><img
class="alignnone size-full wp-image-54710" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u9.jpg" alt="" width="500" height="370" /></a></p><p>When finished, click &#8216;Change&#8217;.<br
/> If you return to the &#8216;Samba Users&#8217; dialogue box and click &#8216;Add User&#8217;, your new user account should be found in the Unix Username drop-down box like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54711" rel="attachment wp-att-54711"><img
class="alignnone size-full wp-image-54711" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u10.jpg" alt="" width="500" height="370" /></a></p><p>Simply complete the relevant details and click &lt;OK&gt; to finish.<br
/> When done, you will be able to assign this user account to specific folders like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54712" rel="attachment wp-att-54712"><img
class="alignnone size-full wp-image-54712" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u111.jpg" alt="" width="500" height="370" /></a></p><p>More information on user accounts can be found here <a
href="https://help.ubuntu.com/12.04/ubuntu-help/user-accounts.html" target="_blank">https://help.ubuntu.com/12.04/ubuntu-help/user-accounts.html</a>.</p><h2>Sharing folders with the graphical tools.</h2><p>To share a folder with Samba, click the green &#8216;+&#8217; (plus) icon to open a dialogue box called &#8216;Create Samba Share&#8217; like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54713" rel="attachment wp-att-54713"><img
class="alignnone size-full wp-image-54713" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u6.jpg" alt="" width="500" height="370" /></a></p><p>Complete the &#8216;basic&#8217; tab with the required information.</p><ul><li><strong>Directory.</strong> Click &#8216;Browse&#8217; to locate the relevant folder you wish to share.</li><li><strong>Share Name.</strong> Use this field to specify a &#8216;human friendly&#8217; name for your share folder.</li><li><strong>Description.</strong> Type a description of the &#8216;share folder&#8217; in this field.</li><li><strong>Writable.</strong> Shared folders are &#8216;read-only&#8217; by default, so place a tick in this box if you would like to enable &#8216;write&#8217; access.</li><li><strong>Visible.</strong> Place a tick in this box if you want your share folder to be &#8216;visible&#8217; on the network.</li></ul><p>Following this, we now need to set the permissions for your new share folder.</p><p>To do this, simply click the &#8216;access&#8217; tab in the same dialogue box like so:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54714" rel="attachment wp-att-54714"><img
class="alignnone size-full wp-image-54714" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u112.jpg" alt="" width="500" height="370" /></a></p><p><strong>If you would like to restrict access to this folder:</strong></p><ul><li>Select &#8216;Only allow access to specific users&#8217;.</li><li>Use the tick boxes to confirm which users can access the folder in question.</li></ul><p><strong>If you would like everyone to access the folder:</strong></p><ul><li>Select &#8216;Allow access to everyone&#8217;.</li></ul><p>When complete, click &#8216;OK&#8217; to close the dialogue box.</p><blockquote><p>To remove any shared folder from Samba, simply choose the relevant folder in the configuration tool and click the &#8216;red icon&#8217;. Don&#8217;t worry, this action will not delete the folder or its contents.</p></blockquote><p>And that&#8217;s it, your share folders are now active.</p><h2>Configuring Samba on the command line</h2><p>Using the graphical tools has its advantages, but if you really want to control every aspect of your Samba server, nothing beats the command line.</p><p>So let&#8217;s begin by making a backup of our original configuration file:</p><pre>cp /etc/samba/smb.conf /etc/samba/smb.conf.bak</pre><p>And open the content of the current configuration file like so:</p><pre>sudo nano /etc/samba/smb.conf</pre><p>We are now going to configure the Samba Server by using a basic example to get you started &#8230;</p><p>I am not going to explain every aspect of Samba (as most server administrators will want to read the official documentation found at <a
href="http://www.samba.org/" target="_blank">http://www.samba.org/</a>) so instead I have provided you with a template in order to get you up and running in no time at all. You should consider this to be a basic template only. It is not definitive by any means and nor do I expect you to replicate it but if you do use it &#8211; remember to change the values shown with values relevant to your specific needs or network requirements:<br
/> And here is the template:</p><pre>[global]
    unix charset = UTF-8
    # -------------------------------------------
    # DEFINE YOUR WORKGROUP AND COMPUTER NAME HERE
    workgroup = YOUR-WORKGROUP-NAME
    server string = YOUR-COMPUTER-NAME
	  netbios name = YOUR-COMPUTER-NAME
    # -------------------------------------------
    dns proxy = no
    # -------------------------------------------
    # IF YOU SET BIND INTERFACES TO YES, TO AVOID LOG ERRORS,
	  # MAKE SURE YOUR SAMBA SERVICE STARTS AFTER THE ETHERNET CARD IS SWITCHED ON
    # bind interfaces only = no
    # bind interfaces only = yes
    bind interfaces only = no
    # ADD THE ETHERNET CARD AND IP ADDRESSES YOU ALLOW
    interfaces = eth0 127.0.0.0/8 192.168.1.0/24
    # -------------------------------------------
    # SAMBA LOG FILES
    log file = /var/log/samba/log.%m
    max log size = 1000
    syslog only = no
    syslog = 0
    # -------------------------------------------
    panic action = /usr/share/samba/panic-action %d
    # LIMIT ACCESS TO USERS ONLY
    security = user
    # USING TDBSAM
    encrypt passwords = true
    passdb backend = tdbsam
    obey pam restrictions = yes
    unix password sync = yes
    passwd program = /usr/bin/passwd %u
    passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
    pam password change = yes
    map to guest = bad user
    usershare allow guests = no
    # -------------------------------------------
    # INCLUDE THIS SECTION TO DISABLE PRINTERS/CUPS ONLY
    #load printers = no
    #printing = bsd
    #printcap name = /dev/null
    #disable spoolss = yes
    # -------------------------------------------
    # DIRECTORIES
    # -------------------------------------------
    # ENABLE HOME FOLDER ACCESS
    [homes]
        comment = Home Directories
        browseable = no
        writable = yes
        valid users = %S
        valid users = MYDOMAIN\%S
        create mask =0755
        directory mask =0755
    # -------------------------------------------
    # EXAMPLE FOLDER WITH LIMITED ACCESS, UNCOMMENT AND CUSTOMISE AS NECESSARY
    #[example]
    #   comment = example share folder on my-computer-name
    #   path = /foldername/foldername/
    #   browseable = yes
    #   guest ok = no
    #   writable = yes
    #   create mask = 0755
    #   directory mask = 0755
    #   valid users = @your-username
    #   force group = your-username-or-group
    #   force create mode = 0755
    # -------------------------------------------</pre><p>To un-comment a line, simply remove the # (hash) symbol.</p><p>Either copy the content of this file to <strong>/etc/samba/smb.conf</strong> or simply work through the samba configuration file using my template as a guide. Don&#8217;t worry, there&#8217;s no rush &#8230;</p><p>When done, &#8216;save&#8217; the file, &#8216;close&#8217; it and restart the Samba service in order that it can apply the new settings by using:</p><pre>sudo service smbd restart &amp;&amp; sudo service nmbd restart</pre><h2>Creating (Linux) users and home folders on the command line</h2><p>Although a complete tutorial on &#8216;working with files, directories and users&#8217; is beyond the scope of this current article, adding a new user account and creating a home folder is a relatively simple task &#8211; just remember to replace my values with something relevant to your needs.</p><p>To create a new user with an associated home folder on your server or desktop, use:</p><pre>sudo adduser new-username-here</pre><p>Ubuntu will now ask you a few basic questions and then complete the task of [a] creating the new user, [b] creating a specific group for that user and then [c] creating a home folder for the user in question.</p><p>And all with a single command :-)</p><p>To explain this, here is a step-by-step example with the resulting output. I am going to create a new user called &#8216;new-username-here&#8217;.</p><p>The process begins after I type the following command:</p><pre>sudo adduser new-username-here</pre><p>Ubuntu will now start the process:</p><pre>Adding user `new-username-here' ...
Adding new group `new-username-here' (1004) ...
Adding new user `new-username-here' (1004) with group `new-username-here' ...
Creating home directory `/home/new-username-here' ...
Copying files from `/etc/skel' ...</pre><p>At this point you will be asked to create a password:</p><pre>Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for new-username-here</pre><p>At this point you will be asked to complete some user-based details:<br
/> (to leave a field blank, just press the &lt;RETURN&gt; key)</p><pre>Enter the new value, or press ENTER for the default
	Full Name []: new-username-here
	Room Number []:
	Work Phone []:
	Home Phone []:
	Other []:</pre><p>At this point you will be asked to confirm your instruction:</p><pre>Is the information correct? [Y/n]</pre><p>Wasn&#8217;t that easy :-)</p><h2>Adding (Samba) users on the command line</h2><p>Finally let&#8217;s create a Samba user based on the example above with the following command.</p><pre>smbpasswd -a new-username-here</pre><p>You will be asked to confirm a password, but it is as simple as that &#8230;</p><blockquote><p>Remember, you will need to give the relevant username and password to your network user.</p></blockquote><p>So until next time &#8230;<br
/> I hope you continue to enjoy using Ubuntu 12.04 LTS Precise Pangolin.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=uvmiODqNOp0:Coz2zCFhTy0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=uvmiODqNOp0:Coz2zCFhTy0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=uvmiODqNOp0:Coz2zCFhTy0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=uvmiODqNOp0:Coz2zCFhTy0:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/uvmiODqNOp0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-file-sharing-with-samba/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-file-sharing-with-samba/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=ubuntu-12-04-lts-precise-pangolin-file-sharing-with-samba</feedburner:origLink></item> <item><title>Stopping Abusive Clients: The Complete Process</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/3RrvOMc1a7U/</link> <comments>http://www.sitepoint.com/stopping-abusive-clients-the-complete-process/#comments</comments> <pubDate>Mon, 21 May 2012 02:33:41 +0000</pubDate> <dc:creator>John Tabita</dc:creator> <category><![CDATA[Freelancing]]></category> <category><![CDATA[Sell Your Services]]></category> <category><![CDATA[Selling Web Design Services]]></category> <category><![CDATA[Web Pro Business]]></category> <category><![CDATA[Work Smarter]]></category> <category><![CDATA[Business]]></category> <category><![CDATA[clients]]></category> <category><![CDATA[freelance]]></category> <category><![CDATA[freelancing]]></category> <category><![CDATA[sales]]></category> <category><![CDATA[selling]]></category> <category><![CDATA[selling your services]]></category> <category><![CDATA[small business]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54749</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/stop-abusive-clients-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="SONY DSC" title="SONY DSC" />In the final installment of his series, Putting a Stop to Abusive Clients, John Tabita shows you how to put it all together in a complete, comprehensive process to end the abuse once and for all.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/stop-abusive-clients-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="SONY DSC" title="SONY DSC" /><p></p><p>This is the 11th and final installment of my series, <a
title="Putting a Stop to Abusive Clients" href="http://www.johntabita.com/abusive-clients/" target="_blank">Putting a Stop to Abusive Clients</a>. I hope I’ve made it clear that the solution is not to continually complain and blame clients if they treat you badly, but to take responsibility and make the appropriate changes to your business practices.</p><p>An important “best practice” for your business is to have a system for selling your services and managing the sales process. When I first started out, I didn’t realize I needed a process, one with a beginning, middle, and end. Not having one meant I typically started off badly, fumbled around in the middle, and didn’t really know when (or if) it really ended. By not knowing how to close (end) the process by asking for the sale, I allowed it to fade into “maybeland,” which is the worst place to be when your income depends on whether you sell or not.</p><p>Having a clearly-defined process allows you to build in checks and balances, to define and manage client expectations. Not having one means clients can walk all over you—either unintentional or deliberately—and you wind up feeling abused. So here in a nutshell is the process I followed for many years … once I figured out I needed one, that is.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>Preliminary Consultation</h2><p>When I make contact with a potential client, the first step is to determine how viable of a prospect he or she really is. Rather than immediately scheduling a meeting, I’m going to have a preliminary phone call to determine two things:</p><ol><li>Are they truly serious about the project?</li><li>Can they afford to pay for a top-end site like I’m going to provide, or are they just looking for the cheapest option available?</li></ol><p>If you’ve read my <strong>27.5 Must-Ask Questions for Consultative Selling</strong>, then you already know some questions to ask. I want to learn a little bit about the company and his business goals and objectives. At some point in the conversation, I’m going to ask some variation of this question:</p><p>“My prices start at $X,XXX. Were you prepared to spend that?” Unless I get a positive response, I’m not hurrying out to meet with him any time soon.</p><p>It’s tempting to skip this crucial first step, or to avoid asking the hard questions and just set up a meeting. But if you want to<a
title="Stop Wasting Time with Prospects Who Aren’t Serious" href="http://www.sitepoint.com/stop-wasting-time-with-prospects-who-arent-serious/" target="_blank"> stop wasting time with prospects who aren’t serious</a>, I highly recommend you don’t.</p><h2>Preparation</h2><p>If the initial conversation warrants a meeting, I’m going to do some research in order to be able to ask some intelligent questions. I want to walk in knowing as much as I can about the company, its owners, and their business model. In this day and age, there’s no excuse for ignorant questions like, “What exactly is it you do here?”</p><h2>Needs Analysis</h2><p>The heart of consultative selling is asking questions and actually listening to the answer (as opposed to thinking about what you’re going to say next). My <strong>27.5 Must-Ask Questions for Consultative Selling</strong> are very direct and to-the-point, and it takes a bit of courage to bring yourself to ask them … especially the first time.</p><p>It helps if you don’t get down to business right away. Think of it like this: the questions you ask should go from general to specific. At some point you’re going to ask some quasi-confidential questions, like how much would he like to increase revenue. But a more appropriate question to begin with might be, “How did you get started in this industry?”</p><p>Before you jump into the deep end, you need to break the ice. I’ve heard it said that prospects who want to get straight down to business really want to get straight down to “How much is this going to cost me?”</p><h2>Recommendation</h2><p>At some point, you’ll need to turn the information-gathering conversation into a diagnosis. Once you feel you sufficiently understand the prospect’s business goal, needs, and objectives, you can begin to offer suggestions and solutions.</p><p>The trick is to <a
title="Stop Giving Away So Much Free Information!" href="http://www.sitepoint.com/stop-giving-away-so-much-free-information/" target="_blank">avoid giving away too much free information</a>. You do that by discussing the WHY, agreeing upon the WHAT, and ignoring the HOW. Forget about the technical stuff you love talking about. To get the prospect’s commitment to do business with you, you only need to establish and agree upon two things you:</p><p>1. What he’s trying to accomplish, his “big picture” objective<br
/> 2. That you’re the one to help him accomplish it</p><h2>Engagement</h2><p>There comes a point when it’s time to close the deal and ask for the engagement. There are many ways to do this, but I always liked to ask a simple question: “Are you ready to move forward?” (You do this after you’ve discussed all there is to discus and recapped the entire conversation, asking if there’s anything that needs to be added.)</p><p>If your prospect says, “yes,” he’d like to move forward, you need to establish the next step. For a lot years, that meant spending several hours preparing a detailed proposal—that is, until I learned how to <a
title="Stop Writing Proposals to Win Business" href="http://www.sitepoint.com/stop-writing-proposals-to-win-business/" target="_blank">stop writing proposals to win business</a>.</p><p>If you establish and agree upon items #1 and #2 above, then you ought to be able to obtain the prospect’s verbal agreement, conditional on price, without ever writing a proposal. Once you do, it’s a simple thing to <a
title="Stop Doing the Same Things and Expecting Different Results" href="http://www.sitepoint.com/stop-doing-the-same-things-and-expecting-different-results/" target="_blank">prepare a cost estimate without turning it into a comprehensive project plan</a>. Whether I did that on the spot or went back to the office depended on the size and complexity of the project. Once I had a price, I got back in touch to get his agreement.</p><h2>Finalize</h2><p>Now it’s time to finalize the agreement. If the prospect has agreed to the price, you return to his place of business with your final, written document in hand (based on everything discussed during the Needs Analysis and Recommendation steps), then sit down with him and go over every clause in detail. To prevent future problems like <a
title="Stop Waiting to Get Paid! How to Collect Even when Your Client Delays" href="http://www.sitepoint.com/stop-waiting-to-get-paid-how-to-collect-even-when-your-client-delays/" target="_blank">waiting to get paid when your client delays</a>, <a
title="Stop Making Endless Design Changes" href="http://www.sitepoint.com/stop-making-endless-design-changes/" target="_blank">making endless design changes</a>, or <a
title="Stop the Slippery Slope of Scope Creep" href="http://www.sitepoint.com/stop-the-slippery-slope-of-scope-creep/" target="_blank">avoiding the slippery slope of scope creep</a>, you must <a
title="Stop Getting Walked on and Set Some Boundaries Already" href="http://www.sitepoint.com/stop-getting-walked-on-and-set-some-boundaries-already/" target="_blank">stop getting walked on and set some boundaries</a>. That’s exactly what you’re doing here, by managing expectation up-front, in a face-to-face conversation, instead of after the fact.</p><h2>The Final Word</h2><p>There are many ways to skin this cat; this just happens to be the way I skin it. You may develop a process that’s similar or completely different. Steal mine, borrow from it, or make up your own. But come up with one that works for you, then refine it until you get it right. It will do wonders for your business and will put an end to abusive clients, misunderstandings, and mismanaged expectations and once and for all.</p><p
style="text-align: right"><em><a
href="http://www.sxc.hu/profile/duchesssa" target="_blank">Image credit</a></em></p><div
style="border-width: 1px;border-style: solid;border-color: #d5d5d5;padding: 8px;margin-top: 30px;margin-bottom: 30px;background: #e8e8e8">It’s not too late to get my free guide, <strong>27.5 Must-Ask Questions for Consultative Selling</strong>. Just <a
title="Twitter | @johntabita" href="http://twitter.com/johntabita" target="_blank">follow me on Twitter</a> and I’ll send you a link.</div><p>This is part 11 of the series <strong>Putting a Stop to Abusive Client Behavior</strong>:</p><ol><li><a
title="Stop Client Abuse of Web Designers Now!" href="http://www.sitepoint.com/stop-client-abuse-of-web-designers-now/" target="_blank">Stop Client Abuse of Web Designers Now!</a></li><li><a
title="Stop the Abuse! 7 Steps to a Well-Trained Client" href="http://www.sitepoint.com/stop-the-abuse-7-steps-to-a-well-trained-client/" target="_blank">Stop the Abuse! 7 Steps to a Well-Trained Client</a></li><li><a
title="Stop Wasting Time with Prospects Who Aren’t Serious" href="http://www.sitepoint.com/stop-wasting-time-with-prospects-who-arent-serious/" target="_blank">Stop Wasting Time with Prospects Who Aren’t Serious</a></li><li><a
title="Stop Giving Away So Much Free Information!" href="http://www.sitepoint.com/stop-giving-away-so-much-free-information/" target="_blank">Stop Giving Away So Much Free Information!</a></li><li><a
title="Stop Writing Proposals to Win Business" href="http://www.sitepoint.com/stop-writing-proposals-to-win-business/" target="_blank">Stop Writing Proposals to Win Business</a></li><li><a
title="Stop Doing the Same Things and Expecting Different Results" href="http://www.sitepoint.com/stop-doing-the-same-things-and-expecting-different-results/" target="_blank">Stop Doing the Same Things and Expecting Different Results</a></li><li><a
title="Stop Waiting to Get Paid! How to Collect Even when Your Client Delays" href="http://www.sitepoint.com/stop-waiting-to-get-paid-how-to-collect-even-when-your-client-delays/" target="_blank">Stop Waiting to Get Paid! How to Collect Even when Your Client Delays</a></li><li><a
title="Stop Getting Walked on and Set Some Boundaries Already" href="http://www.sitepoint.com/stop-getting-walked-on-and-set-some-boundaries-already/" target="_blank">Stop Getting Walked on and Set Some Boundaries Already</a></li><li><a
title="Stop the Slippery Slope of Scope Creep" href="http://www.sitepoint.com/stop-the-slippery-slope-of-scope-creep/" target="_blank">Stop the Slippery Slope of Scope Creep</a></li><li><a
title="Stop Making Endless Design Changes" href="http://www.sitepoint.com/stop-making-endless-design-changes/" target="_blank">Stop Making Endless Design Changes</a></li></ol> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=3RrvOMc1a7U:nxDXv1pjZFU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=3RrvOMc1a7U:nxDXv1pjZFU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=3RrvOMc1a7U:nxDXv1pjZFU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=3RrvOMc1a7U:nxDXv1pjZFU:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/3RrvOMc1a7U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/stopping-abusive-clients-the-complete-process/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://www.sitepoint.com/stopping-abusive-clients-the-complete-process/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=stopping-abusive-clients-the-complete-process</feedburner:origLink></item> <item><title>An Introduction to C</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/XC5vO2nn0_0/</link> <comments>http://www.sitepoint.com/an-introduction-to-c/#comments</comments> <pubDate>Sat, 19 May 2012 15:00:53 +0000</pubDate> <dc:creator>Surabhi Saxena</dc:creator> <category><![CDATA[Web Tech]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=53509</guid> <description><![CDATA[C. You've all heard about it, but how much do you actually know about it? In this piece, Surabhi introduces us to this powerful language.]]></description> <content:encoded><![CDATA[<p></p><p><strong>Introduction</strong></p><p>C is a general purpose, structured programming language. Its instructions consist of terms that resemble algebraic expressions, augmented by certain English keywords such as if, else, for, do and while. In this respect it resembles high level structured programming languages such as Pascal and Fortran. C also contains additional features, that allow it to be used at a lower level, thus bridging the gap between machine language and high level language. This flexibility allows C to be used for systems programming as well as for applications programming. Therefore C is called a <strong><em>middle level language.  </em></strong></p><p>C is characterized by the ability to write very concise source programs, due in part to the large number of operators included within the language. It has a relatively small instruction set, though actual implementations include extensive library functions which enhance the basic instructions. C encourages users to create their own library fuctions.</p><p>An important characteristic of C is that its programs are highly portable. The reason for this is that C relegates most computer dependent features to its library functions. Thus, every version of C is accompanied by its own set of library functions which are relatively standardized. Therefore most C programs can be processed on many different computers with little or no alteration.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><strong>History of C:</strong></p><p>C was developed in the 1970&#8242;s by <strong>Dennis Ritchie</strong> at <strong>Bell Telephone Laboratories</strong>,Inc. (now a part of AT&amp;T). It is an outgrowth of two earlier languages, called BCPL and B, which were also developed at Bell Laboratories.</p><p>The <strong>Combined Programming Language(CPL)</strong> was developed at Cambridge University in 1963 with the goal of developing a common programming language which can be used to solve different types of problems on various hardware platforms. However it turned out to be too complex, hard to learn and difficult to implement. Subsequently in 1967, a subset of CPL, <strong>Basic CPL(BCPL)</strong> was developed by <strong>Martin Richards</strong> incorporating only the essential features. However it was not found to be sufficiently powerful. Around the same time another subset of CPL, a language called <strong>B</strong> was developed by <strong>Ken Thompson</strong> at Bell Labs. However it also turned out to be insufficient . Then, in 1972, Dennis Ritchie at Bell Labs developed the C language incorporating the best features of both BCPL and B.</p><p>C was largely confined to use within Bell Labs until 1978, when Brian Kernighan and Ritchie published a definitive description of the language . The <strong>Kerninghan and Ritchie description of C</strong> is commonly referred to as <em><strong>&#8216;K &amp;R C&#8217;</strong></em>.</p><p>Following the publication of &#8216;K&amp;R C&#8217;,computer professionals, impressed with C&#8217;s many desirable features, began to promote the use of C. By the mid 1980&#8242;s the popularity of C had become widespread-many c compilers and interpreters had been written for computers of all sizes and many commercial application programs had been developed. Moreover, many commercial software products that had originally been written in other languages were rewritten in C in order to take advantage of its efficiency and portability.</p><p>Early commercial implementations of C differed a little from Kerninghan and Ritchie&#8217;s original description, resulting in minor incompatibilities between different implementations. As a result, <strong>the American National Standards Institute(ANSI committee X3J11)</strong>  developed a standardized definition of C. Virtually all commercial compilers and interpreters adhere to the ANSI standard. Many provide additional features of their own.</p><p><strong>C and Systems Programming:</strong></p><p>There are several features of C, which make it suitable for systems programming. They are as follows:</p><ul><li>C is a machine independent and highly portable language.</li><li>It is easy to learn; it has only 28 keywords.</li><li>It has a comprehensive set of operators to tackle business as well as scientific applications with ease.</li><li>Users can create their own functions and add to the C library to perform a variety of tasks.</li><li>C language allows the manipulation of bits, bytes and addresses.</li><li>It has a large library of functions.</li><li>C operates on the same data types as the computer, so the codes generated are fast and efficient.</li></ul><p><strong>Structure of a C Program:</strong></p><p>Every C program consists of one or more modules called <strong><em>functions. </em></strong>One of the functions must be called <strong><em>main</em></strong>. The program will always begin by executing the <em>main</em> function, which may access other functions. The main function is normally,but not necessarily located at the beginning of the program. The group of statements within main( ) are executed sequentially. When the closing brace of main( ) is encountered, program execution stops and control is returned to the operating system.</p><p>Any other function defintions must be defined separately, either ahead or after main( ). Each function must contain:</p><p>1. A <strong><em>function heading</em></strong>, which consists of the <strong><em>function name</em></strong>, followed by an optional list of arguments, enclosed in parantheses.</p><p>2. A <strong><em>return type</em></strong> written before the function name. It denotes the type of data that the function will return to the program.</p><p>3. A list of <strong><em>argument declarations</em></strong>, if arguments are included in the heading.</p><p>4. A <strong><em>compound statement</em></strong>, which comprises the remainder of the function.</p><p>The arguments(also called parameters) are symbols that represent information being passed between the function and other parts of the program.</p><p>Each compound statement is enclosed between a pair of braces{ }. The braces may contain one or more elementary statements (called <strong><em>expression statements</em></strong>) and other compound statements. Thus compound statements may be nested one within another. Each expression statement must end with a semicolon(;).</p><p><strong><em>Comments (remarks)</em></strong> may appear anywhere within a program as long as they are enclosed within the delimiters /* and */. Comments are used for documentation and are useful in identifying the program&#8217;s principal features or in explaining the underlying logic of various program features.</p><p><span
style="text-decoration: underline"><strong>Components of C Language:</strong></span></p><p>There are five main components of the C Language:-</p><p>1. <strong>The character set:</strong> C uses the uppercase letters A to Z, the lowercase letters a to z, the digits 0 to 9 and certain special characters as building blocks to form basic program elements(e. g. constants, variables, expressions, statements etc. ).</p><p>2. <strong>Data Types:</strong> The C language is designed to handle five <em>primary data types, </em>namely, <em>character, integer, float, double and void;</em> and <em>secondary data types </em>like<em> array, pointer, structure, union and enum. </em></p><p><strong>3. </strong><strong>Constants:</strong> A constant<strong> </strong>is a fixed value entity that does not change its value throughout program execution.</p><p>4. <strong>Variables:</strong> A variable is an entity whose value can change during program execution. They are used for storing input data or to store values generated as a result of processing.</p><p>5. <strong>Keywords:</strong> Keywords are <strong><em>reserved</em></strong> words which have been assigned specific meanings in the C language. Keywords cannot be used as variable names.</p><p>The components of C language will be discussed in greater detail in the following articles. This section gives only a brief introduction to the components of C.</p><p><strong>Example 1:</strong> The following program reads in the radius of a circle, calculates the area and then prints the result.</p><pre style="padding-left: 30px">/* program to calculate the area of a circle*/
#include&lt;stdio.h&gt; /*Library file access*/
#include&lt;conio.h&gt; /*Library file access*/
void main( )            /* Function Heading*/
    {
       float radius, area; /*Variable declarations*/
       /*Output Statement(prompt)*/
       printf("Enter the radius :");
      /*Input Statement*/
      scanf("%f", &amp;radius);
      /*Assignment Statement*/
      area = 3.14159*radius*radius;
      /*Output Statement*/
      printf("Area of the circle :%f", area);
       getch( );
     }</pre><p
style="padding-left: 30px">Program output:-</p><p
style="padding-left: 30px">Enter the radius: 3</p><p
style="padding-left: 30px">Area of the circle: 28. 27431</p><p>The following points must be considered to understand the above program:-</p><p>1. The program is typed in lowercase. C is <strong>case sensitive</strong> i. e. uppercase and lowercase characters are not equivalent in C. It is customary to type C instructions in lowercase. Comments and messages(such as those printed using <code>printf() )</code> can be typed in anycase.</p><p>2. The first line is a comment that identifies the purpose of the program.</p><p>3. The instruction<strong> #include &lt;stdio.h&gt;</strong> contains a reference to a special file called stdio. h . This file contains the definition of certain functions required to read and print data such as printf() and scanf() . It is a header file and hence the extension . h.</p><p>4. Similarly <strong>#include &lt;conio.h&gt;</strong> links the file conio. h which is another header file that contains the definitions of functions used for reading and printing data at the console. The function <strong><code>getch()</code></strong> is defined in conio. h. # denotes a preprocessor directive. More about this in a later article.</p><p>5. The instruction <strong>void main()</strong> is a heading for the function main( ). The keyword <strong>void</strong> denotes the return type of main and indicates that the function does not return any value to the program after the program has finished executing. The empty parantheses ( ) after main indicates that this function does not include any arguments. Program execution always begins from main( ).</p><p>6. The remaining five lines of the program are indented and enclosed in a pair of braces { }. These five lines comprise the compound statement within the function main( ).</p><p>7. The instruction <strong>float radius, area;</strong>  is a <strong><em>variable declaration. </em></strong> It establishes the symbolic names &#8216;radius&#8217; and &#8216;area&#8217; as floating point variables. These variables can accept values of type &#8216;float &#8216; i. e numbers containing a decimal point or an exponent.</p><p>8. The next four instructions are <strong><em> expression statements. </em></strong>The instruction <strong>printf(&#8220;Enter the radius :&#8221;);</strong> generates a request for information namely,the value for the radius. This statement generates a prompt where the user enters the value .</p><p>9. The value of the radius is read into (or stored in) the variable <em>radius </em>with the help of the scanf ( ) function. The instruction<strong> scanf(&#8220;%f&#8221;, &amp;radius);</strong> is used for reading data.   &#8220;%f&#8221; is a <strong><em>conversion character</em></strong> which is used to accept a floating point value.</p><p>10. The next instruction, <strong>area = 3.14159*radius*radius;</strong> is called an <strong><em> assignment statement. </em></strong>This instruction calculates the area by using the value of radius entered by the user and assigns the value to the variable <em>area. </em></p><p>11. The next printf( ) statement prints the message <em>Area of the circle </em>followed by the calculated area.</p><p>12. The statement <strong>getch();</strong> is used to pause the screen so that you can read the output. If getch( ) is not used the screen will just flash and go away. This function waits for the user to input some character(as it accepts a character as input), after the program has finished executing. Any key present on the keyboard pressed by the user is accepted by the getch function as input and its ASCII value is returned to main( ).</p><p><strong>Example2:</strong> Below is a variation of the above program:</p><pre>/*program to calculate the area of a circle using a user defined function*/
#include &lt;stdio.h&gt;
#include &lt;conio.h&gt;
#define PI 3.14159
float process(float radius);/*function prototype*/
void main()
    {
      float area,radius;
      printf("\n Enter the radius:");
      scanf("%f", &amp;radius);
      area= process(radius);
      printf("Area =%f", area);
      getch();
     }
float process( float r)
     {
     float a; /*local variable declaration*/
     a= PI*r*r;
     return(a);
     }</pre><p>This version utilizes a separate programmer defined function called <strong><em>process</em></strong>, to calculate the area. Within this function, r is an argument (also called a parameter) that accepts the value of radius supplied to <strong><em> process</em></strong> from <strong><em>main</em></strong>, and a is the calculated result returned to main. A reference to the function appears in main( ), within the statement area= process(radius);</p><p>In this statement, the value of area being returned from the function <em>process </em>is stored in the variable area.</p><p>The main function is preceeded by a function prototype, which indicates that there is a user defined function called process which is defined after main and that it accepts a floating point argument and returns a floating point value. If the user defined function <em>process, </em>was defined before main( ), the function prototype would,generally, have not been required.</p><p>More explanation about this when I write about functions in a later article.</p><p>This program also contains a <strong><em>symbolic constant, PI, </em></strong>which represents the numeric value 3. 14159. This is a form of shorthand that exists for the programmers convenience. When the program is actually compiled, the symbolic constant will automatically be replaced by its numerical value. The output of this program is the same as that of the previous program.</p><p>This article was a brief introduction, it gives an idea of C programming. The next article will talk about the fundamental concepts of C which include the C character set, Identifiers and keywords, data types in detail, constants,variables, variable declarations, expressions, statements and symbolic constants .</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=XC5vO2nn0_0:zNUHHiaOhQw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=XC5vO2nn0_0:zNUHHiaOhQw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=XC5vO2nn0_0:zNUHHiaOhQw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=XC5vO2nn0_0:zNUHHiaOhQw:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/XC5vO2nn0_0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/an-introduction-to-c/feed/</wfw:commentRss> <slash:comments>17</slash:comments> <feedburner:origLink>http://www.sitepoint.com/an-introduction-to-c/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=an-introduction-to-c</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 29/36 queries in 0.058 seconds using memcached
Object Caching 2678/2678 objects using memcached

Served from: www.sitepoint.com @ 2012-05-26 10:40:37 -->

