A web developer's blog. PHP, MySQL, CakePHP, Zend Framework, Wordpress, Code Igniter, Django, Python, CSS, Javascript, jQuery, Knockout.js, and other web development topics.

Django and jQuery AJAX

This is probably my first post for Django. I have only been using it for a few weeks and I am already falling in love with it.

Here is how to do an AJAX “save” using jQuery and Django.

My Javascript would look something like this:

$(document).ready(function() {
    $("#save_button").click(function(){
        if(save_data()) {
            alert('Saved!');
        } else {
            alert('Failed!');
        }
    });
    function save_data() {
        $.post("/business/add/", { 
            csrfmiddlewaretoken: $("input[name='id_csrfmiddlewaretoken").val(),
            name: $("#id_name").val(),
            website: $("#id_website").val()
        },
        function(data) {
                /* 
                UPDATE: You do not need this line if you have "json" as the 3rd parameter for $.post()
                data = json_parse(data); 
                //You must get this file: http://www.JSON.org/json_parse.js
                */  
                if(data.status=="success") {
                    return true;
                } else {
                    console.log("status: "+data.status)
                    console.log("error: "+data.error)
                    console.log("POST DATA: "+data.data)
                    $.each(data.data, function(i, n){
                        console.log(">"+i+": "+n);
                    });
                    return false;
                }
        },
        "json"
        );
    }
});

And my views.py is like this:

@login_required
@transaction.commit_manually
def business_add(request):
    success = False
    error = None
    if request.method == 'POST':
        business_form       = BusinessForm(request.POST)
        if (business_form.is_valid()):
            business_name   = business_form.cleaned_data['name']
            business_website  = business_form.cleaned_data['website']
 
            try:
                business = Business(name=business_name,website=business_website)
                business.save()
            except IntegrityError, e:
                transaction.rollback()
                success = False
                error = e
            else:
                transaction.commit()
                success = True
    else:
        business_form   = BusinessForm()
 
    data = {
        "business_form": business_form,
        "success": success,
        "error": error
    }
 
    if(success):
        if request.is_ajax():
            results = {"status":"success", "message":"Business saved."}
            data = json.dumps(results)
            return HttpResponse(data)
        else:
            return render_to_response("business/business_add.html",
                              data, context_instance=RequestContext(request))
    else:
        if request.is_ajax():
            data = json.dumps({"status":"failed", "error":error, "data":request.POST})
            return HttpResponse(data)
        else:
            return render_to_response("business/business_add.html",
                              data, context_instance=RequestContext(request))

And last but not the least, my template file:

More HTML here...
<div id="add_business_container" title="Add a business">
    <form id="add_business_form">
        {% csrf_token %}
        <h2>Business info</h2>
        {{ business_form.as_p }}
        <input id="save_button" class="submit" type="submit" value="SAVE"/>
    </form>
</div>
More HTML here...

It is basically just like doing it in any web framework (Zend Framework). But with Django, everything is so easy to understand — you have built-in methods like request.is_ajax()

Posted in General | Tagged , , , | Leave a comment

WordPress: How to enable widgets in your custom theme

This is probably in the WordPress documentation but to enable widgets in your own customized theme, do this:

... rest of PHP and HTML code in your here ...
<div id="sidebar">
    <ul>
        <?php if ( ! dynamic_sidebar( 'primary-widget-area' ) ) : ?>
            <li> id="gray_box">
                <?php get_search_form(); ?>
            </li>
        <?php endif; ?>
    </ul>
</div>

After doing that, go to your WP-Admin page and drag-and-drop widgets. The widgets page is found in Appearance > Widgets .

Posted in General | Leave a comment

My notes in Symfony

Right now, I am working on a pet-project using Symfony.

Symfony is a full-stack framework, a library of cohesive classes written in PHP.

It provides an architecture, components and tools for developers to build complex web applications faster. Choosing symfony allows you to release your applications earlier, host and scale them without problem, and maintain them over time with no surprise.

Symfony is based on experience. It does not reinvent the wheel: it uses most of the best practices of web development and integrates some great third-party libraries.

I have spent a few hours today reading their tutorials and books. The learning curve isn’t that hard if you know Zend Framework or Code Igniter. That is why I made notes in my Wiki — containing the important stuff that will guide me while I am building my application.

It has a robust CLI commands to build and reload your database. Using doctrine needs a little getting used to but the documentation for it is really good. If all goes well, I plan to use Symfony on my succeeding applications.

