Laravel routes – Generating a CSV

We’re currently building out an API at Basanty, and I was looking for a way to generate a simple Excel/CSV file.  Using the `artisan routes` command, you can print out a nice table in the console, or even save it by appending `> routes.txt`. The problem is the Symfony table formatter doesn’t translate well to a document.

So I created a simple route that loops through the routes, and saves them to a csv file.  This could quite easily be abstracted to a custom artisan command. Also, after generating the file, you should probably remove it immediately.

/**
 * Generate a CSV of all the routes
 */
Route::get('r', function()
{
    header('Content-Type: application/excel');
    header('Content-Disposition: attachment; filename="routes.csv"');

    $routes = Route::getRoutes();
    $fp = fopen('php://output', 'w');
    fputcsv($fp, ['METHOD', 'URI', 'NAME', 'ACTION']);
    foreach ($routes as $route) {
        fputcsv($fp, [head($route->methods()) , $route->uri(), $route->getName(), $route->getActionName()]);
    }
    fclose($fp);
});

How I use Bower and Grunt with my Laravel projects

I just ran across an excellent article on how to use Grunt with Laravel, and I thought I’d share my process. First things first… install node, npm, bower, grunt, and all that. Google it if this is new to you.

With Laravel installed, I actually use the Laravel-Assetic package for all my concatenation and minimization. That way, cacheing is taken care of automatically. Here’s my composer,json file with all the needed filters

"require": {
		"laravel/framework": "4.0.*",
		"slushie/laravel-assetic": "dev-master",
		"leafo/lessphp": "dev-master",
		"lmammino/jsmin4assetic": "1.0.*",
		"natxet/CssMin": "dev-master"
},

Next, I use Bower for all my asset dependencies. To specify where the files are saved, I needed to add a .bowerrc file in my app’s root, and added this

{
	"directory": "assets/bower"
}

I add the files to use in my bower.json file

{
  "name": "Matula",
  "version": "0.0.0",
  "homepage": "https://terrymatula.com",
  "authors": [
    "Matula <terrymatula@gmail.com>"
  ],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "underscore": "~1.4.4",
    "Eventable": "~1.0.1",
    "jquery": "~2.0.3",
    "bootstrap": "jasny/bootstrap#~3.0.1-p7",
    "sir-trevor-js": "~0.3.0",
    "jquery-ui": "~1.10.3",
    "angular": "~1.2.2"
  },
  "resolutions": {
    "jquery": "~2.0.3"
  }
}

In the command line, run `bower install` and all those files are added to the ‘assets/bower’ directory. Then (after following the Laravel-Assetic install instructions) we need to add the files to use in the Laravel-Assetic config file. Here’s an example of my config:

<?php
/**
 * Configure laravel-assetic options in this file.
 *
 * @package slushie/laravel-assetic
 */

return array(
  'groups' => array(
    // Javascripts
    'script' => array(
      'filters' => array(
        'js_min'
      ),
      'assets' => array(
        'underscore',
        'eventable',
        'jquery',
        'jqueryui',
        'redactorjs',
        'bootstrapjs',
        'sirtrevorjs',
        'sirtrevorcustomjs',
        'customjs'
      ),
      'output' => 'js/matula.js'
    ),

    // CSS
    'style' => array(
      'filters' => array(
        'css_min'
      ),
      'assets' => array(
        'bootstrapcss',
        'sirtrevoricons',
        'sirtrevorcss',
        'redactorcss',
        'customcss'
      ),
      'output' => 'css/matula.css'
    ),

    // LESS files
    'less' => array(
      // Convert LESS to css
      'filters' => array(
        'less',
        'css_min'
      ),
      'assets' => array(
        public_path('less/style.less'),
      ),
      'output' => 'css/less.css'
    ),
  ),

  'filters' => array(
    // Filters
    'js_min'  => 'Assetic\Filter\JsMinFilter',
    'css_min' => 'Assetic\Filter\CssMinFilter',
    'less'    => 'Assetic\Filter\LessphpFilter'
  ),

  // List of Assets to Use
  'assets' => array(
    // Add name to assets
    'jquery'            => public_path('bower/jquery/jquery.js'),
    'angular'           => public_path('bower/angular/angular.js'),
    'bootstrapjs'       => public_path('bower/bootstrap/dist/js/bootstrap.js'),
    'eventable'         => public_path('bower/Eventable/eventable.js'),
    'jqueryui'          => public_path('bower/jquery-ui/ui/jquery-ui.js'),
    'jqueryfileapi'     => public_path('bower/jquery.fileapi/jquery.fileapi.js'),
    'sirtrevorjs'       => public_path('bower/sir-trevor-js/sir-trevor.js'),
    'underscore'        => public_path('bower/underscore/underscore.js'),
    'sirtrevorcustomjs' => public_path('js/custom/sir-trevor-custom-blocks.js'),
    'redactorjs'        => public_path('js/custom/redactor.js'),
    'customjs'          => public_path('js/custom/bs.js'),

    'bootstrapcss'      => public_path('bower/bootstrap/dist/css/bootstrap.css'),
    'sirtrevoricons'    => public_path('bower/sir-trevor-js/sir-trevor-icons.css'),
    'sirtrevorcss'      => public_path('bower/sir-trevor-js/sir-trevor.css'),
    'redactorcss'       => public_path('css/custom/redactor.css'),
    'customcss'         => public_path('css/custom/custom.css'),
    'customless'        => public_path('less/*')
  )
);

