November 09, 2007
It's been hard to blog about cake lately, which is why I have not. Any nifty new tricks I find are obsolete within a few weeks it seems. Cake is really changing rapidly these days, the devs are really working hard. Sorry about the lack of postings.
<br/>
<br/>Hopefully once the coding slows down and the cake code stabilizes I will be able to start posting cool things. Until then I really just don't see the point.
<br/>
<br/>-Rob
0 Comments >>
Tags:
CakePHP
August 14, 2007
Ever get stuck trying to write code and don't know where to look? If you know the right way to find information within the cake community, you can save yourself time. Not only do you not have to wait for someone to help you, usually you find information you were not looking for.
<br/>
<br/>Some folks just hop right on IRC and start asking. Others post to groups, without even searching anywhere. There is a chain of command for these things. Many times people have already written articles on what you are looking for. You just have to know how to find what they have written.
<br/>
<br/>Here are my 5 easy steps to finding out what you want to know about CakePHP.
<br/>
<br/>Step 1. <strong>Search the <a href="http://bakery.cakephp.org/">Bakery</a></strong> - A lot of people have put a lot of time into putting a lot of good code onto the Bakery. It goes through an approval proccess by the cake developers. 80% of the time you'll find a cure for what ails you right here.
<br/>
<br/>Step 2. <strong>Search <a href="http://groups.google.com/group/cake-php">Groups</a></strong> - Chances are if you are having a problem, someone else has had this same problem before you. Most times a solution is also posted
<br/>
<br/>Step 3. <strong>Search the <a href="http://www.google.com/coop/cse?cx=006850030468302103399:mqxv78bdfdo">Blogs</a></strong> - There is a CakePHP custom search maintained by Ritesh that only searches a list of known Blogs. The many smart people within the Cake community discover new features and ways of doing things They post their findings on their blogs. Using this modern technology called the internet, you are able to go read what they have posted.
<br/>
<br/>Step 4. <strong>Ask for help</strong> - Depending on your problem it may be easier to ask on Groups or on IRC. I tend to ask smaller simpler questions on IRC. Things that are a bit more complex and take more to explain, I like to ask on Groups. If you are asking questions on IRC, try not to be a <a href="http://slash7.com/pages">drain</a>. People who help on there are not paid and only help because of their love for CakePHP. Technically it is your problem and it is really on you to solve it, not them.
<br/>
<br/>Step 5. <strong>Take the Cake apart</strong> - Sometimes even asking for help does not work. This is when you really have to start getting your hands dirty. You have to dive into Cake and find out what is going on for yourself. Add print statements, modify the cake core to see how things change. I have a sandbox set separate from my production sites. I use this whenever I need to experiment with Cake. This is far and away the best way to learn about Cake any ways.
<br/>
<br/>There you have it. Happy Baking.
4 Comments >>
Tags:
CakePHP
August 10, 2007
When working with Django there were a few things that I felt could be shortened just by simply extending the request object. I added a few methods onto it so that some tasks were easier.
<br/>
<br/>For example: regarding redirects, I was not a big fan of the "HttpResponseRedirect(reverse(url))" syntax. Redirects are a fairly common thing. I did not enjoy having to import two methods and then write such a long line of code. So what I did was add a redirect method onto request. Now all I do is call "request.redirect(url)" and the redirect is performed. The same goes for rendering. I felt that "render_to_response" was a bit too much. Now I simply call "request.render(file)" to render a template. Its simple and powerful.
<br/>
<br/>These functions make my life a good bit easier. I thought I'd share them with you all. You'll add this in as Middleware. Be aware you must use RequestContext in your app to use this Middleware.
<br/>
<br/><div class="code"><pre><span class="k">import</span> <span class="nn">new</span>
<span class="k">from</span> <span class="nn">django.core.handlers.wsgi</span> <span class="k">import</span> <span class="n">WSGIRequest</span>
<span class="k">from</span> <span class="nn">django.http</span> <span class="k">import</span> <span class="n">HttpResponseRedirect</span>
<span class="k">from</span> <span class="nn">django.core.urlresolvers</span> <span class="k">import</span> <span class="n">reverse</span>
<span class="k">from</span> <span class="nn">django.contrib.sessions.middleware</span> <span class="k">import</span> <span class="n">SessionWrapper</span>
<span class="k">from</span> <span class="nn">django.template</span> <span class="k">import</span> <span class="n">RequestContext</span><span class="p">,</span> <span class="n">add_to_builtins</span>
<span class="k">from</span> <span class="nn">django.shortcuts</span> <span class="k">import</span> <span class="n">render_to_response</span>
<span class="c">##</span>
<span class="c">## Request Handler Middleware</span>
<span class="c">##</span>
<span class="c"># Really I would like to add these, but don't currently have need or know-how</span>
<span class="c"># - is_rss()</span>
<span class="c"># - is_atom()</span>
<span class="c"># - is_mobile()</span>
<span class="c"># - is_wap()</span>
<span class="c"># - is_mobile()</span>
<span class="k">def</span> <span class="nf">_is_ajax</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">META</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'HTTP_X_REQUESTED_WITH'</span><span class="p">)</span> <span class="o">==</span> <span class="s">'XMLHttpRequest'</span>
<span class="k">def</span> <span class="nf">_is_get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'GET'</span>
<span class="k">def</span> <span class="nf">_is_post</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span>
<span class="k">def</span> <span class="nf">_is_put</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'PUT'</span>
<span class="c"># Simple redirect that handles most normal use</span>
<span class="k">def</span> <span class="nf">_redirect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwArgs</span><span class="p">):</span>
<span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="n">reverse</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwArgs</span><span class="p">))</span>
<span class="c"># Ideally I woulnd't want this in here, but RequestContext forced me</span>
<span class="k">def</span> <span class="nf">_render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">()):</span>
<span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span>
<span class="n">context_instance</span><span class="o">=</span><span class="n">RequestContext</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">RequestHandlerMiddleware</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">process_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
<span class="n">request</span><span class="o">.</span><span class="n">is_ajax</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_is_ajax</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">is_get</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_is_get</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">is_post</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_is_post</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">is_put</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_is_put</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">redirect</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_redirect</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">render</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">instancemethod</span><span class="p">(</span><span class="n">_render</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">WSGIRequest</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">None</span>
</pre></div>
<div style='display:none'>
<br/>import new
<br/>from django.core.handlers.wsgi import WSGIRequest
<br/>from django.http import HttpResponseRedirect
<br/>from django.core.urlresolvers import reverse
<br/>from django.contrib.sessions.middleware import SessionWrapper
<br/>from django.template import RequestContext, add_to_builtins
<br/>from django.shortcuts import render_to_response
<br/>
<br/>##
<br/>## Request Handler Middleware
<br/>##
<br/># Really I would like to add these, but don't currently have need or know-how
<br/># - is_rss()
<br/># - is_atom()
<br/># - is_mobile()
<br/># - is_wap()
<br/># - is_mobile()
<br/>
<br/>def _is_ajax(self):
<br/> return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
<br/>
<br/>def _is_get(self):
<br/> return self.method == 'GET'
<br/>
<br/>def _is_post(self):
<br/> return self.method == 'POST'
<br/>
<br/>def _is_put(self):
<br/> return self.method == 'PUT'
<br/>
<br/># Simple redirect that handles most normal use
<br/>def _redirect(self, url, *args, **kwArgs):
<br/> return HttpResponseRedirect(reverse(url, *args, **kwArgs))
<br/>
<br/># Ideally I woulnd't want this in here, but RequestContext forced me
<br/>def _render(self, template, data=()):
<br/> return render_to_response(template, data,
<br/> context_instance=RequestContext(self))
<br/>
<br/>class RequestHandlerMiddleware(object):
<br/>
<br/> def process_request(self, request):
<br/> request.is_ajax = new.instancemethod(_is_ajax, request, WSGIRequest)
<br/> request.is_get = new.instancemethod(_is_get, request, WSGIRequest)
<br/> request.is_post = new.instancemethod(_is_post, request, WSGIRequest)
<br/> request.is_put = new.instancemethod(_is_put, request, WSGIRequest)
<br/> request.redirect = new.instancemethod(_redirect, request, WSGIRequest)
<br/> request.render = new.instancemethod(_render, request, WSGIRequest)
<br/> return None
<br/></div>
0 Comments >>
Tags:
Django,
Python
July 30, 2007
Sometimes I've needed to get a list of fields that a Model's table has. This is a little function that I have in my AppModel just to make getting the list of fields easy.
<br/>
<br/>Dont forget, if you just want to know about one field, you can use the already builtin Model->hasField($name)
<br/>
<br/><div class="code"><pre><span class="cp"><?php</span>
<span class="k">class</span> <span class="nc">AppModel</span> <span class="k">extends</span> <span class="nx">Model</span> <span class="p">{</span>
<span class="c">/**</span>
<span class="c"> * Get a list of all fields of a the table this model is associated with</span>
<span class="c"> * @param bool, prefix all values with the name of this model eg: Model.fieldname </span>
<span class="c"> * @return array non-associative array with field names as values</span>
<span class="c"> * @author rtconner</span>
<span class="c"> */</span>
<span class="k">function</span> <span class="nf">fieldNames</span><span class="p">(</span><span class="nv">$prefix</span><span class="o">=</span><span class="k">false</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">_tableInfo</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-></span><span class="na">loadInfo</span><span class="p">();</span>
<span class="p">}</span>
<span class="nv">$arr</span> <span class="o">=</span> <span class="nf">array_keys</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">_tableInfo</span><span class="o">-></span><span class="na">combine</span><span class="p">(</span><span class="s1">'{n}.name'</span><span class="p">));</span>
<span class="k">if</span><span class="p">(</span><span class="nv">$prefix</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$func</span> <span class="o">=</span> <span class="nf">create_function</span><span class="p">(</span><span class="s1">'&$a, $key, &$obj'</span><span class="p">,</span> <span class="s1">'$a = $obj->escapeField($a);'</span><span class="p">);</span>
<span class="nf">array_walk</span><span class="p">(</span><span class="nv">$arr</span><span class="p">,</span> <span class="nv">$func</span><span class="p">,</span> <span class="nv">$this</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nv">$arr</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cp">?></span><span class="x"></span>
</pre></div>
<div style='display:none'><?php
<br/>class AppModel extends Model {
<br/>
<br/> /**
<br/> * Get a list of all fields of a the table this model is associated with
<br/> * @param bool, prefix all values with the name of this model eg: Model.fieldname
<br/> * @return array non-associative array with field names as values
<br/> * @author rtconner
<br/> */
<br/> function fieldNames($prefix=false) {
<br/> if (empty($this->_tableInfo)) {
<br/> $this->loadInfo();
<br/> }
<br/>
<br/> $arr = array_keys($this->_tableInfo->combine('{n}.name'));
<br/> if($prefix) {
<br/> $func = create_function('&$a, $key, &$obj', '$a = $obj->escapeField($a);');
<br/> array_walk($arr, $func, $this);
<br/> }
<br/> return $arr;
<br/> }
<br/>}
<br/>
<br/>?></div>
0 Comments >>
Tags:
CakePHP
July 28, 2007
One of the most common questions I see on IRC is "How do I stop the view from displaying?".
<br/>
<br/>The controller has a handy little attribute <em>autoRender</em>, setting it to false will stop the view from being displayed.
<br/>
<br/>Also using the <em>render(...)</em> method automatically sets autoRender to false. This is handy if you want to another view aside from the default one for an action.
<br/>
<br/>Some example code:
<br/><div class="code"><pre><span class="cp"><?php</span>
<span class="c">// in a controllers action</span>
<span class="nv">$this</span><span class="o">-></span><span class="na">autoRender</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
<span class="nf">header</span><span class="p">(</span><span class="s1">'Content-type: application/pdf'</span><span class="p">);</span>
<span class="nf">readfile</span><span class="p">(</span><span class="s1">'/path/tp/pdf_file'</span><span class="p">);</span>
<span class="c">// or say you want to render an element as a view. </span>
<span class="c">// maybe you are using ajax</span>
<span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">RequestHandler</span><span class="o">-></span><span class="na">isAjax</span><span class="p">())</span> <span class="p">{</span> <span class="c">// is a cake component</span>
<span class="nv">$this</span><span class="o">-></span><span class="na">viewPath</span> <span class="o">=</span> <span class="s1">'elements'</span><span class="o">.</span><span class="nx">DS</span><span class="o">.</span><span class="s1">'products'</span><span class="p">;</span>
<span class="nv">$this</span><span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="s1">'product_table'</span><span class="p">,</span> <span class="s1">'ajax'</span><span class="p">);</span>
<span class="p">}</span>
<span class="cp">?></span><span class="x"></span>
</pre></div>
<div style='display:none'><?php
<br/>
<br/>// in a controllers action
<br/>$this->autoRender = false;
<br/>header('Content-type: application/pdf');
<br/>readfile('/path/tp/pdf_file');
<br/>
<br/>// or say you want to render an element as a view.
<br/>// maybe you are using ajax
<br/>if($this->RequestHandler->isAjax()) { // is a cake component
<br/> $this->viewPath = 'elements'.DS.'products';
<br/> $this->render('product_table', 'ajax');
<br/>}
<br/>
<br/>?></div>
<br/>
<br/>Some links:
<br/><a href="http://api.cakephp.org/1.2/class_controller.html#90046e6b62c91452a987c9573372c2ac">Controller::render</a> [api.cakephp.org]
<br/><a href="http://api.cakephp.org/1.2/class_request_handler_component.html">RequestHandler</a> [api.cakephp.org]
<br/>
<br/>-rtconner
0 Comments >>
Tags:
CakePHP,
PHP