My notes can be found here: http://wiki.ekini.net/main/Symfony

Posted in General | Tagged | 5 Comments

How to create a sub-domain in Linode

Open the DNS Manager in Linode

  1. Login to Linode Members Area
  2. Go to the DNS Manager tab.
  3. Click the domain name you want to put the sub-domain to.
  4. Scroll to the middle of the page and look for the A/AAAA Records.
  5. Click on Add a new A/AAAA Record
  6. In the Hostname input box, input the sub-domain you want. For example, if you want blog.mydomain.com, enter “blog” in the input box.
  7. For the IP Address, input the IP address of your server.
  8. Click Save.

SSH to your server

  1. SSH to your server.
  2. Once you are logged in as root, create a user called “shop” (same as your sub-domain name).
  3. Go to: /etc/apache2/sites-available OR enter this command:
    cd /etc/apache2/sites-available
  4. If you do an
    ls -la

    you should see something like this:

    -rw-r--r-- 1 root root   385 Apr 24 02:21 default
    -rw-r--r-- 1 root root  7364 Mar  9 21:19 default-ssl
    
  5. Copy the default file into your new sub-domain file. You can issue this command:
    cp default shop.mydomain.com
    
  6. Open up shop.mydomain.com in VI.
  7. Make the new file look like this:
    
         ServerAdmin admin@mydomain.com
         ServerName shop.mydomain.com
         ServerAlias www.mydomain.com
         DocumentRoot /home/shop/public_html/
         ErrorLog /home/shop/logs/error.log
         CustomLog /home/shop/logs/access.log combined
    
    
  8. The next obvious thing to do is to create the directory structure found above. So just do something like this:
    mkdir /home/shop/public_html/
    
  9. Enable the site by issuing this command:
    a2ensite shop.mydomain.com
  10. Then refresh Apache by using this command:
    /etc/init.d/apache2 reload

That’s about it.

FYI: My Linode is using Ubuntu 9.10.

Posted in General | Tagged , , , | 4 Comments

OpenX Ad Server: Beginner’s Guide from Packt Publising

I have not yet considered seriously running ads on my site so I have never heard of OpenX Ad Server before Packt Publishing sent me a free PDF copy of OpenX Ad Server (link here).

What is OpenX Ad Server? OpenX is a platform where you can manage your ads across different websites. It is written in PHP and uses MySQL. The book from Packt Publishing was written by Murat Yilmaz. He is from Russia and obviously has a lot of experience. He is a software developer and runs his own blog and online advertising network.

The book he has written is very detailed. What I mean by details is that a lot of screenshots are provided to guide the reader. Anyone who knows how to create a website will understand the book by scanning the pages. It is a very good guide if you want to get your hands dirty right away with OpenX Ad Server. The author even included screenshots for the installation. I have been doing some tutorials over the past few years, and I tell you, that is a lot of work. The author even goes through an extra step by giving an explaination at the end of each topic.

The book is for beginners, so you won’t find advanced topics. But it is good enough to introduce the new comers to the Ad serving community. It also includes chapters on how to use OpenX with WordPress.

In the end, the book convinced me to look into the “Ad Serving” part of the internet. I have dealt with other systems and web applications but none of this kind. So if you own a lot of websites and want to run advertisements, I suggest that you get a copy of this book. It will probably make your life easier.

You can find out more about this book by clicking HERE. And yes, that is an affiliate link. So if you are going to buy the book, use the link. ;)

Posted in General | 3 Comments

Beginner’s Guide to OpenX Ad Server

I got an email from Packt Publishing to review a book that they will be releasing very soon (March 2010?). The book is about OpenX.

In all honesty, I have not even tried to use OpenX Ad Server yet. Still, I am interested in this book because I also serve ads on this blog; too bad though that the ads on the sides are not enough to pay for the hosting :P

I will have another update for this book once I have read it. I got a free ebook so I will have something to read on my 14-hour flight back home. :D