Some explanation: Starting at the bottom, we have our ‘assets’ array, where we assign a name to each asset and point it to the file we want to use. Then, we have our ‘filters’ array where we give a name to each filter we’re using. The composer file loaded in the filters we’re using. Before that, we create our ‘groups’ array. Each group is basically the filters we want to use, the files we want to filter, and then the output file to create. The order of the files is important, since this will affect any dependent files (eg, jquery needs to be before jquery-ui).

Now, we can run `php artisan asset:warm’ and all our files will be created. The one issue I had during development was that I was doing lots of quick updates to the css/js, and it would take time for the asset cache to clear. So I had to ‘warm’ them often. This was a time waste, so I’m using grunt to take care of that for me, ad live-reload it as well.

The only 2 grunt packages we need are ‘grunt-contrib-watch’ and ‘grunt-exec’. This is how my Gruntfile.js file looks:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    exec: {
      warmscript: {
        cmd: 'php artisan asset:warm script'
      },
      warmstyle: {
        cmd: 'php artisan asset:warm style'
      },
      warmless: {
        cmd: 'php artisan asset:warm less'
      }
    },
    watch: {
      options: {
        livereload: true
      },
      less: {
        files: ['assets/less/*.less'],
        tasks: ['exec:warmless']
      },
      css: {
        files: ['assets/css/custom/*.css'],
        tasks: ['exec:warmstyle']
      },
      js: {
        files: ['assets/js/custom/*.js'],
        tasks: ['exec:warmscript']
      },
      html: {
        files: ['app/views/*.php', 'app/views/**/*.php']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-exec');

  grunt.registerTask('default', ['exec', 'watch']);

};

I open a dedicated command line tab, run `grunt` and it will warm everything on start. Then, anytime I make a change to one of the files, it’s automatically warmed and the page is reloaded. The ‘html’ part will reload it when my views are changed.

One word of warning… the way I have it set up, it loads every js/css into every view. While it’s handy to only have 2 (or 3 in my case) minimized files that need to be loaded, we’ll only need Redactor on the pages with forms.  It might be best to create our groups dynamically, and only use the assets we need for each view.

Laravel Application Development Cookbook

Hey look! I wrote a book about Laravel: http://bit.ly/laravelcookbook

Some of the fun and exciting things you’ll learn…

  • Setting Up and Installing Laravel
  • Using Forms and Gathering Input
  • Authenticating Your Application
  • Storing Data
  • Using Controllers and Routes for URLs and APIs
  • Displaying Your Views
  • Creating and Using Composer Packages
  • Using Ajax and jQuery
  • Using Security and Sessions Effectively
  • Testing and Debugging Your App
  • Deploying and Integrating Third Party Libraries

 

Some Packagist API “hacks”

In a previous post, I was trying to parse out the most popular Composer packages, and wasn’t able to find a way to get the information through any kind of API. I ended up doing a simple scrape, but then I started searching through the Packagist code ,  and I found some interesting gems.

First, is a list of ALL the packages: https://packagist.org/packages/list.json . It produces a simple list of all 7002 (at the moment) packages in json.

{
    "packageNames": [
        "illuminate/auth",
        "illuminate/cache",
        "illuminate/config",
        "illuminate/console",
        "illuminate/container",
        "illuminate/cookie",
        "illuminate/database",
        "illuminate/encryption",
        "illuminate/events",
        "illuminate/exception",
        "illuminate/filesystem",
        "illuminate/foundation",
        "illuminate/hashing",
        "illuminate/http",
        "illuminate/log",
        "illuminate/mail",
        "illuminate/pagination",
        "illuminate/queue",
        "illuminate/redis",
        "illuminate/routing",
        "illuminate/session",
        "illuminate/socialite",
        "illuminate/support",
        "illuminate/translation",
        "illuminate/validation",
        "illuminate/view",
        "illuminate/workbench",
    ]
}


With that list, you could easily get the specifics about each package at https://packagist.org/p/{package-name}.json. For example: https://packagist.org/p/illuminate/database.json . But what about searching? The Packagist website UI isn’t the most intuitive, but there a couple of queries that make the search fairly powerful. First, is just a regular search like : https://packagist.org/search.json?q=laravel This is fine. It mirrors the site’s search and it’s nice that it includes the ‘downloads’ and ‘favers’

{
    "results": [
        {
            "name": "laravel/framework",
            "description": "The Laravel Framework.",
            "url": "https://packagist.org/packages/laravel/framework",
            "downloads": 6493,
            "favers": 4
        },
        {
            "name": "laravel/curl",
            "description": "Laravel Curl Helper Library inspired by Phil",
            "url": "https://packagist.org/packages/laravel/curl",
            "downloads": 87,
            "favers": 0
        },
    ],
    "total": 77,
    "next": "https://packagist.org/search.json?q=laravel&page=2"
}

But we can get even fancier and search the tags as well: https://packagist.org/search.json?tags=laravel

{
    "results": [
        {
            "name": "laravel/framework",
            "description": "The Laravel Framework.",
            "url": "https://packagist.org/packages/laravel/framework",
            "downloads": 6493,
            "favers": 4
        },
        {
            "name": "composer/installers",
            "description": "A multi-framework Composer library installer",
            "url": "https://packagist.org/packages/composer/installers",
            "downloads": 5562,
            "favers": 2
        },
        {
            "name": "cartalyst/sentry",
            "description": "PHP 5.3+ fully-featured authentication & authorization system",
            "url": "https://packagist.org/packages/cartalyst/sentry",
            "downloads": 731,
            "favers": 2
        },
        {
            "name": "illuminate/database",
            "description": "An elegant database abstraction library.",
            "url": "https://packagist.org/packages/illuminate/database",
            "downloads": 10787,
            "favers": 1
        }
    ],
    "total": 60,
    "next": "https://packagist.org/search.json?page=2&tags%5B0%5D=laravel"
}


Let’s say we only want packages that are tagged with “laravel” AND “database”. That’s possible, too: https://packagist.org/search.json?tags[]=laravel&tags[]=database

{
    "results": [
        {
            "name": "illuminate/database",
            "description": "An elegant database abstraction library.",
            "url": "https://packagist.org/packages/illuminate/database",
            "downloads": 10787,
            "favers": 1
        },
        {
            "name": "laravelbook/ardent",
            "description": "Self-validating smart models for Laravel 4's Eloquent O/RM",
            "url": "https://packagist.org/packages/laravelbook/ardent",
            "downloads": 69,
            "favers": 1
        },
        {
            "name": "jtgrimes/laravelodbc",
            "description": "Adds an ODBC driver to Laravel4",
            "url": "https://packagist.org/packages/jtgrimes/laravelodbc",
            "downloads": 5,
            "favers": 0
        },
        {
            "name": "dhorrigan/capsule",
            "description": "A simple wrapper class for the Laravel Database package.  This is only to be used outside of a Laravel application.",
            "url": "https://packagist.org/packages/dhorrigan/capsule",
            "downloads": 79,
            "favers": 0
        },
        {
            "name": "iyoworks/elegant",
            "description": "",
            "url": "https://packagist.org/packages/iyoworks/elegant",
            "downloads": 12,
            "favers": 0
        }
    ],
    "total": 5
}


You can also search for a “type”, like https://packagist.org/search.json?type=symfony-module or even mix the queries like so: https://packagist.org/search.json/?q=laravel&tags[]=orm&tags[]=database

Other interesting ways to view the data can be found at: https://packagist.org/packages.json … so if you wanted to view packages only released in January of 2013, you can use: https://packagist.org/p/packages-2013-01.json

My favorite “hack”, is searching with an empty value like so: https://packagist.org/search.json?page=1&q= … which returns all the records (15 on a page), ordered by popularity.

One of these days, if someone else doesn’t beat me to it, I’ll make a review/upvote/downvote site so that the best packages can be found a bit easier. Also, there are some excellent packages that have almost no documentation… so having comments that explain some use-cases would be nice.

Autoloading Organized Routes in Laravel

This is an excellent tip from Jesse O’Brien about breaking up your Laravel routes file.  I’ve actually done something similar for a while now, and kind of forgot that Laravel doesn’t come preconfigured this way.

First, in the application directory, I create another directory called “routes”.

In that directory, I have a “filters.php” and “events.php” and some other files to hold my GET and POST routes.

Then in the start.php, I drop on this bit of code:

foreach (scandir(path('app') . 'routes') as $filename) {
	$path = path('app') . 'routes/' . $filename;
	if (is_file($path)) {
		require($path);
	}
}

This way, you can add as many routes as you want, and they’ll all load.

I’ve toyed with the idea of scanning for directories in the routes folder, and including those as well… but if you’re at that point, you should probably just use controllers.

Laravel and Redactor

I’ve been working on this book thing, and the bit I wrote about using Laravel with Redactor is quite nice.. if I do say so myself.  Here’s a bit…

First, WYSIWYG text editor javascript libraries are pretty hit and miss. But Redactor is brilliant. It looks good, it’s coded well, and it just works. Using it with Laravel is a PHP dev’s dream.  So to start, we need to make sure we have a copy of Redactor and have Laravel all set up.

In our routes.php file, we create a route to hold our form with the Redactor field

Route::get('redactor', function()
{
    return View::make('redactor');
});

 

Then create a view named redactor.php.  I’m using straight PHP for the form, but Blade would work just as well.

<!DOCTYPE html>
<html>
   <head>     
         <title>Laravel and Redactor</title>
         <meta charset="utf-8">
         <link rel="stylesheet" href="css/redactor.css" />
         <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
         <script src="js/redactor/redactor.min.js"></script>
   </head>
   <body>
         <?php echo Form::open() ?>
         <?php echo Form::label('mytext', 'My Text') ?>
         <br>
         <?php echo Form::textarea('mytext', '', array('id' => 'mytext')) ?>
         <br>
         <?php echo Form::submit('Send it!') ?>
         <?php echo Form::close() ?>
         <script type="text/javascript">
               $(function() {
                     $('#mytext').redactor({
                           imageUpload: 'redactorupload'
                     });
               });
         </script>
   </body>
</html>

So we created a textarea with the name ‘mytext’, and make the id of that field the same as the name.  So to target it, and add Redactor to it, just use

$('#mytext').redactor();

In the imageUpload parameter, we pass the URL path where we post the image. In this case, it’s routing to ‘redactorupload’.  So let’s create that route.

Route::post('redactorupload', function()
{
   $rules = array(
         'file' => 'image|max:10000'
   );

   $validation = Validator::make(Input::all(), $rules);
   $file = Input::file('file');
   if ($validation->fails())
    {
        return FALSE;
    }
    else
    {
         if (Input::upload('file', 'public/images', $file['name']))
         {
            return Response::json(array('filelink' => 'images/' . $file['name']));
         }
         return FALSE;
    }
});

The image will automatically POST here. So we want to make sure it’s actually an image and is less than 10 megabytes… so we run those validations. If everything validates, we move it to its permanent location, and send out a json response.  Redactor expects the json key to be ‘filelink’ and the value to be the path to the image.  If everything worked, when you add the image, it will display in your Redactor textarea.

We can check what the code output looks like by creating a route to accept the Redactor data.

Route::post('redactor', function()
{
    return dd(Input::all());
});

File uploads through redactor are done pretty much the same way, except with the fileUpload parameter… and the json output should also include a ‘filename’ key.

Postmark – Laravel bundle

I did a Laravel bundle for the Postmark API.  It’s really just a simple wrapper for the API, and I needed it for a non-Laravel project I worked on, and noticed there wasn’t a bundle already. Probably the one update that would be most useful is getting attachments working.  Right now, you have to parse the content and mime-type before attaching… and I should probably update it to just accept the file and do all the parsing in the method. Maybe one day.

Things I’ve Learned Using Codeigniter – PHP

1) You don’t need an ORM

I had experimented with Datamapper, and it was great. But there was complex join statement I needed that DM didn’t support… so I had to just write out the SQL like normal.  I then realized it’s just as easy to use CI’s Active Record or regular query command and create your own methods.  Plus, it keeps things pretty speedy.

2) You DO need a base Model

I’ve only just recently started using Jamie Rumbelow’s MY_Model and it’s changed everything. Previously, when I wanting to get a single record from a table, I was writing $this->db->from('table')->where('id',$id)->limit(1)->get()->row(); for every single table. Now, that’s already included for every Model I make.

3) It’s helpful to look at the core code

For example, I was curious how the Active Record was implemented, so I opened up DB_active_rec.php. I know some people prefer to use “->get()” by adding in the table name and limit as parameters, and I wondering if there was difference in how it’s handled.  Interestingly, it runs the exact same “from()” method, just as if you had “->from()” in the query.

And while this is a micro-optimization, if you want to return a single result and you’re sure it’s the first result… use “->limit(1)”.  The “row()” method will work with multiple rows returned, so there’s logic built in to just return the first row.  Adding “->limit(1)” will help skip all that.

4) The url helper really needs to be auto-loaded by default

In my autoload file, I always load the database and sessions libraries and the url helper. I can’t remember a project where those didn’t get used.  I’ll occasionally autoload the form helper as well, but that’s a project-by-project call.

But the url helper… I honestly can’t see how anyone would ever NOT use that in every project.  “site_url()” and “redirect()” just seem like no-brainers.

5) Object-Oriented programming and MVC

Prior to learning Codeigniter, I was experience in Drupal and WordPress, and a bit of Joomla, but working with them isn’t strict OO.  The custom stuff I programmed was really procedural or functional, based on the fact that I learned programming using PHP 4 and classic ASP/ vbscript.  While I read about and tried using Classes and methods, I just didn’t get it. With CI, I had the ‘flipped switch’ moment, where Objects and Classes made total sense.

Now, I’m onto learning as much as I can about OO in PHP 5.3, including namespaces and inheritance… which aren’t yet built into CI

Simple Facebook / Codeigniter Authorization

On a Codeigniter project I’m working on, I wanted to have Twitter and Facebook logins available. Luckily, right around the time I was starting the project, Elliot Haughin released libraries for both Twitter and Facebook. The Twitter library worked almost instantly and is quite brilliant. However, the Facebook library was causing me some problem.

Looking through the Facebook Developer pages, it seemed like a fairly straight-forward process to get a User’s Facebook auth tokens… and with CI2 having querystring support now, I thought I could do everything in a simple Facebook controller.  Here’s what I got:

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Name:  Simple Facebook Codeigniter Login
 *
 * Author: Terry Matula
 *         terrymatula@gmail.com
 *         @terrymatula

 * Created:  03.31.2011
 *
 * Description:  An easy way to use Facebook to login
 *
 * Requirements: PHP5 or above
 *
 */
class Facebook extends CI_Controller {

    public $appid;
    public $apisecret;

    public function __construct()
    {
        parent::__construct();
        // replace these with Application ID and Application Secret.
        $this->appid = '12345';
        $this->apisecret = '123abc123';
    }

    /**
     * if you have a Facebook login button on your site, link it here
     */
    public function index()
    {
        // set the page you want Facebook to send the user back to
        $callback = site_url('facebook/confirm');
        // create the FB auth url to redirect the user to. 'scope' is
        // a comma sep list of the permissions you want. then direct them to it
        $url = "https://graph.facebook.com/oauth/authorize?client_id={$this->appid}&redirect_uri={$callback}&scope=email,publish_stream";
        redirect($url);
    }

    /**
     * Get tokens from FB then exchanges them for the User login tokens
     */
    public function confirm()
    {
        // get the code from the querystring
        $redirect = site_url('facebook/confirm');
        $code = $this->input->get('code');
        if ($code)
        {
            // now to get the auth token. '__getpage' is just a CURL method
            $gettoken = "https://graph.facebook.com/oauth/access_token?client_id={$this->appid}&redirect_uri={$redirect}&client_secret={$this->apisecret}&code={$code}";
            $return = $this->__getpage($gettoken);
            // if CURL didn't return a valid 200 http code, die
            if (!$return)
                die('Error getting token');
            // put the token into the $access_token variable
            parse_str($return);
            // now you can save the token to a database, and use it to access the user's graph
            // for example, this will return all their basic info.  check the FB Dev docs for more.
            $infourl = "https://graph.facebook.com/me?access_token=$access_token";
            $return = $this->__getpage($infourl);
            if (!$return)
                die('Error getting info');
            $info = json_decode($return);
            print_r($info);
        }
    }

    /**
     * CURL method to interface with FB API
     * @param string $url
     * @return json
     */
    private function __getpage($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $return = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        // check if it returns 200, or else return false
        if ($http_code === 200)
        {
            curl_close($ch);
            return $return;
        }
        else
        {
            // store the error. I may want to return this instead of FALSE later
            $error = curl_error($ch);
            curl_close($ch);
            return FALSE;
        }
    }

}


That’s about it. You could put it all in “index()”, but I wanted to separate it a little.

update: Looking at the bit.ly api, it’s actually very similar. i’ll eventually try to make it more generic.

Motivations To Code

A few months back, I had an idea for a recommendation site for politicians/political candidates. The thought is, a user browses through a list of candidates that they can vote for, then clicks on an icon to “endorse” them.  I also wanted a way to not recommend a candidate by having a “reject” button. Then I would allow the candidates to include a script on their site that listed all their endorsements, ideally replacing/adding to the Endorsements page that many political candidates have on their site.

Basically, it’s a Facebook “Like” button, but with an option to “Not Like”… and all the candidates would be in one place.

The problem is, it’s just me doing all the coding and design, and being new to Austin, I don’t know anyone else that might be interested in helping out.  Add to that, the hours I spend at my  job, and having an 18-month old baby, and  going through a seemingly never-ending move… and it’s difficult to find the time, or the motivation to work on the project.

When I do find time, there will be brief spans of productivity and clarity.  Then eventually, I’ll hit a wall and a particular programming problem will stump me.  Instead of pushing through it with OCD abandon, I’d rather just stop and play with the baby.  This has been a circular pattern that has gone on for the past 9 months or so.

Tonight, I watched The Social Network movie, and the scene about the creation of FaceSmash made me long for the days when I would have an idea and stay up all night working on it.  Like when I bought a copy of “Creating Cool HTML 4 Web Pages” and spend all day and night reading every word, and creating “cool” web pages.  In those days, had I known PHP (or at least PERL), I would’ve had my endorsement site done in a week.  Of course, I didn’t have a full-time  job, a wife, or a baby at the time.

Then, I read the latest Email from Jason Calacanis and I’m not sure whether to be defiant or justified.  He basically argues that entrepreneurship is for single, young people… at least if it’s your first foray into creating something.  In the past, he’s also argued (essentially) that if you’re not working 18 hours a day, you’re not working hard enough. But I think 37 Signals shows that that isn’t always the case.

And no, I  don’t think my little idea would qualify me as an entrepreneur, but I think it is something that would have some appeal. I had also considered rolling it into another idea I’ve been working: creating nice-looking, dynamic web sites for candidates in local elections. In fact, I’ve got TONS of ideas… ideas constantly running through my head. Many times, I’ll spend a week or two on them, get them to a functional place, and stop.  And up until a year or so ago, I would immediately register a domain name to go along with it.

For example, TheMoviePunch.com was going to be a video blog where I reviewed movies, but only having viewed their trailer. Or ReindeerBlog.com was going to be one of Santa’s reindeer anonymously posting about the dark-side of working at the North Pole… and more recently, I was thinking about registering ReindeerLeaks, and then “leaking” documents about Santa, the elves, etc. And why do I own MrShoop.com?

So anyway, I’m now looking for the motivation to get back to coding, or more specifically finishing some coding.  My biggest motivation right now is just about learning new technologies and keeping my skills sharp.  But that doesn’t require a finished product… just a continual process. My hope is that I can blog more, and get these ideas I have out in the wild. At least that way they’re  not just filling up my brain space.