<?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>CodeForest - web development and programming blog</title>
	
	<link>http://www.codeforest.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 09 Feb 2012 07:59:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<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/Codeforest" /><feedburner:info uri="codeforest" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Codeforest</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>GIT vs SVN</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/ZUH3-UowUE4/git-vs-svn</link>
		<comments>http://www.codeforest.net/git-vs-svn#comments</comments>
		<pubDate>Sun, 05 Feb 2012 16:08:57 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1192</guid>
		<description><![CDATA[Comparison of GIT and SVN is not easy, as they come from different worlds and eras. But, I tried. And here it is.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Revision control, also known as version control, source control or software configuration management (SCM), is the management of changes to documents, programs, and other information stored as computer files.</p>
<p>Version control systems provide the ability to track (and potentially revert) incremental changes to files, reporting them to a mailing list as they are made, and can be used concurrently by many developers.</p>
<h2>Distributed vs Centralized</h2>
<p>To better understand the comparison of this two Version Control tools, first we must understand what is the difference between Centralized and Distributed (Decentralized) version control systems.</p>
<p>Distributed revision control (DRCS) takes a peer-to-peer approach, as opposed to the client-server approach of centralized systems. Rather than a single, central repository on which clients synchronize, each peer&#8217;s working copy of the codebase is a bona-fide repository.  Distributed revision control conducts synchronization by exchanging patches (change-sets) from peer to peer. This results in some important differences from a centralized system:</p>
<ul>
<li>No canonical, reference copy of the codebase exists by default; only working copies.</li>
<li>Common operations (such as commits, viewing history, and reverting changes) are fast, because there is no need to communicate with a central server.</li>
<li>Rather, communication is only necessary when pushing or pulling changes to or from other peers.</li>
<li>Each working copy effectively functions as a remote backup of the codebase and of its change-history, providing natural protection against data loss.</li>
</ul>
<p><strong>Other differences are as follows:</strong></p>
<ul>
<li>In DVCS there may be many &#8220;central&#8221; repositories.</li>
<li>Code from disparate repositories is merged based on a web of trust, i.e., historical merit or quality of changes.</li>
<li>Numerous different development models are possible, such as development / release branches or a Commander / Lieutenant model, allowing for efficient delegation of topical developments in very large projects.</li>
<li>Lieutenants are project members who have the power to dynamically decide which branches to merge.</li>
<li>Network is not involved in most operations.</li>
<li>A separate set of &#8220;sync&#8221; operations are available for committing or receiving changes with remote repositories.</li>
</ul>
<p><strong>DVCS proponents point to several advantages of distributed version control systems over the traditional centralized model:</strong></p>
<ul>
<li>Allows users to work productively even when not connected to a network</li>
<li>Makes most operations much faster since no network is involved</li>
<li>Allows participation in projects without requiring permissions from project authorities, and thus arguably better fosters culture of meritocracy instead of requiring &#8220;committer&#8221; status</li>
<li>Allows private work, so users can use their revision control system even for early drafts they do not want to publish</li>
<li>Avoids relying on a single physical machine as a single point of failure.</li>
<li>Still permits centralized control of the &#8220;release version&#8221; of the project</li>
</ul>
<p><strong>DVCS disadvantages:</strong></p>
<ul>
<li>As a disadvantage of DVCS, one could note that initial cloning of a repository is slower compared to centralized checkout, because all branches and revision history are copied. This may be relevant if access speed is low and the project is large enough.</li>
<li>Another problem with DVCS is the lack of locking mechanisms that is part of most centralized VCS and still plays an important role when it comes to non-mergable binary files such as graphic assets.</li>
</ul>
<h2>SVN</h2>
<p>SVN or Subversion is Centralized Version Control (CVCS) tool and belongs to second generation of Version Control tools. It was developed in 2000 and at this moment maintained by Apache.</p>
<p>SVN is the third implementation of a revision control: RCS, then CVS and finally SVN. SVN offers VCS features (labeling and merging), but its tag is just a directory copy (like a branch, except you are not &#8220;supposed&#8221; to touch anything in a tag directory), and its merge is still complicated, currently based on meta-data added to remember what has already been merged.</p>
<h2>GIT</h2>
<p>GIT is Decentralized Version Control (DVCS) tool and belongs to third generation of Version Control tools.</p>
<p>GIT was initially designed and developed by Linus Torvalds for Linux kernel development. Every GIT working directory is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server.</p>
<p>GIT is a <strong>file content management</strong> (a tool made to merge files), <strong>evolved into a true Version Control System</strong>, based on a DAG (Directed Acyclic Graph) of commits, where branches are part of the history of data (and not a data itself), and where tags are a true meta-data.</p>
<h2>GIT over SVN</h2>
<h3>Distributed Nature</h3>
<p>Git was designed from the ground up as a distributed version control system. Being a distributed version control system means that multiple redundant repositories and branching are first class concepts of the tool.</p>
<p>In a distributed VCS like Git every user has a complete copy of the repository data stored locally, thereby making access to file history extremely fast, as well as allowing full functionality when disconnected from the network. It also means every user has a complete backup of the repository. Have 20 users? You probably have more than 20 complete backups of the repository as some users tend to keep more than one repository for the same project. If any repository is lost due to system failure only the changes which were unique to that repository are lost. If users frequently push and fetch changes with each other this tends to be a small amount of loss, if any.</p>
<p>In a centralized VCS like Subversion only the central repository has the complete history. This means that users must communicate over the network with the central repository to obtain history about a file. Backups must be maintained independently of the VCS. If the central repository is lost due to system failure it must be restored from backup and changes since that last backup are likely to be lost. Depending on the backup policies in place this could be several human-weeks worth of work.</p>
<h3>Access control</h3>
<p>Due to being distributed, you inherently do not have to give commit access to other people in order for them to use the versioning features. Instead, you decide when to merge what from whom.</p>
<p>That is, because subversion controls access, in order for daily checkins to be allowed &#8211; for example &#8211; the user requires commit access. In git, users are able to have version control of their own work while the source is controlled by the repo owner.</p>
<h3>Branch handling</h3>
<p>Branches in Git are a core concept used every day by every user. In Subversion they are more cumbersome and often used sparingly.</p>
<p>The reason branches are so core in Git is every developer&#8217;s working directory is itself a branch. Even if two developers are modifying two different unrelated files at the same time it&#8217;s easy to view these two different working directories as different branches stemming from the same common base revision of the project.</p>
<p>Consequently Git:</p>
<p>Tracks the project revision the branch started from &#8211; this information is necessary to merge the branch back to trunk</p>
<ul>
<li>Records branch merge events including:</li>
<ul>
<li>Author, time and date</li>
<li>Branch and revision information</li>
<li>Changes made on the branch(es) remain attributed to the original authors and the original timestamps of those changes</li>
<li>What changes were made to complete the merge? These are attributed to the merging user</li>
<li>Why the merge was done (optional; can be supplied by the user).</li>
</ul>
<li>Automatically starts the next merge at the last merge.</li>
<ul>
<li>Knowing what revision was last merged is necessary in order to successfully merge the same branches together again in the future.</li>
</ul>
</ul>
<p>This is different to Subversion&#8217;s handling of branches. As of Subversion 1.5:</p>
<ul>
<li>Automatically tracks the project revision the branch started from.</li>
<ul>
<li>Like Git, Subversion remembers where a branch originated.</li>
</ul>
<li>If the merging user had to modify 12 lines of code to complete the merge successfully you can&#8217;t tell what those 12 lines were, or how those 12 lines differ from the versions on the branches being merged.</li>
</ul>
<p>In Subversion, branches and tags all are copies. Sometimes this is inconvenient, it is easy to check out the whole repository by mistake. Branch path and file path lie in same namespace but they have different semantics &#8211; this can be confusing.</p>
<h3>Performance (Speed of Operation)</h3>
<p>Git is extremely fast. Since all operations (except for push and fetch) are local there is no network latency involved to:</p>
<ul>
<li>Perform a diff.</li>
<li>View file history.</li>
<li>Commit changes.</li>
<li>Merge branches.</li>
<li>Obtain any other revision of a file (not just the prior committed revision).</li>
<li>Switch branches.</li>
</ul>
<h3>Smaller Space Requirements</h3>
<p>Git&#8217;s repository and working directory sizes are extremely small when compared to SVN.</p>
<p>For example the Mozilla repository is reported to be almost 12 Gb when stored in SVN using the fsfs backend. Previously, the fsfs backend also required over 240,000 files in one directory to record all 240,000 commits made over the 10 year project history. This was fixed in SVN 1.5, where every 1000 revisions are placed in a separate directory. The exact same history is stored in Git by only two files totaling just over 420 Mb. This means that SVN requires 30x the disk space to store the same history.</p>
<p>One of the reasons for the smaller repo size is that an SVN working directory always contains two copies of each file: one for the user to actually work with and another hidden in .svn/ to aid operations such as status, diff and commit. In contrast a Git working directory requires only one small index file that stores about 100 bytes of data per tracked file. On projects with a large number of files this can be a substantial difference in the disk space required per working copy.</p>
<p>As a full Git clone is often smaller than a full checkout, Git working directories (including the repositories) are typically smaller than the corresponding SVN working directories. There are even ways in Git to share one repository across many working directories, but in contrast to SVN, this requires the working directories to be collocated.</p>
<h3>Line Ending Conversion</h3>
<p>Subversion can be easily configured to automatically convert line endings to CRLF or LF, depending on the native line ending used by the client&#8217;s operating system. This conversion feature is useful when Windows and UNIX users are collaborating on the same set of source code.</p>
<p>It is also possible to configure a fixed line ending independent of the native operating system. Files such as a Makefile need to only use LFs, even when they are accessed from Windows. This can be adjusted in a global config and overridden in user configs. Binary files are checked in with a binary flag (like with CVS except that SVN does this almost always automatically) and such never get converted or keyword substituted.</p>
<p>Subversion also allows the user to specify line ending conversion on a file-by-file basis. But if the user does not check the binary flag on adding (Subversion prints for every added file whether it recognized it as binary) binary content might get corrupted.</p>
<p>Whilst Git versions prior 1.5.1 never convert files and always assume that every file is opaque and should not be modified. Git 1.5.1 and onwards make [line ending conversion configurable]. Git&#8217;s advantage over Subversion is that you do not have to manually specify which files this conversion should be applied to, it happens automatically (hence autocrlf).</p>
<h2>SVN over GIT</h2>
<h3>Single repository</h3>
<p>Since Subversion only supports a single repository there is little doubt about where something is stored. Once a user knows the repository URL they can reasonably assume that all materials and all branches related to that project are always available at that location. Backup to tape/CD/DVD is also simple as there is exactly one location that needs to be backed up regularly.</p>
<p>Since Git is distributed by nature not everything related to a project may be stored in the same location. Therefore there may be some degree of confusion about where to obtain a particular branch, unless repository location is always explicitly specified. There may also be some confusion about which repositories are backed up to tape/CD/DVD regularly, and which aren&#8217;t.</p>
<h3>Access control</h3>
<p>Since Subversion has a single central repository it is possible to specify read and write access controls in a single location and have them be enforced across the entire project.</p>
<h3>Binary files</h3>
<h3>Detection and properties</h3>
<p>Subversion can be used with binary files (it is automatically detected; if that detection fails, you have to mark the file binary yourself). Just like Git.</p>
<p>Only that with Git, the default is to interpret the files as binary to begin with. If you _have_ to have CR+LF line endings (even though most modern programs grok the saner LF-only line endings just fine), you have to tell Git so. Git will then autodetect if a file is text (just like Subversion), and act accordingly. Analogous to Subversion, you can correct an erroneous autodetection by setting a git attribute.</p>
<h3>Change tracking</h3>
<p>In an earlier version of git seemingly minor changes to binary files, such as adjusting brightness on an image, could be different enough that Git interprets them as a new file, causing the content history to split. Since Subversion tracks by file, history for such changes is maintained.</p>
<h3>Partial Checkout/Bandwidth Requirements</h3>
<p>With Subversion, you can check out just a subdirectory of a repository. This is not possible with Git. For a large project, this means that you always have to download the whole repository, even if you only need the current version of some sub-directory. In times where fast Internet connections are only available in most cities and traffic over mobile internet connections is expensive, git can cost much more time and money in rural areas or with mobile devices. This is arguably mitigated by the small size of git repositories.</p>
<p>In other cases, requirements other than the raw repository size provide the motivation for wanting a partial checkout, e.g. access control (you can&#8217;t restrict read access to part of the repository with Git) or directory layout requirements. There is no general solution for this problem other than to split the original Git repository into multiple repositories, then cloning one of the new repositories. (Git subprojects can mitigate some of the difficulties of managing the collection of new repositories.)</p>
<h3>Shorter and Predictable Revision Numbers</h3>
<p>First, as SVN assigns revision numbers sequentially (starting from 1) even very old projects such as Mozilla have short unique revision numbers (Mozilla is only up to 6 digits in length). Many users find this convenient when entering revisions for historical research purposes. They also find this number easy to embed into their product, supposedly making it easy to determine which sources were used to create a particular executable. However since the revision number is global to the entire repository, including all branches, there is still a question of which branch the revision number corresponds to.</p>
<p>Unless the last committed revision is recorded. Since revisions are global for a repository, the last committed revision makes it possible to determine which branch was used</p>
<p>As Git uses a SHA1 to uniquely identify a commit each specific revision can only be described by a 40 character hexadecimal string, however this string not only identifies the revision but also the branch it came from. In practice the first 8 characters tends to be unique for a project, however most users try to not rely on this over the long term. Rather than embedding long commit SHA1s into executables Git users generate a uniquely named tag. This is an additional step, but a simple one.</p>
<p>Secondly, SVN&#8217;s revision numbers are predictable. If the current commit is 435 the next one will be 436. It&#8217;s very easy then to go through a few sequential revisions to, e.g. look at differences, revert to an old revision to find when a regression was introduced, etc. Furthermore, without looking up any additional information, you know that commit 436 was done after 435. Similar actions and knowledge from git requires looking at the log.</p>
<p>Git provides shorthand syntax to partially compensate for this by allowing you to add any number of ^ after a revision to indicate how far back to go. e8fa9c^^^..e8fa9c, for instance, would show the history for e8fa9c and it&#8217;s 3 parent revisions. (However, it does not provide any shorthand syntax for going forward in time.)</p>
<h2>Conclusion</h2>
<p>Both VC systems can deliver almost everything a modern developer need. Personally I prefer GIT as it is more intuitive (to me) and faster. I think that it is even more reliable.</p>
<p><strong>What do you think? What VCS are you using?</strong></p>
<div class="shr-publisher-1192"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fgit-vs-svn' data-shr_title='GIT+vs+SVN'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/Z5th1LNi3CRIFTw1pf16aNngbwc/0/da"><img src="http://feedads.g.doubleclick.net/~a/Z5th1LNi3CRIFTw1pf16aNngbwc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Z5th1LNi3CRIFTw1pf16aNngbwc/1/da"><img src="http://feedads.g.doubleclick.net/~a/Z5th1LNi3CRIFTw1pf16aNngbwc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=ZUH3-UowUE4:SQfv3uTu-0o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=ZUH3-UowUE4:SQfv3uTu-0o:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=ZUH3-UowUE4:SQfv3uTu-0o:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=ZUH3-UowUE4:SQfv3uTu-0o:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/ZUH3-UowUE4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/git-vs-svn/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/git-vs-svn</feedburner:origLink></item>
		<item>
		<title>Invoicera: Great Online Solution To Streamline Your Invoicing Process</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/hbkPocBAU9c/invoicera-great-online-solution-to-streamline-your-invoicing-process</link>
		<comments>http://www.codeforest.net/invoicera-great-online-solution-to-streamline-your-invoicing-process#comments</comments>
		<pubDate>Thu, 12 Jan 2012 21:08:58 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[resources]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1185</guid>
		<description><![CDATA[When it comes to operating an online business, creating invoice often creates a lot of trouble for businesses. It may appear like a trifle task but generating effective invoices is a must for an online business and it can be really troublesome. ]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>When it comes to operating an online business, creating invoice often creates a lot of trouble for businesses. It may appear like a trifle task but generating effective invoices is a must for an online business and it can be really troublesome.</p>
<p>However, if you have a flexible, robust and user friendly invoicing application at your disposal, you certainly need not worry. For an online business, it is imperative to keep all the financial records in a well organized manner. This is precisely what <a href="http://www.invoicera.com/?rid=NzIxODc=" target="_blank">Invoicera</a> is good at. Invoicera is a perfect <a href="http://www.invoicera.com/?rid=NzIxODc=" target="_blank">online invoicing</a> tool that can help your business run in a smooth and organized manner.</p>
<h2>How Invoicera Can be an Asset To Your Company?</h2>
<h3>Interface and Usability of Invoicera</h3>
<p>The very approach of Invoicera is quite professional and focused. It has a simple, user friendly and visually appealing interface that helps you generate thoroughly professional invoices. It is not overloaded with too many features and hence there is no cluttered look. Whatever needs to be done can be done easily using the features incorporated in a layout with minimal stuff in it. This makes it very easy to use and hence people with limited technical prowess can also use it effectively. You need not be a tech savvy person to work with Invoicera. That is the best thing about Invoicera. It is flexible enough to meet the requirements and capabilities of users.</p>
<p><img class="aligncenter size-full wp-image-1187" title="Invoicera online invoicing" src="http://www.codeforest.net/wp-content/uploads/2012/01/invoicera2.jpg" alt="Invoicera online invoicing" width="540" height="232" /></p>
<h3>Ensure Greater Transparency Through Reminders</h3>
<p>In order to keep a track of the payments due, it is imperative to possess a tool that sends a reminder automatically to your customers and clients. And this is done with perfect precision with Invoicera tool. By keeping sending reminders on time, it also helps you to check out any customer who has not made payments for long and has gone into defaulters list. Through the Invoicera tool, you can check when your customers are logging in so that they cannot claim later of not being able to see the bills on time and thus delaying payments.</p>
<h3>Sprucing Up With Your Company’s Template</h3>
<p>You surely would like your clients to get a peek into what your company is like, even though they might be sitting at the farthest corners of the globe. For this, Invoicera endows you the opportunity to equip your Invoice with templates that can be customized and tweaked in accordance with your company’s profile and logo as well as your needs.</p>
<h3>Some Other Useful Features of Invoicera</h3>
<ul>
<li><strong>Multiple Languages and Currency Support</strong>: It helps in creating and sending invoices to your clients in their respective currency and language. Invoices in 11 languages can be created for your individual clients from all across the world. This will make your clients comfortable with meaningful and accurate invoices.</li>
<li><strong>Customized Invoice Template</strong>: To make sure your business identity is reflected and represented through the invoices received by your clients, professionally multiple designed templates have been provided. For those who are not that much technically sound to customize their template, for those Invoicera has come up with a Template Customization Service, with which you can get your invoice/estimate template customized by their experts as per your requirements.</li>
<li><strong>Magento Extension</strong>: With Invoicera&#8217;s magento extension, you can easily generate and send professional invoices to your customers with in real time as soon as they place an order on your store.</li>
<li><strong>Invoicera with Google Apps</strong>: If you are a user of Google apps, then using Invoicera will create many benefits here. The application can easily be accessed through Google apps with single sign in process and further utilizing Invoicera with single Google sub-domain.</li>
<li><strong>Invoice Scheduling</strong>: Scheduling of your invoice to be sent on specific date and time can be carved out. It would be sent automatically on the set date &amp; time without any complexity. This will make your workload lighter.</li>
<li><strong>Late Fees Payment</strong>: Invoicera gives you the option to charge late fees from the defaulters. It is just one click away and you can add late fee charges in the invoice and get paid in either percentage terms or in a fixed amount</li>
<li><strong>Referral Program</strong>: With Invoicera’s <a href="http://www.invoicera.com/blog/updates/now-earn-40-referral-commission-with-our-referral-program" target="_blank">Referral Program</a>, you can earn 40% recurring commission for life time by simply getting your friends or your business contacts to sign up for the Invoicera&#8217;s paid subscription.</li>
</ul>
<h2>Final Thoughts</h2>
<p>Thus, by doing deep invoicing review, I have found that overall Invoicera is a great package for all type of businesses that don’t require or need the complexness that full double-entry accounting system wants.</p>
<p>The user interface is simply great and eye catching, it’s very easy and quick to learn and simple to use and with the new addition to its features, it has added more value to basic invoicing functionality.</p>
<p>Invoicera with its multifunctional features will not only augment your invoicing process but also assist you to build a good relation with your customers.</p>
<p><strong>Do you use Invoicera? Share your experience below&#8230;.</strong></p>
<div class="shr-publisher-1185"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Finvoicera-great-online-solution-to-streamline-your-invoicing-process' data-shr_title='Invoicera%3A+Great+Online+Solution+To+Streamline+Your+Invoicing+Process'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/1PKpRFNdU_f14YsX5LNV2KBEBWI/0/da"><img src="http://feedads.g.doubleclick.net/~a/1PKpRFNdU_f14YsX5LNV2KBEBWI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/1PKpRFNdU_f14YsX5LNV2KBEBWI/1/da"><img src="http://feedads.g.doubleclick.net/~a/1PKpRFNdU_f14YsX5LNV2KBEBWI/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=hbkPocBAU9c:jytlugtutF4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=hbkPocBAU9c:jytlugtutF4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=hbkPocBAU9c:jytlugtutF4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=hbkPocBAU9c:jytlugtutF4:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/hbkPocBAU9c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/invoicera-great-online-solution-to-streamline-your-invoicing-process/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/invoicera-great-online-solution-to-streamline-your-invoicing-process</feedburner:origLink></item>
		<item>
		<title>Custom post fields using Advanced Custom Fields WordPress plugin</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/OpzQL2-nq-0/wordpress-how-to-make-custom-post-field-using-advanced-custom-fields-plugin</link>
		<comments>http://www.codeforest.net/wordpress-how-to-make-custom-post-field-using-advanced-custom-fields-plugin#comments</comments>
		<pubDate>Sun, 11 Dec 2011 21:34:40 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Expert]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1153</guid>
		<description><![CDATA[WordPress is one of the most powerful platform on the web today. I am going to show you how easy it is to make Google Maps custom post field using the great Advanced Custom Post Fields WordPress Plugin. At the end of tutorial you will have a Google Map and when you click it, the location will be saved in your custom field type which you can then show on the Map in the frontend.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>The time when <strong>WordPress</strong> was used mainly as a blog engine has passed and WordPress has become one of the most powerful Content Management Systems on the web.</p>
<p><strong>Custom post types</strong> allows flexibility and give enormous power to WordPress. Usually, we use custom post types with built-in fields like excerpt, content editor, thumbnail etc.</p>
<p>But often, we need some special type of fields for dealing with customer wishes like date picker, relationships, file upload etc.</p>
<p>This is where <strong>Advanced Custom Fields</strong> plugin comes in.</p>
<h2>Advanced custom fields overview</h2>
<p>The Advanced Custom Fields Plugin gives you the tools to create your own custom edit screens. It’s a must have for any WordPress developer. Field types include: Wysiwyg, text, textarea, image, file, select, checkbox, page link, post object, date picker, repeater &#8230;</p>
<p>Advanced Custom Fields Plugin provides a simple to use interface allowing you to create, edit, reorder and completely customize your edit screens.</p>
<p>With Advanced Custom Fields Plugin it is not only possible to create new fields, but to hide WordPress’s default fields as well.</p>
<h2>Installing the plugin</h2>
<p>Installation is the same as for any WordPress plugin</p>
<ol>
<li>Download <a href="http://wordpress.org/extend/plugins/advanced-custom-fields/" target="_blank">Advanced Custom Fields plugin</a></li>
<li>Upload &#8216;advanced-custom-fields&#8217; to the &#8216;/wp-content/plugins/&#8217; directory</li>
<li>Activate the plugin through the &#8216;Plugins&#8217; menu in WordPress</li>
<li>You may be prompted for a Database Upgrade. This is necessary for ACF to function. Please backup your database and click the Upgrade button</li>
</ol>
<h2>Usage</h2>
<p>Once the plugin is uploaded and activated, go to Settings and click on the Adv Custom Fields link and then “Add New”. You can then give a name to your new set of fields (for example “Columns”) and add as many types of custom fields as you want. Currently supported types are:</p>
<ul>
<li>Text</li>
<li>Text area</li>
<li>WYSIWYG Editor</li>
<li>Image</li>
<li>File</li>
<li>Select</li>
<li>Checkbox</li>
<li>Radio Button</li>
<li>True / False</li>
<li>Page Link</li>
<li>Post Object</li>
<li>Relationship</li>
<li>Date Picker</li>
<li>Repeater (it costs $25)</li>
</ul>
<p>Advanced Custom Fields interface is very intuitive and it is very simple to add custom fields groups and assign them to what ever you want. You can decide what Pages, Posts or Custom Post Types you want to have this new set of Custom Fields. For example, you could have all Pages, or all Posts, or only a specific page (for example Home), or all posts in a certain category:</p>
<p><img class="aligncenter size-full wp-image-1154" title="Advanced Custom Fields options page" src="http://www.codeforest.net/wp-content/uploads/2011/12/acf1.jpg" alt="Advanced Custom Fields options page" width="590" height="259" /></p>
<p>Advanced Custom Fields also lets you decide what other fields are available on the page. So you can remove the Content Editor, Slug, Author etc and control that and you new fields all from one place.</p>
<p><img class="aligncenter size-full wp-image-1156" title="Advanced Custom Fields" src="http://www.codeforest.net/wp-content/uploads/2011/12/acf2.jpg" alt="Advanced Custom Fields" width="570" height="286" /></p>
<h2>Advanced Custom Fields API</h2>
<p>Plugin also have a powerful API for dealing with your fields. For example, to display a field on the theme inside a loop:</p>
<pre class="brush: php; ">

&lt;p&gt;&lt;?php the_field(&#039;field_name&#039;); ?&gt;&lt;/p&gt;
</pre>
<p>More about the API can be read on <a href="http://plugins.elliotcondon.com/advanced-custom-fields/documentation/" target="_blank">Plugin&#8217;s official documentation page</a>.</p>
<h2>Extending the plugin</h2>
<p>Now, you may think that all this is enough. Well, for an average developer it should be. But, if you want to make some really cool types of fields, you can. That is the beauty of this powerful plugin.</p>
<p>I am going to show you how easy it is to make your own custom post field on a real life example. At the end of this tutorial, you can download custom post field type shown here.</p>
<h2>The problem</h2>
<p>Your customer wants to enter Events into WordPress and wants to select a location of the event by simply clicking on Google Map.</p>
<h2>Making the Events custom post type</h2>
<p>To make this work, we need a custom post type named Events in which our customer will enter data. First, let us see what data will be needed:</p>
<ul>
<li>Title</li>
<li>Image</li>
<li>Description</li>
<li>Date</li>
<li>Time</li>
<li>Location &#8211; shown on Google Maps</li>
</ul>
<p>Let&#8217;s begin by making this post type. Open your theme&#8217;s <em>functions.php</em> and enter this in:</p>
<pre class="brush: php; ">

function eventRegister()
{
$labels = array(
&#039;name&#039; =&gt; _x(&#039;Events&#039;, &#039;post type general name&#039;),
&#039;singular_name&#039; =&gt; _x(&#039;Event&#039;, &#039;post type singular name&#039;),
&#039;add_new&#039; =&gt; _x(&#039;Add New&#039;, &#039;portfolio item&#039;),
&#039;add_new_item&#039; =&gt; __(&#039;Add New Event&#039;),
&#039;edit_item&#039; =&gt; __(&#039;Edit Event&#039;),
&#039;new_item&#039; =&gt; __(&#039;New Event&#039;),
&#039;view_item&#039; =&gt; __(&#039;View Event&#039;),
&#039;search_items&#039; =&gt; __(&#039;Search Events&#039;),
&#039;not_found&#039; =&gt; __(&#039;Nothing found&#039;),
&#039;not_found_in_trash&#039; =&gt; __(&#039;Nothing found in Trash&#039;),
&#039;parent_item_colon&#039; =&gt; &#039;&#039;
);

$args = array(
&#039;labels&#039; =&gt; $labels,
&#039;public&#039; =&gt; true,
&#039;publicly_queryable&#039; =&gt; true,
&#039;show_ui&#039; =&gt; true,
&#039;query_var&#039; =&gt; true,
&#039;capability_type&#039; =&gt; &#039;post&#039;,
&#039;hierarchical&#039; =&gt; false,
&#039;menu_position&#039; =&gt; null,
&#039;supports&#039; =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;),
&#039;rewrite&#039; =&gt; true,
&#039;show_in_nav_menus&#039; =&gt; true,
);

register_post_type(&#039;event&#039; , $args);
}

add_action(&#039;init&#039;, &#039;eventRegister&#039;);
</pre>
<p>Save <em>functions.php</em> and go to WordPress admin dashboard. You will see newly created Custom Post type in the left hand menu. Wow, that was easy.</p>
<p>Click on Add Event and you will see something similar to this:</p>
<p><img class="aligncenter size-full wp-image-1157" title="Add events custom post type" src="http://www.codeforest.net/wp-content/uploads/2011/12/acf3.jpg" alt="Add events custom post type" width="570" height="230" /></p>
<p>You can enter title, description and thumbnail image. Now, open your Advanced Custom Fields under Settings and click Add new. We will add other fields into field group called Events and it should look like this:</p>
<p><img class="aligncenter size-full wp-image-1159" title="Advanced custom fields - field group" src="http://www.codeforest.net/wp-content/uploads/2011/12/acf4.jpg" alt="Advanced custom fields - field group" width="570" height="319" /></p>
<p>If you go to Add Event page now, you should see that you can now pick an event date and enter a time.</p>
<p>Wow, that was really easy. Now comes the hard part.</p>
<h2>Making our own custom field type</h2>
<p>Author of this great plugin has made our lives easier and give us a Class template for making our own custom field types for ACF. <a href="http://codeforest.net/demo/my_field.php_.zip" target="_blank">Download it here</a>, unpack it and place it inside your active theme. I prefer to create a fields folder in my theme&#8217;s root and put this template in it.</p>
<p>Now rename this file to <em>location.php</em>. Open it up in your editor and rename the class, the name variable and the title:</p>
<pre class="brush: php; ">

class Location_field extends acf_Field
{
function __construct($parent)
{
// do not delete!
parent::__construct($parent);

// set name / title
$this-&gt;name = &#039;location&#039;; // variable name (no spaces / special characters / etc)
$this-&gt;title = __(&quot;Location&quot;,&#039;acf&#039;); // field label (Displayed in edit screens)

} ...
</pre>
<p>Next, we must register this field so ACF plugin will know about it. Open your theme&#8217;s <em>functions.php</em> and enter this anywhere:</p>
<pre class="brush: php; ">

register_field(&#039;Location_field&#039;, dirname(__FILE__) . &#039;/fields/location.php&#039;);
</pre>
<p>This function will register our field in the ACF. It has 2 parameters, the first is our Class name and the second is the path to the Class file.</p>
<p>If you go to Advanced Custom Fields Settings, you should see Location in the drop down:</p>
<p><img class="aligncenter size-full wp-image-1163" title="Location field in the drop down" src="http://www.codeforest.net/wp-content/uploads/2011/12/acf5.jpg" alt="Location field in the drop down" width="570" height="258" /></p>
<p>Next thing we are going to do is create our Latitude and Longitude field that will be shown on edit screen and populated with values from Google Map.</p>
<p>For this, we will need create_field function inside our <em>location.php</em> file:</p>
<pre class="brush: php; ">

function create_field($field)
{
echo &#039;&lt;input type=&quot;text&quot; value=&quot;&#039; . $field[&#039;value&#039;] . &#039;&quot; id=&quot;&#039; . $field[&#039;name&#039;] . &#039;&quot; class=&quot;&#039; . $field[&#039;class&#039;] . &#039;&quot; name=&quot;&#039; . $field[&#039;name&#039;] . &#039;&quot; /&gt;&#039;;
echo &#039;&lt;div id=&quot;map&quot;&gt;&lt;/div&gt;&#039;;
}
</pre>
<p>Save this file and go add Location field to field group inside ACF settings and Update. Now, go to entering new Event and you will see our Location text field. Everything is working, field gets saved to database. Basically, we recreated the text field.</p>
<h2>Adding Google Map</h2>
<p>Next task is to add a Google Map and some Google Map API, so when the user clicks on the map, we will get the Latitude and Longitude of that point and fill our Location field with it.</p>
<p>For this use, we will use admin_head function, which is great for inserting CSS and JavaScript:</p>
<pre class="brush: php; ">

function admin_head()
	{
		?&gt;
		&lt;style type=&quot;text/css&quot;&gt;
			#map {width: 100%; height: 500px; margin-top: 10px;}
		&lt;/style&gt;
		    &lt;script src=&#039;http://maps.googleapis.com/maps/api/js?sensor=false&#039; type=&#039;text/javascript&#039;&gt;&lt;/script&gt;
			&lt;script type=&quot;text/javascript&quot;&gt;
				function load() {
					var exists = 0, marker;
					// get the lat and lng from our input field
					var coords = jQuery(&#039;.location&#039;).val();
					// if input field is empty, default coords
					if (coords === &#039;&#039;) {
						lat = 45.77598686952638;
						lng = 15.985933542251587;
					} else {
						// split the coords by ;
						temp = coords.split(&#039;;&#039;);
						lat = parseFloat(temp[0]);
						lng = parseFloat(temp[1]);
						exists = 1;
					}
					// coordinates to latLng
					var latlng = new google.maps.LatLng(lat, lng);
					// map Options
					var myOptions = {
					  zoom: 8,
					  center: latlng,
					  mapTypeId: google.maps.MapTypeId.ROADMAP
					};
					//draw a map
					var map = new google.maps.Map(document.getElementById(&quot;map&quot;), myOptions);

					// if we had coords in input field, put a marker on that spot
					if(exists == 1) {
						marker = new google.maps.Marker({
							position: map.getCenter(),
							map: map,
							draggable: true
						});
					}

					// click event
					google.maps.event.addListener(map, &#039;click&#039;, function(point) {
						if (exists == 0) {
							exists = 1;
							// drawing the marker on the clicked spot
							marker = new google.maps.Marker({
								position: point.latLng,
								map: map,
								draggable: true
							});
							//put the coordinates to input field
							jQuery(&#039;.location&#039;).val(marker.getPosition().lat() + &#039;;&#039; + marker.getPosition().lng());
							// drag event for add screen
							google.maps.event.addListener(marker, &quot;dragend&quot;, function (mEvent) {
								jQuery(&#039;.location&#039;).val(mEvent.latLng.lat() + &#039;;&#039; + mEvent.latLng.lng());
							});
						} else {
							// only one marker on the map!
							alert(&#039;Marker already on the map! Drag it to desired location.&#039;);
						}
					});
					//dragend event for update screen
					if(exists === 1) {
						google.maps.event.addListener(marker, &quot;dragend&quot;, function (mEvent) {
							jQuery(&#039;.location&#039;).val(mEvent.latLng.lat() + &#039;;&#039; + mEvent.latLng.lng());
						});
					}
				}

			jQuery(document).ready(function(){
				load();
			});
			&lt;/script&gt;

		&lt;?php
	}
</pre>
<p>There is plenty of comments above in the code, so everything is self explanatory.</p>
<p>When you go to add new Event, you will now see a Google Map below your Location field. When you click on a map, Lat and Long coordinates will be filled into your Location field. You can even drag a marker on a map to change the location! How cool is that?</p>
<p>Now, all we have to do is to show this Event in our theme, along with a Google Map.</p>
<h2>Showing the location in the theme</h2>
<p>Actually, it is very easy to show the coordinates we entered in our event in the theme. Advanced Custom Fields has a great API for that.</p>
<p>To use the coordinates, just enter this inside your WordPress loop:</p>
<pre class="brush: php; ">

the_field(&#039;location&#039;);
</pre>
<p>But, I want to show this coordinates in a map. So create a <em>single-event.php</em> file in your theme&#8217;s folder and enter something like this (this is just the content inside a single post loop for TwentyEleven Theme):</p>
<pre class="brush: php; ">

&lt;div class=&quot;entry-content&quot;&gt;
&lt;?php the_content(); ?&gt;
&lt;p&gt;Date of the event: &lt;?php the_field(&#039;date&#039;); ?&gt; &lt;?php the_field(&#039;time&#039;); ?&gt;&lt;/p&gt;
&lt;div id=&quot;map&quot; style=&quot;width: 500px; height: 350px;&quot;&gt;&lt;/div&gt;
&lt;?php
$location = get_field(&#039;location&#039;);
$temp = explode(&#039;;&#039;, $location);
$lat = (float) $temp[0];
$lng = (float) $temp[1];
?&gt;
&lt;script src=&#039;http://maps.googleapis.com/maps/api/js?sensor=false&#039; type=&#039;text/javascript&#039;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[
function load() {
var lat = &lt;?php echo $lat; ?&gt;;
var lng = &lt;?php echo $lng; ?&gt;;
// coordinates to latLng
var latlng = new google.maps.LatLng(lat, lng);
// map Options
var myOptions = {
zoom: 9,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//draw a map
var map = new google.maps.Map(document.getElementById(&quot;map&quot;), myOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map
});
}
// call the function
load();
//]]&gt;
&lt;/script&gt;
&lt;?php wp_link_pages( array( &#039;before&#039; =&gt; &#039;&lt;div class=&quot;page-link&quot;&gt;&lt;span&gt;&#039; . __( &#039;Pages:&#039;, &#039;twentyeleven&#039; ) . &#039;&lt;/span&gt;&#039;, &#039;after&#039; =&gt; &#039;&lt;/div&gt;&#039; ) ); ?&gt;
&lt;/div&gt;&lt;!-- .entry-content --&gt;
</pre>
<p>Or, you can make a page with events and one map that will show all your events. What ever you want, is achievable now.</p>
<h2>Conclusion</h2>
<p>WordPress is a very powerful tool and stuff described above, makes it even more powerful. Your imagination is the limit.</p>
<p><a class="source_files" href="http://codeforest.net/demo/cust_fields.rar" target="_blank">Demo</a><br />
<strong>Don&#8217;t hesitate to share your thoughts or ask a question below.</strong></p>
<div class="shr-publisher-1153"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fwordpress-how-to-make-custom-post-field-using-advanced-custom-fields-plugin' data-shr_title='Custom+post+fields+using+Advanced+Custom+Fields+Wordpress+plugin'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/yXW8YFLvZno14LCIPHAF4UIROlc/0/da"><img src="http://feedads.g.doubleclick.net/~a/yXW8YFLvZno14LCIPHAF4UIROlc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/yXW8YFLvZno14LCIPHAF4UIROlc/1/da"><img src="http://feedads.g.doubleclick.net/~a/yXW8YFLvZno14LCIPHAF4UIROlc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=OpzQL2-nq-0:-p0njJtlx1U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=OpzQL2-nq-0:-p0njJtlx1U:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=OpzQL2-nq-0:-p0njJtlx1U:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=OpzQL2-nq-0:-p0njJtlx1U:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/OpzQL2-nq-0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/wordpress-how-to-make-custom-post-field-using-advanced-custom-fields-plugin/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/wordpress-how-to-make-custom-post-field-using-advanced-custom-fields-plugin</feedburner:origLink></item>
		<item>
		<title>Programming for kids: PHP string manipulation and arrays</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/Yt5MxCHCJMY/programming-for-kids-php-string-manipulation-and-arrays</link>
		<comments>http://www.codeforest.net/programming-for-kids-php-string-manipulation-and-arrays#comments</comments>
		<pubDate>Mon, 21 Nov 2011 22:49:22 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Basics]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1140</guid>
		<description><![CDATA[I am continuing my Programming for kids series with an overview of things my kids have done using PHP string manipulation functions.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>As I said earlier in my <a href="http://www.codeforest.net/programming-for-kids" target="_blank">Programming for kids</a> post, I started to teach my kids some basic programming stuff.</p>
<p>We were playing around with some word games and came up with a simple encrypting trick which I learned when I was a kid. </p>
<p>Basically, you type a word <strong>GERMANIKUS</strong> and substitute every character in that word with number, starting from 0.</p>
<p>So, G=0, E=1, R=2, M=3, A=4, N=5, I=6, K=7, U=8, S=9. After that, you write your message and substitute every character found in a word <strong>GERMANIKUS</strong> with a number and all other characters are just plain text. </p>
<p>For example, the word <em>Codeforest</em> would be <em>COD1F1219T</em>. Nice and interesting.</p>
<p>Now, my kids wanted to program a simple script that would take a message as a parameter and encrypt it using the above method. We chose PHP and started with writing down how the program should look and work. My kids were too eager to see the results, we first tried to work this out. This is the first version:</p>
<pre class="brush: php; ">

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;title&gt;Programming for kids - string replacing&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;?php
    $secretWord = &#039;germanikus&#039;;
    $message = &#039;Is this thing working?&#039;;
    $key = &#039;&#039;;

    $array1 = array(&#039;g&#039;,&#039;e&#039;, &#039;r&#039;, &#039;m&#039;, &#039;a&#039;, &#039;n&#039;, &#039;i&#039;, &#039;k&#039;, &#039;u&#039;, &#039;s&#039;);
    $array2 = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

    $encodedMessage = str_replace($array1, $array2, $message);

    echo &#039;Original message: &#039; . $message . &#039;&lt;br /&gt;&lt;br /&gt;&#039;;
    echo &#039;Encoded message: &#039; . strtoupper($encodedMessage);
?&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>
<a class="demo" href="http://www.codeforest.net/demo/encryption/index_first.php" target="_blank">Demo</a><br />
<br style="clear:both" />
</p>
<p>Very simple and effective. I explained everything to my kids and they were eager to continue.</p>
<p>Next step was to build a form so you can enter the message to be encrypted.</p>
<pre class="brush: php; ">

&lt;form action=&quot;&quot; method=&quot;POST&quot;&gt;
Insert your message:&lt;br /&gt;
&lt;textarea name=&quot;message&quot; rows=&quot;4&quot; cols=&quot;60&quot;&gt;&lt;/textarea&gt;&lt;br /&gt;
&lt;input type=&quot;submit&quot; value=&quot;Encode&quot; /&gt;
&lt;/form&gt;
&lt;br /&gt;

&lt;?php
    $secretWord = &#039;germanikus&#039;;

    $array1 = array(&#039;g&#039;,&#039;e&#039;, &#039;r&#039;, &#039;m&#039;, &#039;a&#039;, &#039;n&#039;, &#039;i&#039;, &#039;k&#039;, &#039;u&#039;, &#039;s&#039;);
    $array2 = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

    if($_POST) {
	$message = strip_tags($_POST[&#039;message&#039;]);
        $encodedMessage = str_replace($array1, $array2, $message);
	echo &#039;Encoded message:&lt;br /&gt;&#039;;
	echo nl2br(strtoupper($encodedMessage));
    }
?&gt;
</pre>
<p>
<a class="demo" href="http://www.codeforest.net/demo/encryption/index_second.php" target="_blank">Demo</a><br />
<br style="clear:both" />
</p>
<p>Very nice, now we have a basic encrypting mechanism. But what if we want to make this even harder to break? My older kid had an idea: we will allow user to enter a key which will be a number. If a user enters number 3, that would move number 0 (zero) to the third letter of <em>germanikus</em> word.</p>
<p>Great, let&#8217;s do it:</p>
<pre class="brush: php; ">

&lt;?php
$secretWord = &#039;GERMANIKUS&#039;;
$length = strlen($secretWord);
$secretWordArray = array();
$codeArray = array(0,1,2,3,4,5,6,7,8,9);

// making array of letters out of secretWord
for ($i = 0; $i &lt; $length; $i++) {
	$secretWordArray[$i] = $secretWord[$i];
}

if($_POST) {

	$key = strip_tags($_POST[&#039;key&#039;]);
	// calculating array with our key
	$position = $key[0];
	$number = $key[1];
	$numberOfRotations = 10 - $position;
	for($i = 0; $i &lt; $numberOfRotations; $i++) {
		array_push($codeArray, array_shift($codeArray));
	}
	$count = 0;
	foreach($codeArray as $key =&gt; $word) {
		$r[$count] = $secretWord[$key] . &#039; =&gt; &#039; . $word;
		$count++;
	}
	echo implode(&#039;, &#039;, $r) . &#039;&lt;br /&gt;&#039;;
	$message = strip_tags($_POST[&#039;message&#039;]);
	//encode
	$encodedMessage = str_replace($secretWordArray, $codeArray, strtoupper($message));
	//decode
	$decodedMessage = str_replace($codeArray, $secretWordArray, $encodedMessage);
	echo &#039;Encrypted message:&lt;br /&gt;&#039;;
	echo nl2br(strtoupper($encodedMessage));
	echo &#039;&lt;br /&gt;&#039;;
	echo &#039;Decrypted message:&lt;br /&gt;&#039;;
	echo nl2br(strtoupper($decodedMessage));
}
?&gt;
</pre>
<p>
<a class="demo" href="http://www.codeforest.net/demo/encryption/index_third.php" target="_blank">Demo</a><br />
<br style="clear:both" />
</p>
<p>When you try this demo, you will see that if you enter 3 as a key, the fourth letter will be 0. That is ok, as we want to start counting from zero.</p>
<p>That&#8217;s it, my kids were delighted with this and have learned a lot about string manipulation and a little bit about arrays in PHP.</p>
<p><strong>Please share your thoughts in comments below.</strong></p>
<div class="shr-publisher-1140"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fprogramming-for-kids-php-string-manipulation-and-arrays' data-shr_title='Programming+for+kids%3A+PHP+string+manipulation+and+arrays'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/oA7Uj9ij5JdF4LiTJZSYedNGlVc/0/da"><img src="http://feedads.g.doubleclick.net/~a/oA7Uj9ij5JdF4LiTJZSYedNGlVc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/oA7Uj9ij5JdF4LiTJZSYedNGlVc/1/da"><img src="http://feedads.g.doubleclick.net/~a/oA7Uj9ij5JdF4LiTJZSYedNGlVc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=Yt5MxCHCJMY:dx1Gc7WkrsM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=Yt5MxCHCJMY:dx1Gc7WkrsM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=Yt5MxCHCJMY:dx1Gc7WkrsM:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=Yt5MxCHCJMY:dx1Gc7WkrsM:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/Yt5MxCHCJMY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/programming-for-kids-php-string-manipulation-and-arrays/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/programming-for-kids-php-string-manipulation-and-arrays</feedburner:origLink></item>
		<item>
		<title>jQuery Mobile 1.0 Final Released</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/bIiOFZyM2co/jquery-mobile-1-0-final-released</link>
		<comments>http://www.codeforest.net/jquery-mobile-1-0-final-released#comments</comments>
		<pubDate>Thu, 17 Nov 2011 20:29:28 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery mobile]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1133</guid>
		<description><![CDATA[After one year of fine tuning and optimizing, jQuery Mobile reached its first full version release. And it did it with a bang.... The new ThemeRoller feature is just plain awesome.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><strong>jQuery Mobile</strong> has been a great mobile framework from the beginning in summer of 2010. I always liked the framework for its simplicity and a plethora of documentation. </p>
<p>Being it on site documentation or resources and tutorials that could be found around the internet (even here you can find <a href="http://www.codeforest.net/jquery-mobile-tutorial-basics" title="jQuery Mobile Tutorial: Basics" target="_blank">jQuery Mobile Tutorial: Basics</a> and <a href="http://www.codeforest.net/jquery-mobile-advanced-tutorial-rss-reader-app" target="_blank">jQuery Mobile Advanced Tutorial</a>), this framework is very well documented.</p>
<p>Coming out of their mouth:</p>
<blockquote class="pullquote"><p>Equally as important, we set out to make this framework easy for developers to get up and running fast, with a minimal learning curve.</p></blockquote>
<p>So let&#8217;s see what is new. </p>
<h2>ThemeRoller</h2>
<p>ThemeRoller is a web-based tool that makes it super simple to create custom themes without writing a single line of CSS. Drag and drop colors to create your masterpiece, then share it via URL or download a ZIP file with your custom theme stylesheet, ready for production (or additional tweaking). </p>
<p><img src="http://www.codeforest.net/wp-content/uploads/2011/11/themeroller-mobile-quickswatch-300x135.png" alt="jQuery Mobile ThemeRoller" title="jQuery Mobile ThemeRoller" width="300" height="135" class="aligncenter size-medium wp-image-1135" /></p>
<p>Yeah, it is that awesome. Enough said, go and check it out on <a href="http://jquerymobile.com/themeroller/" target="_blank">ThemeRoller page</a>.</p>
<p>The main man behind the ThemeRoller is <a href="https://twitter.com/#!/tybenz" target="_blank">Tyler Benzinger</a>, a guy who was borrowed from Adobe.</p>
<p>When you create your awesome jQuery Mobile Theme, just download the zip archive with compressed theme file (for production) as well as the uncompressed ones (for tweaking). Inside an archive there is also an <em>index.html</em> file as sample of how your theme is working on jQuery Mobile elements. Awesome.</p>
<p>One more thing: the complete source code for the new jQuery Mobile ThemeRoller tool is open source under the standard jQuery project licenses for you to improve, remix and build into your apps. The core tool is designed to work completely client-side to make it easy to drop into your code — only the download and sharing features require a bit of PHP. Go forth and <a href="https://github.com/jquery/web-jquery-mobile-theme-roller" target="_blank">fork it on GitHub</a>.</p>
<h2>Performance</h2>
<p>The team spent hours and hours optimizing the framework and gain 30-50% better performance than RC2 release. They are already working on improving touch event responsiveness, page transition and scrolling smoothness and other important factors in upcoming releases.</p>
<h2>Resources</h2>
<p>As I said earlier, jQuery Mobile has a huge community that has been incredibly active writing plugins and extensions, building frameworks and tools that enhance the library,  and writing tons of articles and tutorials. There are now 8 books on jQuery Mobile and many more in the works.</p>
<p>All resources can now be found in brand new <a href="http://jquerymobile.com/resources" target="_blank">Resources page</a>.</p>
<h2>Other news</h2>
<p>There are other great stuff on their pages like new documentation site, quick start guide, the oft-requested data-attribute reference, a set of global configuration test pages that let your easily preview key settings, a PhoneGap tips page, detailed documentation on the experimental touchOverflow feature, info on how to access new features of the fixed toolbars, and much more.</p>
<p>Since jQuery 1.7 was just recently released and has some significant changes (and improvements), only 1.6.4 is officially supported at this time. 1.7 support is planned in version 1.1.</p>
<p>All you need to get going is putting this 3 lines inside your HTML file:</p>
<pre class="brush: html; ">

&lt;link rel=&quot;stylesheet&quot; href=&quot;http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css&quot; /&gt;
&lt;script src=&quot;http://code.jquery.com/jquery-1.6.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js&quot;&gt;&lt;/script&gt;
</pre>
<h2>Platforms</h2>
<p>jQuery Mobile has broad support for the vast majority of all modern desktop, smartphone, tablet, and e-reader platforms. In addition, feature phones and older browsers are supported because of their progressive enhancement approach.</p>
<p>Get the <a href="http://jquerymobile.com/gbs/" target="_blank">full list of supported platforms</a></p>
<p>I am excited with this release, as this is a full-blown HTML 5 Mobile framework. </p>
<p><strong>What do you think? Share your comments below&#8230;</strong></p>
<div class="shr-publisher-1133"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fjquery-mobile-1-0-final-released' data-shr_title='jQuery+Mobile+1.0+Final+Released'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/TM1iiuw99xipKyHrm7tHaFVq1-I/0/da"><img src="http://feedads.g.doubleclick.net/~a/TM1iiuw99xipKyHrm7tHaFVq1-I/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/TM1iiuw99xipKyHrm7tHaFVq1-I/1/da"><img src="http://feedads.g.doubleclick.net/~a/TM1iiuw99xipKyHrm7tHaFVq1-I/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=bIiOFZyM2co:GocJgwNiFJ8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=bIiOFZyM2co:GocJgwNiFJ8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=bIiOFZyM2co:GocJgwNiFJ8:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=bIiOFZyM2co:GocJgwNiFJ8:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/bIiOFZyM2co" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/jquery-mobile-1-0-final-released/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/jquery-mobile-1-0-final-released</feedburner:origLink></item>
		<item>
		<title>jQuery UI 1.8 – The User Interface Library for jQuery – Book Review</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/P8mFFALu-sM/jquery-ui-1-8-the-user-interface-library-for-jquery</link>
		<comments>http://www.codeforest.net/jquery-ui-1-8-the-user-interface-library-for-jquery#comments</comments>
		<pubDate>Thu, 10 Nov 2011 21:09:37 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryui]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1126</guid>
		<description><![CDATA[Here is another great book from Packt Publishing that I read. This book is a massive overview of jQuery UI 1.8 - the user interface library for jQuery.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I deal with jQuery a lot in my line of work and have a great amount of understanding how jQuery works as well as how jQuery UI is helping with its great widgets.</p>
<p>When I started reading this great book, I realized that there is plenty new things I can learn out of it.</p>
<p>On the very beginning of the book, there is a detailed introduction in jQuery and jQuery UI 1.8 set up. Everything is very well explained, from download to setting up a development environment, and is easily followed even by inexperienced developers.</p>
<blockquote class="pullquote"><p>Dan Wellman, the author, has been writing computer-related articles, tutorials, and reviews for around eight years and is rarely very far from a keyboard of some description. This is his fourth book. </p></blockquote>
<p>The second chapter jumps into the explaining how jQuery UI works and is very detailed. The core css functionality is explained as well as theming, theme overriding, theme switching, widgets and how to create them, avoiding collisions etc.</p>
<p>After that book is explaining all the widgets in stunning details and great screenshots. Every single option for every widget is explained and show hot it affects the result. The detailed explaining and screenshots is what makes this book stand out.</p>
<p>In the last part, jQuery UI effects are explained with same amount of enthusiasm as in previous chapters. Even the advanced effects are shown like:</p>
<ol>
<li>Blind</li>
<li>Clip</li>
<li>Drop</li>
<li>Explode</li>
<li>Fold</li>
<li>Puff</li>
<li>Pulsate</li>
<li>Scale</li>
<li>Slide</li>
</ol>
<p>What I really like about this book is that it gave me the big picture and then gently followed me to the tiniest details in jQuery UI. All examples used in a book can really be used in a real life scenarios, and that is really something.</p>
<p>If you are interested in jQuery UI this book is definitely a must read. Even advanced developers can learn something out of it.</p>
<p>You can buy this book at Amazon: <a target="_blank" href="http://www.amazon.com/gp/product/1849516529/ref=as_li_ss_tl?ie=UTF8&#038;tag=codeforest-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399373&#038;creativeASIN=1849516529">jQuery UI 1.8: The User Interface Library for jQuery</a><img src="http://www.assoc-amazon.com/e/ir?t=codeforest-20&#038;l=as2&#038;o=1&#038;a=1849516529&#038;camp=217145&#038;creative=399373" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> or <a href="http://www.packtpub.com/jquery-ui-1-8-user-interface-library/book" target="_blank">Packt Publishing </a></p>
<div class="shr-publisher-1126"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fjquery-ui-1-8-the-user-interface-library-for-jquery' data-shr_title='jQuery+UI+1.8+-+The+User+Interface+Library+for+jQuery+-+Book+Review'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/iobDmHNexJFSydIS5N719Xrs1J4/0/da"><img src="http://feedads.g.doubleclick.net/~a/iobDmHNexJFSydIS5N719Xrs1J4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/iobDmHNexJFSydIS5N719Xrs1J4/1/da"><img src="http://feedads.g.doubleclick.net/~a/iobDmHNexJFSydIS5N719Xrs1J4/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=P8mFFALu-sM:fqtwxA4d760:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=P8mFFALu-sM:fqtwxA4d760:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=P8mFFALu-sM:fqtwxA4d760:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=P8mFFALu-sM:fqtwxA4d760:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/P8mFFALu-sM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/jquery-ui-1-8-the-user-interface-library-for-jquery/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/jquery-ui-1-8-the-user-interface-library-for-jquery</feedburner:origLink></item>
		<item>
		<title>Win $50 worth of credit for Premium Themes on 4Templates.com</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/SCdvkVrhPtM/win-50-credit-for-premium-themes-on-4templates</link>
		<comments>http://www.codeforest.net/win-50-credit-for-premium-themes-on-4templates#comments</comments>
		<pubDate>Tue, 01 Nov 2011 21:16:45 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[giveaway]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1146</guid>
		<description><![CDATA[Enter this great giveaway for a chance for winning a $50 credit on 4Templates.com - Premium Themes, Templates, WordPress Themes and more...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>How many times did you face a problem that you developed some fancy web application, but your skills as a designer are not that fancy.</p>
<p>Whatever you develop, it will never succeed if it doesn&#8217;t look good.</p>
<p>Designing is hard and sometimes you just want to take something great looking and already finished.</p>
<p>That is where guys at <a href="http://www.4templates.com/?go=119634262" target="_blank">4Templates</a> come in. Believe me, they got all you need: Site templates, WordPress Themes, Business Card templates and more. NAd prices below $30 guarantee that you are getting a bargain.</p>
<p>They even go some great Print templates.</p>
<p><a href="http://www.4templates.com/?go=119634262" target="_blank">4Templates</a> and Codeforest are giving a <strong>chance of <strong>winning $50 worth of credit</strong> on 4Templates to two of the lucky winners</strong>.</p>
<p>You can then spend your credit on State of the art Premium Templates on 4Templates.</p>
<h2>How to participate</h2>
<p>It is really simple to participate, so hurry:</p>
<ol>
<li>Share this post on Twitter</li>
<li>Leave a comment below and tell me what will you do with your <strong>$50</strong> if you are the winner</li>
</ol>
<p>Please, leave a valid email address in the comment, so I can contact you if you win.</p>
<p><strong>The lucky 2 winners will be announced on December, 14th on this blog.</strong></p>
<div class="shr-publisher-1146"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fwin-50-credit-for-premium-themes-on-4templates' data-shr_title='Win+%2450+worth+of+credit+for+Premium+Themes+on+4Templates.com'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/OhhqDyY6IY51uZuIZvAmVvHZfDE/0/da"><img src="http://feedads.g.doubleclick.net/~a/OhhqDyY6IY51uZuIZvAmVvHZfDE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/OhhqDyY6IY51uZuIZvAmVvHZfDE/1/da"><img src="http://feedads.g.doubleclick.net/~a/OhhqDyY6IY51uZuIZvAmVvHZfDE/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=SCdvkVrhPtM:bRNqXD9tCSY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=SCdvkVrhPtM:bRNqXD9tCSY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=SCdvkVrhPtM:bRNqXD9tCSY:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=SCdvkVrhPtM:bRNqXD9tCSY:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/SCdvkVrhPtM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/win-50-credit-for-premium-themes-on-4templates/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/win-50-credit-for-premium-themes-on-4templates</feedburner:origLink></item>
		<item>
		<title>Obfuscate your e-mail address with PHP, JavaScript and CSS</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/dB_JJcC6XM0/obfuscate-your-email-address-with-php-javascript-and-css</link>
		<comments>http://www.codeforest.net/obfuscate-your-email-address-with-php-javascript-and-css#comments</comments>
		<pubDate>Thu, 27 Oct 2011 19:27:29 +0000</pubDate>
		<dc:creator>Zoran Jambor</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Expert]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1089</guid>
		<description><![CDATA[According to Wikipedia, more than 97% of all e-mails sent over the net are unwanted. That’s around 200 billion spam messages per day. To keep this insane amount of spam out of your inbox, you should keep your e-mail safe when you display it on web. One of the ways to keep it safe is [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>
According to <a target="_blank" rel="nofollow" href="http://en.wikipedia.org/wiki/E-mail_spam#Statistics_and_estimates" title="Wikipedia">Wikipedia</a>, more than 97% of all e-mails sent over the net are unwanted. That’s around 200 billion spam messages per day.
</p>
<p>
To keep this insane amount of spam out of your inbox, you should keep your e-mail safe when you display it on web. One of the ways to keep it safe is to obfuscate it. In this tutorial I’ll show you how to create a script that will do just that.
</p>
<p>
Basic requirements for such script (at least from my point of view) are:
</p>
<ol>
<li>It should function pretty much out of the box. User should work only with real e-mail; script should obfuscate and deobfuscate it on the fly.</li>
<li>It should show obfuscated e-mail to bots, but real one to humans; humans should not even notice that obfuscation (or deobfusaction) is taking place.</li>
<li>Script should work on all desktop browsers (I’m talking IE6+here) and on mobile browsers as well (at least on the ones that support JavaScript).</li>
</ol>
<p>
To handle this, we’ll create a PHP function that will take string (e-mail address) as an argument. The function will reverse the address and obfuscate it using slightly modified <a target="_blank" rel="nofollow" href="http://en.wikipedia.org/wiki/ROT13" title="ROT13">ROT13</a> algorithm.
</p>
<p>
Deobfuscation will be done with JavaScript. When user opens the page we will detect which e-mail links have been obfuscated, apply reversed ROT13 algorithm on them and <em>direction:rtl</em> and <em>unicode-bidi:override</em> CSS rules.
</p>
<p>
This way, users will see real address, but spam bots will still (even if they can parse JavaScript) see a reversed e-mail.
</p>
<p>
This will, of course, leave us with a usability problem. If user copies the address, or if he clicks it, he’ll get the reversed one. Therefore, as a last deobfuscation step, we’ll reverse the reversed address and remove added CSS rules as soon as the user hovers over the link.
</p>
<p>
<a class="demo" href="http://www.codeforest.net/demo/obfuscateEmailAddress/demo.php" target="_blank">Demo</a><br />
<br style="clear:both" />
</p>
<h2>E-mail Obfuscation (PHP)</h2>
<p>Code is thoroughly commented, have a look if you’d like to know more.</p>
<pre class="brush: php; ">

//Function takes string as an argument and returns a string.
function obfuscateEmail( $email ) {

	//We will work with UTF8 characters, just to be safe that we won&#039;t mess up any address.
	$emailLetters = preg_split( &#039;//u&#039;, $email, null, 1 );
	$obfuscatedEmail = &#039;&#039;;

	//Reversing the string (e-mail).
	$emailLetters = array_reverse( $emailLetters );

	//Characters that are to be used when obfuscating email address.
	//If you change this, make sure you change the characters string in JavaScript as well.
	//And please note that the string must have even number of characters for this to work.
	$characters = &#039;123456789qwertzuiopasdfghjklyxcvbnmMNBVCXYLKJHGFDSAPOIUZTREWQ&#039;;

	//Get the number of characters dynamically.
	$charactersLength = strlen( $characters ) - 1;

	//Obfuscate string letter by letter.
	foreach( $emailLetters as $letter ) {

		//Get the current letter position in the string.
		$letterPos = strpos($characters, $letter);

		//If the character is present in our string of characters,
		//we&#039;ll switch it; if not, we&#039;ll leave it as is.
		if( $letterPos !== false ) {

			$letterPos += $charactersLength / 2;

			//For letters that are in our characters string positioned
			//after the total number of characters, we&#039;ll start from beginning.
			//For example, &quot;v&quot; becomes &quot;1&quot;, &quot;b&quot; becomes &quot;2&quot;
			$letterPos = $letterPos &gt; $charactersLength ? $letterPos - $charactersLength - 1 : $letterPos; 

			//Obfuscated letter.
			$newLetter = substr($characters, $letterPos, 1);

		} else {

			//Characters that aren&#039;t in our list will be left unchanged.
			$newLetter = $letter;

		}

		//We append obfuscated letter to the result variable.
		$obfuscatedEmail .= $newLetter;

	}

	//Sign @ is a control letter. Since more than one @ sign is illegal
	//in email address, we&#039;re going to use two @ symbols to know when
	//the string has been obfuscated (and needs deobfuscation).
	//That way you can use obfuscated e-mail only in href attribute,
	//while the link text can be something entirely different.
	//An example: &lt;a href=&quot;mailto:myemail@gmail.com&quot;&gt;This is my email&lt;/a&gt;.
	return $obfuscatedEmail . &#039;@&#039;;

}
</pre>
<p>
After you include function into your code, obfuscation can be preformed like this:
</p>
<pre class="brush: php; ">

&lt;?php
echo obfuscateEmail(&#039;mymail@mail.com&#039;);  //Obfuscated string will be: 4FQ.RGS4@RGS4E4@
?&gt;
</pre>
<p>
And in a real life usage, you&#8217;d create an obfuscated e-mail link like this:
</p>
<pre class="brush: php; ">

&lt;a class=&quot;obfuscatedEmail&quot; href=&quot;&lt;?php echo obfuscateEmail(&#039;mailto:mymail@mail.com&#039;); ?&gt;&quot; rel=&quot;nofollow&quot;&gt;&lt;?php echo obfuscateEmail(&#039;mailto:mymail@mail.com&#039;); ?&gt;&lt;/a&gt;
</pre>
<p>
We’re adding a class obfuscatedEmail to each obfuscated link. That way it will be easy for us to find all elements that need deobfuscation.
</p>
<h2>E-mail deobfuscation (JavaScript &#038; CSS)</h2>
<p>
Step one is to detect all obfuscated links on a page. That’s fairly easy to do; we just find all elements that have class <em>obfuscatedEmail</em>.
</p>
<pre class="brush: javascript; ">

//This is written to be as general as possible; you can leave this part out and just call
//deObfuscateEmail() manually on elements that should be deobfuscated.

var obfuscatedEmails = document.getElementsByTagName(&#039;a&#039;),
    obfuscatedEmailsLength = obfuscatedEmails.length,
    i = 0;

for( ; i&lt;obfuscatedEmailsLength; i++ ) {

    if( obfuscatedEmails[i].className.indexOf(&#039;obfuscatedEmail&#039;) &gt; -1 ) {

        deObfuscateEmail( obfuscatedEmails[i] );

    }

}
</pre>
<p>
I encourage you to adjust this part to your own needs. If you have only one e-mail on the page, you don’t have to loop through all page elements. Something like this would suffice:
</p>
<pre class="brush: php; ">

//PHP
&lt;a id=&quot;myObfuscatedEmail&quot; href=&quot;&lt;?php echo obfuscateEmail(&#039;mailto:mymail@mail.com&#039;); ?&gt;&quot; rel=&quot;nofollow&quot;&gt;&lt;?php echo obfuscateEmail(&#039;mailto:mymail@mail.com&#039;); ?&gt;&lt;/a&gt;

//JavaScript
deObfuscateEmail( document.getElementById(‘myObfuscatedEmail’) );
</pre>
<p>
Function deObfuscateEmail still hasn’t been created. We’ll get to it after we create a function that will change back e-mail letters based on ROT13 algorithm.
</p>
<pre class="brush: javascript; ">

//This is a first layer of deobfuscation.
//Basically a reversed ROT13 algorithm.
function changeLetters(string) {

    //Helper variables.
    var currentLetter,
        currentPos,
        currentString = &#039;&#039;,

        //Behold! The one and only counter.
        i = 0,

        //We&#039;re going to loop through the obfuscated strings characters, so this will come in handy.
        stringLength = string.length - 1,

        //Characters that will be used when deobfuscating email address.
        //Same as string in PHP obfuscate function (obfuscateEmail).
        characters = &#039;123456789qwertzuiopasdfghjklyxcvbnmMNBVCXYLKJHGFDSAPOIUZTREWQ&#039;,
        charactersLength = characters.length;

    //Counter variable has been declared before.
    for( ; i&lt;stringLength; i++ ) {

        //This letter will be deobfuscated.
        currentLetter = string.charAt(i);

        //Position of the letter in our characters string.
        currentPos = characters.indexOf(currentLetter);

        //If character is present in our string, replace it with a character
        //30 places before (opposite from obfuscating).
        //If not, leave it as it is (because character wasn&#039;t obfuscated).
        if( currentPos &gt; -1 ) {

            currentPos -= (charactersLength-1) / 2;
            currentPos = currentPos &lt; 0 ? charactersLength + currentPos : currentPos;

        } else {

            currentString += currentLetter;

        }

        //Finally, append a character to our temp string that will be returned.
        currentString += characters.charAt(currentPos);

    }

    return currentString;

}
</pre>
<p>
We&#8217;ll call this function on each letter of obfuscated e-mail.
</p>
<p>
Here’s the final part of the code, the one that takes an HTML element as a parameter, checks its value and href attribute and calls changeLetters function on each of its characters.<br />
Then it adds CSS rules to correctly show reversed address and binds mouseover event on the link, which triggers final function that re-reverses the address.
</p>
<pre class="brush: javascript; ">

//Function that will handle email deobfuscation.
//@param element is a reference to html element that will be deobfuscated.
//Deobfuscation is done on text and on href attribute of the element.
//Nevertheless, function will work well with any element you pass in,
//even if href attribute won&#039;t be present.
function deObfuscateEmail( element ) {

    //Get the text of the element.
    var text = element.innerHTML,

        //Get href attribute. If there is no href attribute, set href value to be an empty string.
        //Regular expression is an IE Fix.
        //Namely, IE appends obfuscated email to the url (www.domain.com/com.liameym@em).
        //Therefore, the first part of the link needs to be removed (we grab just everything after the last forward slash &#039;/&#039;).
        href = element.getAttribute(&#039;href&#039;).replace(/http:\/\/(.+)\//gi, &#039;&#039;) || &#039;&#039;,

        //Control variable. if the two @ symbols are present, we will perform deobfuscation,
        //if not, the string is not obfuscated and doesn&#039;t have to be deobfuscated.
        textReplace = text.search(/@.+@/),
        hrefReplace = href.search(/@.+@/),

        //This function handles the second layer of deobfuscation.
        //It is called later in the code.
        //Letters of the email are reversed (again) and css direction returned back to ltr.
        //This is called on mouseover event.
        reverseEmails = function(){

            //Only if htef is obfuscated.
            if( hrefReplace &gt; -1 ) {

                //That&#039;s the reversing part right here.
                element.setAttribute(&#039;href&#039;, href.split(&#039;&#039;).reverse().join(&#039;&#039;) );

            }

            //Only if text is obfuscated.
            if( textReplace &gt; -1 ) {

                //Reverse the text of the element and
                //return the direction to normal (left to right).
                element.innerHTML = text.split(&#039;&#039;).reverse().join(&#039;&#039;);
                element.style.direction = &#039;ltr&#039;;
                element.style.unicodeBidi = &#039;normal&#039;;

            }

            //Letters are replaced and the event isn&#039;t needed anymore.
            if( element.removeEventListener ) {

                element.removeEventListener(&#039;mouseover&#039;, reverseEmails, false);

            } else {

                // IE8-
                element.detachEvent(&#039;onmouseover&#039;, reverseEmails);

            }

        };
        //End variables and functions definitions.

    //href has to be processed first, because of the strange
    //IE bug that will mix the href and innerHTML values.
    if( hrefReplace &gt; -1 ) {

        href = changeLetters(href);
        element.setAttribute(&#039;href&#039;, href);

    }

    //Change the direction of the text to show real address
    //to users, instead of an reversed one.
    if( textReplace &gt; -1 ) {

        text = changeLetters( text );
        element.innerHTML = text;
        element.style.direction = &#039;rtl&#039;;
        element.style.unicodeBidi = &#039;bidi-override&#039;;

    }

    //Since we have a rtl text, user can&#039;t copy or click on a link.
    //Therefore we&#039;ll replace the value as soon as user hovers over the link.
    if( element.addEventListener ) {

        element.addEventListener(&#039;mouseover&#039;, reverseEmails, false);

    } else {

        element.attachEvent(&#039;onmouseover&#039;, reverseEmails);

    }

}
</pre>
<p>
If we put all these pieces of code together, we will get the fully functional deobfuscation script:
</p>
<pre class="brush: javascript; ">

(function(){

    //This is a first layer of deobfuscation.
    //Basically a reversed ROT13 algorithm.
    function changeLetters(string) {

        //Helper variables.
        var currentLetter,
            currentPos,
            currentString = &#039;&#039;,

            //Behold! The one and only counter.
            i = 0,

            //We&#039;re going to loop through the obfuscated strings characters, so this will come in handy.
            stringLength = string.length - 1,

            //Characters that will be used when deobfuscating email address.
            //Same as string in PHP obfuscate function (obfuscateEmail).
            characters = &#039;123456789qwertzuiopasdfghjklyxcvbnmMNBVCXYLKJHGFDSAPOIUZTREWQ&#039;,
            charactersLength = characters.length;

        //Counter variable has been declared before.
        for( ; i&lt;stringLength; i++ ) {

            //This letter will be deobfuscated.
            currentLetter = string.charAt(i);

            //Position of the letter in our characters string.
            currentPos = characters.indexOf(currentLetter);

            //If character is present in our string, replace it with a character
            //30 places before (opposite from obfuscating).
            //If not, leave it as it is (because character wasn&#039;t obfuscated).
            if( currentPos &gt; -1 ) {

                currentPos -= (charactersLength-1) / 2;
                currentPos = currentPos &lt; 0 ? charactersLength + currentPos : currentPos;

            } else {

                currentString += currentLetter;

            }

            //Finally, append a character to our temp string that will be returned.
            currentString += characters.charAt(currentPos);

        }

        return currentString;

    }

    //Function that will handle email deobfuscation.
    //@param element is a reference to html element that will be deobfuscated.
    //Deobfuscation is done on text and on href attribute of the element.
    //Nevertheless, function will work well with any element you pass in,
    //even if href attribute won&#039;t be present.
    function deObfuscateEmail( element ) {

        //Get the text of the element.
        var text = element.innerHTML,

            //Get href attribute. If there is no href attribute, set href value to be an empty string.
            //Regular expression is an IE Fix.
            //Namely, IE appends obfuscated email to the url (www.domain.com/com.liameym@em).
            //Therefore, the first part of the link needs to be removed (we grab just everything after the last forward slash &#039;/&#039;).
            href = element.getAttribute(&#039;href&#039;).replace(/http:\/\/(.+)\//gi, &#039;&#039;) || &#039;&#039;,

            //Control variable. if the two @ symbols are present, we will perform deobfuscation,
            //if not, the string is not obfuscated and doesn&#039;t have to be deobfuscated.
            textReplace = text.search(/@.+@/),
            hrefReplace = href.search(/@.+@/),

            //This function handles the second layer of deobfuscation.
            //It is called later in the code.
            //Letters of the email are reversed (again) and css direction returned back to ltr.
            //This is called on mouseover event.
            reverseEmails = function(){

                //Only if htef is obfuscated.
                if( hrefReplace &gt; -1 ) {

                    //That&#039;s the reversing part right here.
                    element.setAttribute(&#039;href&#039;, href.split(&#039;&#039;).reverse().join(&#039;&#039;) );

                }

                //Only if text is obfuscated.
                if( textReplace &gt; -1 ) {

                    //Reverse the text of the element and
                    //return the direction to normal (left to right).
                    element.innerHTML = text.split(&#039;&#039;).reverse().join(&#039;&#039;);
                    element.style.direction = &#039;ltr&#039;;
                    element.style.unicodeBidi = &#039;normal&#039;;

                }

                //Letters are replaced and the event isn&#039;t needed anymore.
                if( element.removeEventListener ) {

                    element.removeEventListener(&#039;mouseover&#039;, reverseEmails, false);

                } else {

                    // IE8-
                    element.detachEvent(&#039;onmouseover&#039;, reverseEmails);

                }

            };
            //End variables and functions definitions.

        //href has to be processed first, because of the strange
        //IE bug that will mix the href and innerHTML values.
        if( hrefReplace &gt; -1 ) {

            href = changeLetters(href);
            element.setAttribute(&#039;href&#039;, href);

        }

        //Change the direction of the text to show real address
        //to users, instead of a reversed one.
        if( textReplace &gt; -1 ) {

            text = changeLetters( text );
            element.innerHTML = text;
            element.style.direction = &#039;rtl&#039;;
            element.style.unicodeBidi = &#039;bidi-override&#039;;

        }

        //Since we have a rtl text, user can&#039;t copy or click on a link.
        //Therefore we&#039;ll replace the value as soon as user hovers over the link.
        if( element.addEventListener ) {

            element.addEventListener(&#039;mouseover&#039;, reverseEmails, false);

        } else {

            element.attachEvent(&#039;onmouseover&#039;, reverseEmails);

        }

    }

    //We could use native getElementsByClassName in browsers that support this method,
    //but I did a few quick tests and it seems to be slower.
    //If you have more info on performance getElementsByClassName vs getElementsByTagName + className.indexOf please let me know.
    //var obfuscatedEmails = document.getElementsByClassName(&#039;obfuscatedEmail&#039;),

    //This is written to be as general as possible; you can leave this part out and just call
    //deObfuscateEmail() manually on elements that should be deobfuscated.

    var obfuscatedEmails = document.getElementsByTagName(&#039;a&#039;),
        obfuscatedEmailsLength = obfuscatedEmails.length,
        i = 0;

    for( ; i&lt;obfuscatedEmailsLength; i++ ) {

        if( obfuscatedEmails[i].className.indexOf(&#039;obfuscatedEmail&#039;) &gt; -1 ) {

            deObfuscateEmail( obfuscatedEmails[i] );

        }

    }

}());
</pre>
<p>
<a class="demo" href="http://www.codeforest.net/demo/obfuscateEmailAddress/demo.php" target="_blank">Demo</a><a class="source_files" href="http://www.codeforest.net/demo/obfuscateEmailAddress.rar" target="_blank">Source files</a><br />
<br style="clear:both" />
</p>
<h2>Conclusion</h2>
<p>
With the amount of spam that is being sent over the internet, you surely don’t want to leave your e-mail address unattended; do everything you can to prevent it from falling in wrong (spammy) hands.
</p>
<p>
Technique that I&#8217;ve shown you here should be (if nothing else) at least a good start.
</p>
<p>
<strong>Additional readings:</strong>
</p>
<ul>
<li><a target="_blank" rel="nofollow" href="http://www.alistapart.com/articles/gracefulemailobfuscation/">Graceful E-Mail Obfuscation</a></li>
<li><a target="_blank" rel="nofollow" href="http://csarven.ca/hiding-email-addresses">Methods to hide email addresses from page source</a></li>
<li><a target="_blank" rel="nofollow" href="http://perishablepress.com/press/2010/08/01/best-method-for-email-obfuscation/">Best Method for Email Obfuscation?</a></li>
</ul>
<div class="shr-publisher-1089"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fobfuscate-your-email-address-with-php-javascript-and-css' data-shr_title='Obfuscate+your+e-mail+address+with+PHP%2C+JavaScript+and+CSS'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/16uwtAwbC0cIQQW7d8ubpuhmD0Y/0/da"><img src="http://feedads.g.doubleclick.net/~a/16uwtAwbC0cIQQW7d8ubpuhmD0Y/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/16uwtAwbC0cIQQW7d8ubpuhmD0Y/1/da"><img src="http://feedads.g.doubleclick.net/~a/16uwtAwbC0cIQQW7d8ubpuhmD0Y/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=dB_JJcC6XM0:Ugb8mt8CL2s:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=dB_JJcC6XM0:Ugb8mt8CL2s:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=dB_JJcC6XM0:Ugb8mt8CL2s:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=dB_JJcC6XM0:Ugb8mt8CL2s:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/dB_JJcC6XM0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/obfuscate-your-email-address-with-php-javascript-and-css/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/obfuscate-your-email-address-with-php-javascript-and-css</feedburner:origLink></item>
		<item>
		<title>Interview with Jeffrey Way</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/2JNUY7p8oWI/interview-with-jeffrey-way</link>
		<comments>http://www.codeforest.net/interview-with-jeffrey-way#comments</comments>
		<pubDate>Wed, 26 Oct 2011 19:40:07 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1117</guid>
		<description><![CDATA[Today I had the privilege to interview Jeffrey Way - the editor of a popular web development blog, <strong>Nettuts+</strong>, and a developer evangelist for the <strong>Envato marketplaces</strong> (ThemeForest and CodeCanyon, among others).]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I always wanted to interview influential people in development world. So, I decided to ask one of the most interesting one &#8211; <strong>Jeffrey Way</strong> of Envato (they call him &#8220;The Man&#8221;).</p>
<p>His tutorials, books and simple approach to most difficult problems have always inspired me.</p>
<p>Enjoy:</p>
<h2>Who is Jeffrey Way? Tell us something about yourself</h2>
<p>I&#8217;m the editor of a popular web development blog, <strong>Nettuts+</strong>, and a developer evangelist for the <strong>Envato marketplaces</strong> (ThemeForest and CodeCanyon, among others). These days, whenever I can manage to find some free time, I&#8217;ve been pushing myself into the Ruby on Rails world, and have been loving every second of it. </p>
<h2>How much time do you spend on learning new things?</h2>
<p>Luckily, I have a job that virtually demands that I continue learning. I wouldn&#8217;t be able to run Nettuts+ otherwise. It&#8217;s perhaps the biggest blessing I&#8217;ve had. As we all know, it&#8217;s incredibly difficult to remain relevant and up-to-date in the industry; so Nettuts+ is certainly a huge help. </p>
<p>I&#8217;d say around 20 hours a week are spent learning, reading, etc. </p>
<h2>I see that you are programming in Ruby and Ruby on Rails? Which do you prefer better, PHP or Ruby?</h2>
<p>Honestly, it&#8217;s difficult to compare the two. At this point in my career, I prefer Ruby. It&#8217;s a language that was created to be as understandable as possible. PHP is a scripting language; Ruby feels like a human language. I love that!</p>
<p>But, at the same time, PHP was made specifically for the web; Ruby wasn&#8217;t. If I was asked to recommend a language to a beginning web designer, I&#8217;d vote for PHP. </p>
<p>Many people dislike Rails because they see it as being forced to follow a specific guideline for how to build web applications. I can appreciate this line of thinking, but is that so bad? The industry is complicated enough; it helps to be nudged in the right direction as much as possible. Think of it as your best judgment vs. the best judgment of an entire group of dedicated developers. I appreciate the help. </p>
<h2>I noticed that number of your great tutorials is falling on Nettuts. I really miss the Quick tips. Why is that? No time, or working on some new projects?</h2>
<p>Are you referring to me specifically? If so, I&#8217;m putting a great deal of energy into the next release of Tuts+ Premium, which is our subscription portion of Tuts+. I&#8217;m working on creating courses, which teach skills from the inside out. </p>
<p>I&#8217;m still able to get at least one article a week out on Nettuts+ though. Quick tips will continue as well! </p>
<h2>Do you have any advice for people who try to sell items on Envato Marketplaces?</h2>
<p>I created a screencast on this very thing. Refer here: <a href="http://notes.envato.com/case-studies/be-professional-be-believable-brand-your-profile-page/" target="_blank">How to become better author on Envato?</a> </p>
<h2>Lately, I saw some lower quality additions on CodeCanyon. Is standard going down to have as much items as you can?</h2>
<p>No; our standards have increased consistently since the launch. We prefer quality over quantity; so if you do come across an item that you don&#8217;t feel fits our standards, definitely let us know. We&#8217;ll look into it immediately! <img src='http://www.codeforest.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>How is your Vegetarianism going? Do you feel better?</h2>
<p>I&#8217;ve been a vegetarian for a couple years now, and will never turn back. It&#8217;s easily the best decision I&#8217;ve ever made in my life. I&#8217;d never want to push my opinions on others, however, if it&#8217;s something that any of your readers are considering, I can&#8217;t recommend it enough. When the meat industry is tasked with feeding billions of people on this planet, can you imagine the level of abuse that occurs behind those locked doors? Chickens who spend their entire lives in darkness and in their own feces, pigs who scream in pain&#8230; all of this is real. It&#8217;s amazing how willing we are to turn a blind eye. </p>
<p>Read a couple books, or watch some documentaries on the subject. If you&#8217;re going to eat meat, at least be aware of what goes on behind the scenes. Those quaint photos of farm animals and the red barn don&#8217;t exist. There&#8217;s a reason why it&#8217;s referred to as factory farming. </p>
<h2>Do you have some free time? An how do you spend it?</h2>
<p>Well, of course; I don&#8217;t think I&#8217;d survive otherwise. I spend much of time on the computer; so, when I do have free time, I like to get outdoors. Running, sports, etc. I live up in the mountains, so it&#8217;s particularly refreshing to go hiking whenever I have the chance. </p>
<p>I don&#8217;t have as much time available as I used to, but I also still enjoy a good video game. Right now, I&#8217;m counting the days until the new Zelda comes out in November. </p>
<h2>Can you give us a sneak peak of what will be your few next steps? A new book? New project?</h2>
<p>As I briefly mentioned above, right now, I&#8217;m working full steam on the re-launch of Tuts+ Premium. For the last few months, I&#8217;ve been creating course after course &#8211; everything from WordPress plugin development, to Phing, to CSS3. If you enjoy the style of my video tutorials, you&#8217;ll feel right at home with these courses. </p>
<p>Next month, I&#8217;m hoping to finish my next HTML5 book for Rockable Press. It&#8217;ll be a compilation of everything I&#8217;ve learned in the last few years on the subject.</p>
<p><em>Thanks again for this oprtunity, Jeffrey.</em></p>
<div class="shr-publisher-1117"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Finterview-with-jeffrey-way' data-shr_title='Interview+with+Jeffrey+Way'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/t7yvwuE-b6stpHYLHUtwDaWo5is/0/da"><img src="http://feedads.g.doubleclick.net/~a/t7yvwuE-b6stpHYLHUtwDaWo5is/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/t7yvwuE-b6stpHYLHUtwDaWo5is/1/da"><img src="http://feedads.g.doubleclick.net/~a/t7yvwuE-b6stpHYLHUtwDaWo5is/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=2JNUY7p8oWI:AvqS2wSG77E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=2JNUY7p8oWI:AvqS2wSG77E:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=2JNUY7p8oWI:AvqS2wSG77E:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=2JNUY7p8oWI:AvqS2wSG77E:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/2JNUY7p8oWI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/interview-with-jeffrey-way/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/interview-with-jeffrey-way</feedburner:origLink></item>
		<item>
		<title>CakePHP 2.0 released: What’s new?</title>
		<link>http://feedproxy.google.com/~r/Codeforest/~3/-NGFxPW7u68/cakephp-2-0-released-whats-new</link>
		<comments>http://www.codeforest.net/cakephp-2-0-released-whats-new#comments</comments>
		<pubDate>Wed, 19 Oct 2011 21:32:42 +0000</pubDate>
		<dc:creator>Zvonko</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.codeforest.net/?p=1084</guid>
		<description><![CDATA[After a long time, one of the popular PHP frameworks reached 2.0 version. Let's see what is new in CakePHP 2.0.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>&#8220;CakePHP is a rapid development framework for PHP that provides an extensible architecture for developing, maintaining, and deploying applications. Using commonly known design patterns like MVC and ORM within the convention over configuration paradigm, CakePHP reduces development costs and helps developers write less code. &#8221;</p>
<p>And now, it even got better. After a year and a half of coding, CakePHP 2.0 is released.</p>
<p>I will first talk about some cool new features and explain some of them later.</p>
<h4>New features</h4>
<ul>
<li>Dropped PHP 4 support and we have refactored all the code to be strictly compliant with PHP 5.2+.</li>
<li>Use of native features like exceptions, PDO, SPL, json_encode and much more.</li>
<li>Embraced the PSR-0 recommendation for file naming. Now all your classes map to a file with the same name. Less things to remember!</li>
<li>New Error and Exception handlers provide easier to configure, and ease working with errors such as page not found, unauthorized error and lots more.</li>
<li>Improved I18n functions for easier multilingual development.</li>
<li>Support for injecting your own objects to act as CakePHP libraries, such as component, helpers and behaviors, no more excuses for modifying core files.</li>
<li>Console libraries rebuilt from scratch, automatic help generation, parameter checking, and colors!</li>
<li>New Request and Response objects for easier handling of HTTP requests.</li>
<li>Better session handling for easier custom engines. Put your sessions into storage systems like Memcache with less effort.</li>
<li>Completely refactored Auth system. It is now easier to configure and plug in your own implementations for external login services or your permissions system.</li>
<li>Brand new email library with support for multiple transports. With easy to use global configuration, logging, and charset support.</li>
<li>Dropped SimpleUnit in favor of PHPUnit. PHPUnit is the defacto testing framework for PHP with support for more options, better mock objects, and improved console output [16]</li>
<li>Reworked the SecurityComponent to suck less, now you can more easily protect your apps against CSRF and form tampering attacks while having fun.</li>
<li>Improved support for PostgreSql, SQLite and SqlServer, they are now first class citizens along with Mysql datasource.</li>
<li>HTML 5 form inputs support in form helper.</li>
<li>A Sexier default look taking advantage of new CSS 3 features.</li>
<li>A lot faster, almost everything is now lazy-loaded, and even on debug mode you will feel your applications flying.</li>
</ul>
<p>CakePHP 2.0 completely dropped the PHP 4 support and is now supporting PHP 5.2.6 and above. This was expected.</p>
<h4>Models</h4>
<p>The model construction process has been made lighter. Model associations are now lazy loaded, applications with lots of models and associations will see great time reductions in the bootstrap process.</p>
<p>Now models won’t require a database connection in the construction process. The database will be accessed for the first time only when a find operation is issued or information for one of the columns is required.</p>
<h4>Views</h4>
<p>View will now always have the last rendered content (view or layout) accessible through <code>$this-&gt;output</code>. In helpers you can use <code>$this-&gt;_View-&gt;output</code>. Modifying this property will change the content that comes out of the view rendering.</p>
<h4>Helpers</h4>
<p>There are some interesting new features inside powerful CakePHP Helpers:</p>
<ul>
<li><tt>FormHelper</tt> now supports all HTML5 input types and custom input types. Just use the input type you want as the method on the helper. For example <tt>range()</tt> would create an input with type = range.</li>
<li><tt>postLink()</tt> and <tt>postButton()</tt> Creates link/button to access some page using HTTP method POST. With this, in your controller you can avoid some action, like delete, to be accessed by GET method.</li>
<li><tt>select()</tt> with multiple = checkbox, now treats the <tt>'id'</tt> attribute as a prefix for all the generated options.</li>
<li><tt>getCrumbsList()</tt> Creates breadcrumb links wrapped in <tt>&lt;li&gt;</tt> elements in <tt>HTMLHelper</tt></li>
</ul>
<h4>Error handling</h4>
<p>The error handling implementation has dramatically changed in 2.0. Exceptions have been introduced throughout the framework, and error handling has been updated to offer more control and flexibility.</p>
<h4>PHPUnit</h4>
<p>All of the core test cases and supporting infrastructure have been ported to use PHPUnit 3.5. Of course you can continue to use SimpleTest in your application by replacing the related files. </p>
<p>No further support will be given for SimpleTest and it is recommended that you migrate to PHPUnit as well.</p>
<h4>Database Objects</h4>
<p>Cake 2.0 introduces some changes to Database objects that should not greatly affect backwards compatibility. The biggest one is the adoption of PDO for handling database connections. </p>
<p>If you are using a vanilla installation of PHP 5 you will already have installed the needed extensions, but you may need to activate individual extensions for each driver you wish to use.</p>
<h4>Console</h4>
<p>CakePHP features not only a web framework but also a console framework for creating console applications. Console applications are ideal for handling a variety of background tasks such as maintenance, and completing work outside of the request-response cycle. CakePHP console applications allow you to reuse your application classes from the command line.</p>
<p>CakePHP comes with a number of console applications out of the box. Some of these applications are used in concert with other CakePHP features (like ACL or i18n), and others are for general use in getting you working faster.</p>
<p>One of the cool things is that the console app is now colorized to easier spot error messages and other critical information.</p>
<h4>Conclusion</h4>
<p>CakePHP 2.0 is a great step for this framework. I mentioned only the biggest features but there are even more.</p>
<p>I am looking forward to write some tutorials, benchmarks and reviews on CakePHP 2.0 to see how it really works in a real world examples. So, stay tuned.</p>
<p><strong>What do you think of CakePHP framework? What frameworks do you use?</strong></p>
<div class="shr-publisher-1084"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:60px;'><a class='shareaholic-googleplusone' data-shr_size='tall' data-shr_count='true' data-shr_href='http%3A%2F%2Fwww.codeforest.net%2Fcakephp-2-0-released-whats-new' data-shr_title='CakePHP+2.0+released%3A+What%27s+new%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->
<p><a href="http://feedads.g.doubleclick.net/~a/Go0xQ-gQyrBfP58sOkfc2-x0Rn4/0/da"><img src="http://feedads.g.doubleclick.net/~a/Go0xQ-gQyrBfP58sOkfc2-x0Rn4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Go0xQ-gQyrBfP58sOkfc2-x0Rn4/1/da"><img src="http://feedads.g.doubleclick.net/~a/Go0xQ-gQyrBfP58sOkfc2-x0Rn4/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Codeforest?a=-NGFxPW7u68:k4HBEsrGmJU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=-NGFxPW7u68:k4HBEsrGmJU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=-NGFxPW7u68:k4HBEsrGmJU:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Codeforest?a=-NGFxPW7u68:k4HBEsrGmJU:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/Codeforest?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Codeforest/~4/-NGFxPW7u68" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeforest.net/cakephp-2-0-released-whats-new/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.codeforest.net/cakephp-2-0-released-whats-new</feedburner:origLink></item>
	</channel>
</rss>