Here is the book in detail:

  • Learn the essentials of online advertising from the advertiser and publisher points of view
  • Install and utilize OpenX Ad Server effectively to make your business run faster
  • Get to know the usage of all the campaign and banner types
  • Manage ad campaigns and banners on multiple web sites from a centralized platform
  • Display ads according to their importance and alter the under-performing ads easily and swiftly
  • Learn the most effective way to work with web site ad zones
  • Maximize your profits by selling your ad space on your blogs and web sites effectively
  • Take full advantage of GeoTargeting for generating maximum revenue by showing ads according to visitor origin
  • Utilize the channels to show relevant ads based on the content of web sites
  • Integrate Google AdSense and Amazon ads with your web sites using OpenX
  • Convert OpenX Ad Server into a multi-user ad management platform for advertisers, publishers, and ad agencies
  • Track the success of any ad campaign, banner or web site zone using detailed statistics, and reports
Posted in General | Tagged , , , | Leave a comment

WordPress: How to create a breadcrumb without using any plugins

A quick post for WordPress users.

Go to your functions.php file. If it doesn’t exist, then create it.

wp-content/themes/theme_name/functions.php

Then add this inside the functions.php file.

function the_breadcrumb($post_ancestors) {
    if (!is_home()) {
        echo '<a href="';
        echo get_option('home');
        echo '">';
        echo 'Home';
        echo "</a> &gt; ";
        if (is_category() || is_single()) {
            the_category('title_li=');
            if (is_single()) {
                echo " &gt; ";
                the_title();
            }
         } elseif (is_page()) {
            foreach($post_ancestors AS $value) {
                echo "<a href='".get_permalink($value)."'>".get_the_title($value)."</a> &gt; ";
            }
            echo the_title();
        }
    }
}

Then in your wp-content/themes/theme_name/index.php or anywhere in your template files, you can do this:

<?php global $post; ?>
<div class="breadcrumbs"><?php the_breadcrumb(get_post_ancestors($post)); ?></div>

That should display something like this:
Home > A Sample Page > Sub for the Sample Page


* Most of the source code is from here Catswhocode.com. I edited it so that you can get the “parents” for the pages. Thanks to for the kick-start!

Posted in General | Tagged , | Leave a comment

A CSV File and SQL Dump for all the zip codes in Philippines

I spent a few hours yesterday gathering all the zip codes for the Philippines. This is public data, so I am sharing it with everyone. If you use it, I’d appreciate it if you credit me (It is not required but it would be great if you can send some traffic to my site — I have been planning to get a Linode but I can’t afford one yet :P).

Here is a preview of the CSV file:

"id","country","major_area","zip_code","city"
"1","PH","Abra","2800","Bangued"
"2","PH","Abra","2801","Dolores"
"3","PH","Abra","2802","Lagangilang"
"4","PH","Abra","2803","Tayum"
"5","PH","Abra","2804","Peñarrubia"
"6","PH","Abra","2805","Bucay"
"7","PH","Abra","2806","Pidigan"
"8","PH","Abra","2807","Langiden"
"9","PH","Abra","2808","San Quintin"
"10","PH","Abra","2809","San Isidro"
"11","PH","Abra","2810","Manabo"
"12","PH","Abra","2811","Villaviciosa"
"13","PH","Abra","2812","Pilar"
"14","PH","Abra","2813","Luba"
...
...
...
"462","PH","Cebu","6000","Cebu City"
"463","PH","Cebu","6003","Compostela"
"464","PH","Cebu","6001","Consolacion"
"465","PH","Cebu","6017","Cordova"
"466","PH","Cebu","6013","Daanbantayan"
"467","PH","Cebu","6022","Dalaguete"
"468","PH","Cebu","6004","Danao City"
"469","PH","Cebu","6035","Dumanjug"
"470","PH","Cebu","6028","Ginatilan"
"471","PH","Cebu","6015","Lapu-Lapu City (Opon)"
"472","PH","Cebu","6002","Liloan"
"473","PH","Cebu","6016","Mactan Airport"

The MySQL Table is like this:

CREATE TABLE IF NOT EXISTS `zipcodes` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `country` CHAR(2) NOT NULL,
  `major_area` VARCHAR(300) NOT NULL,
  `zip_code` VARCHAR(25) NOT NULL,
  `city` VARCHAR(300) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `major_area` (`major_area`),
  KEY `zip_code` (`zip_code`),
  KEY `city` (`city`)
) ENGINE=MyISAM

Updated: March 13, 2010 (2,270 zip codes)

Download the files below:

Fixed download link: http://blog.ekini.net/wp-content/uploads/2013/01/ph_zipcodes.zip (Updated 2013-01-08)

Disclaimer: The file has not been updated since 2010.

Corrections, suggestions, etc. just leave a comment below.

Enjoy!

Posted in General | Tagged , , | 4 Comments

CSS: Creating a horizontal menu/navigation bar

I always forget how to do this. Every time I forget, it takes me about 10minutes searching for the right one. So I am posting it here for my reference.

My HTML would look something like this:

<div id="navbar">
    <ul>
        <li class="first"><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Projects</a></li>
        <li class="last"><a href="#">Contact</a></li>
    </ul>
</div>

And my CSS would look something like this:

#navbar {
    background-color: #d90000;
}
 
#navbar ul {
    margin: 0; 
    padding: 0;
    float: left;
}
 
#navbar ul li {
    display: inline;
    list-style-type: none;
    padding-right: 20px;
}
 
#navbar ul li a{
    float: left; 
    text-decoration: none;
    color: white;
    padding: 10.5px 11px;
}
 
#navbar ul li a:visited {
    color: white;
}
 
#navbar ul li a:hover, #navbar ul li .current{
    color: #fff;
    background-color:#bf0000;
}
 
#navbar .first  {
    /*You can put stuff here for the first item in the navbar*/
}
 
#navbar .last  {
    /*You can put stuff here for the last item in the navbar*/
}

Comments or suggestions please ;-)

Posted in General | Tagged , , | 3 Comments

Zend Framework: How to use nested transactions with Zend_Db and MySQL

Steve Hollis first blog post about practical nested database transactions using Zend_Db. He writes really well and his blog is very readable. I love reading long text in Serif :D Thanks Steve!

His solution:

The Solution
Disclaimer: This solution is adapted from the extended Pdo_MySql adapter in Varien’s Magento e-commerce product. A similar approach is adopted by Bryce Lohr’s Nested Table Support for Zend_Db proposal. You should read Bill Karwin’s comments about that proposal and understand the limitations of this method before implementing it. That said, I still believe this is a useful and practical way of simulating nested transactions and I have used it a number of times.

A simple solution to the problem is to keep track of the “depth” of the transaction, that is, how many times the beginTransaction() method has been called. That way, we can hold off committing the changes to the database until we are certain that all the save operations have completed successfully.

Since transactions apply to the whole database connection, the most logical place to manage this process is in the DB adapter class. To do this, we extend our adapter class like so:

App_Zend_Db_Adapter_Mysqli extends Zend_Db_Adapter_Mysqli
{
    /**
     * Current Transaction Level
     *
     * @var int
     */
    protected $_transactionLevel = 0;
 
    /**
     * Begin new DB transaction for connection
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */
    public function beginTransaction()
    {
        if ( $this->_transactionLevel === 0 ) {
            parent::beginTransaction();
        }
        $this->_transactionLevel++;
 
	return $this;
    }
 
    /**
     * Commit DB transaction
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */
    public function commit()
    {
        if ( $this->_transactionLevel === 1 ) {
            parent::commit();
        }
        $this->_transactionLevel--;
 
        return $this;
    }
 
    /**
     * Rollback DB transaction
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */
    public function rollback()
    {
        if ( $this->_transactionLevel === 1 ) {
            parent::rollback();
        }
        $this->_transactionLevel--;
 
        return $this;
    }
 
    /**
     * Get adapter transaction level state. Return 0 if all transactions are complete
     *
     * @return int
     */
    public function getTransactionLevel()
    {
        return $this->_transactionLevel;
    }
}

Update your bootstrap to use the extended class et voila – a single START TRANSACTION and COMMIT or ROLLBACK is sent to MySQL, regardless of how many levels of nested pseudo-transactions have been created.

Please Note:

  1. It’s important that each child save() method re-throws the exception so that transaction depth is reduced by successive calls to rollBack(). The end result is that the originally called save() method then performs the actual rollback.
  2. All the tables used in the transaction must use a storage engine that supports transactions. For MySQL, this will most likely mean using InnoDB. To convert a MyISAM or other table type to InnoDB, use “ALTER TABLE table ENGINE = InnoDB”. It could take some time to rebuild the indexes on large tables. There are other considerations about the use of InnoDB – please consult the MySQL manual.
  3. If the tables used don’t support transactions, it’ll just fail silently. Bad times. I highly recommend using Firebug and Zend_Db_Profiler to monitor database queries during development (see http://framework.zend.com/manual/en/zend.db.profiler.html);

And of course, the source can be found here: http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/

Posted in General | Tagged , , , , | 4 Comments