Practical DWR 2 Projects> Foreword The funny thing about getting heavily involved in an open source project is the roller coaster ride you embark on. There's. Practical CodeIgniter 3 .. Chapter 2: Environmental Protection Codes worked on and the environments those projects were created in. ruthenpress.info - Ebook download as PDF File .pdf), Text File .txt) or read things. it becomes self-defeating at times. it is intended to be a practical “ field . I believe that adopting these methods will help keep your projects organized and Easy as 1 2 3 CodeIgniter is based loosely around the MVC pattern.
|Language:||English, Spanish, Dutch|
|Distribution:||Free* [*Register to download]|
Today's Web is demanding more with less. CodeIgniter, an up-and-coming PHP-based Web application development framework that leaves a little footprint, . CodeIgniter is an open source rapid development web appli Download PDF. 9 downloads 9 Views Title: Practical CodeIgniter 2 Projects: Building Realâ. Who Should Read This Book Practical CakePHP is a book mainly for If there are two chapters in the book that need to be read in sequence, they are Chapters 1 and 2. . such as Ruby on Rails, symfony, Zend Framework, and CodeIgniter.
You can always customize the directories it looks in to fit your situation. We need to add a new section to the file. Controlling Traffic 37 The first thing to do is decide where to put the new controllers. If you are going to use namespaces that match up to the directories. Instead of using an array of directories.
This file currently just holds some basic information about CodeIgniter itself. To do this. This will fix the problem most of the time. Controller Tweaks In this section of the book. I use them all of the time. Dump Autoload When working with Composer. Not everything will be something that you will want in your projects. The first step to debug is always to jump to the command line in your project root. It checks if the session has been initialized and.
Controlling Traffic 39 any form submittals that would redirect to other methods on success or failure. While this part is not technically necessary due to the mentioned changes in the session library.
Along with this. The type is used for CSS classes to affect the displayed status message. I prefer not to hit that additional page load and. It also stores a copy in a class var. This allows you to have multiple display types for it by simply calling different views.
Controlling Traffic 40 13 if! You can pass them to the views directly. These methods provide a very handy way of working with status messages. In my applications. Whether you want to run this in production or not is very much an application-specific issue that you should discuss with your team.
Instead of going through all of that work. For those reasons. As a default. Set it and forget it. This way. Controlling Traffic 41 your current code every time you want to use it. I find it handy to control this from a single config setting.
I would recommend turning this feature OFF in production environments to keep things safe. This is a tiny convenience method. This is especially helpful when you are working in teams as it keeps everyone in sync. This provides a one-stop place to change the cache drivers to use. A good solution is to ensure that the cache driver is always up and running. Add the following properties at the top of the class: Config settings to the rescue. Cache By Default In order to really optimize your applications.
In that case. If not. If performance starts to become an issue. While a bigger API might require you to to output data in multiple formats. The profiler is turned off. Most of the time. HTTP headers-based redirects. This could be for a very long-running data import script. In order to break out. This method does just that for you.
CodeIgniter will use output buffering to collect all of the output and send it to the browser all at once. The second parameter can typically be left to its default.
Realtime Responses By default. This technique could also be used to create custom methods to work with values from PUT. You could easily store that view under a sub-directory for each part of the application. Just add the name of the sub-directory to the name of the view. The first parameter is the name of the view to display. View Data You can make data available to use within the view by passing it in as the second parameter. In the view. No problem. This makes it simple to pull the information together in the controller.
There are times. Method 1: In Method The first method I saw recommended years ago.. With each method I go over. I will go over them here. Constructing Pages What you want to display to the user. There will be common elements.. Showing Your Work 50 Method 2: This is a simplified version of what I tend to use now.
This allows several other views to be grouped in one file.. Then a second footer view might include the page footer. What To Expect The first task is to decide what features this system needs to provide for us.
For many small sites. It will focus on a few conventions to keep your files organized and easy to find for everyone in the team. You should view this as a starting point. This reduces a lot of our calls by combining the different elements into collections of templated content which surrounds our page content..
We should support multiple layouts. This allows you to easily create page structures specific to certain areas of your site. Especially if you design as much admin interaction into the front-end of the site as possible. If you have access to PHP version 5.
Here are some examples. This could be very easily expanded to work with multiple themes with very little effort. No special tool needs to be created for this. Or to simply allow for common configurations. They will be passed along with the other data to the view. This also allows variables to be added from other methods in your controller very simply. This does require a few properties to be added to the class to keep track of assets and allow us to customize which layout or view file should be used.
This is the method you would call from any of your controller functions to display the page. First is that it allows you to make modifications to variables that are accessed later in the layout file.
For Bootstrap or Foundation. Once we collect this view. We collect it here. This provides the controller with a full set of values to send to the view to display to the user. There are a few small utility methods that we will build out to make it more flexible before leaving you to tweak it to your needs. Showing Your Work 54 Next. We will add these next two methods to make that process a little more elegant than simply setting the properties.
Parsing View Output Now that you can display the content. I am sure there are many other areas that could be expanded. A few things you might want to consider adding to it are listed below. We will look at integrating this in the next section.
If you do that. Many companies prefer to use some form of template tags to keep their designers away from the PHP. There it is! A simple. The first parameter is the name of the view file to load. When you have opening and closing tags. The third parameter. Installing Twig For this tutorial. The problem becomes how to integrate it easily and elegantly into your workflow. Integrating Twig We will handle the integration with a new library. They will then turn to existing template engines like Smarty or Twig.
To do that. We will discuss what it does afterwards. Integrating the Twig Template Engine For some companies. If it works. You could create a config file to store these settings outside of the class. The output is passed on to the Output library. This makes the class act as if it is the instance so you can call any Twig command directly on this library. Using the Twig Library Now that we have created the library.
Most of these are at the default values. Showing Your Work In this example, this is handled in the constructor, though creating a new ThemedController or something similar might be a better solution, since you could customize your workflow around Twig. If you want to, you can use simple. This section goes over how you can easily create your own widget implementation for use in your own projects.
Overview What we want to accomplish with this library is to create a system that allows you to call a method in any library or fully namespaced class that can be found by your autoloader s. If you are using Composer, this is expanded to even more classes.
We want to be able to pass in a number of named parameters so that we can customize the output, for example, if we want to change the number of blog posts returned to 5 instead of the default of This allows us to freely pass in the parameters in any order we want, keeping things simple in the views. Finally, we want the system to allow the widget to be cached so that we can really crank up the performance of our application by not having to use any potentially expensive database calls to display the information.
Best of all, we can do all of this with a single method in its own library file. The Solution Here is the entire class. I will discuss the code below.
On line We loop through each of these. The code to load the class and check whether the method exists is found in lines An array of named parameters is passed to your library method. For this class. We collect this into an array. This requires that the cache library has already been loaded. This allows you to pass a list of parameters. Continuing the example of the recent blog posts above. Once handled by the script. If we find it. As an example. If you are using Composer. We then try to read the info from the cache.
Starting at line The Library The first thing you need is a library to call. All of the output is then returned to the view. The only restriction our library methods have is that they accept an array of parameters.
We will step through a sample implementation of the blog posts example from above just to make sure that everything is clear. PHP will tell us where we messed up so we can fix it. Using The System To use the system in a project. Inside that file. This method will take only one parameter: The first is to load it in the controller methods that need it.
AJAX calls. Display the Widget Now that the library has been created. This can get a bit tedious and error prone. I definitely discourage this unless every call on your site will be displaying a page. This might be tempting. Loading the Widget Library The Widgets class must be available whenever you are displaying your views so we need to ensure that it is loaded.
You have a few ways to load the Widgets class. Drivers If the user guide provides a list of which drivers CodeIgniter currently supports.
It still makes sense to try. This often works. In this file you can define one or more connections. The user guide covers them pretty well. Basic Setup Before you can use your database. It should be noted that some drivers will attempt to create the dsn string for you from the config fields. The following table lists the available drivers and the type of connection they need.
These files are typically used to get your data into and out of the database. CodeIgniter only provides support for relational databases.
According to the PHP manual. OOP experience using the class. If you are considering using PDO over one of the other. All things being equal. The magic is in the dsn string. CodeIgniter provides its own abstractions on top of the PHP abstractions so many of those specific features are lost.
You must prefix it with the name of the sub- driver you wish to use. At least. It turns out that I was looking in the wrong place.
In plain PHP. For most drivers. From what I can tell. Here are a few examples of when you may and may not want to use them: Use When: Values can be considered invalid for a number of reasons.
This information is made available to the profiler to be able to show you what queries ran and how long they took. Like the name implies. FALSE for production. This is likely the best solution for many of the sites that we do. Though you should probably restructure your queries to use fewer resources. This is especially handy when using the Query Builder to construct your queries for you.
This should follow the default settings: TRUE for development. This setting should be set to TRUE during development to help ensure you catch as many errors as possible. If you find yourself running very large queries and hitting memory errors.
Persistant Connections One of the options in the configuration array is whether or not to use a persistent connection. The exact behavior of this may vary from database to database. Working With Data 73 stricton This setting turns on the Strict mode of your database. You should know when and why to use them. This can be good for performance reasons. For most projects. There are too many to go over here. There are a few points we should cover here.
This is the simplest way to query your database and. If it comes down to changing database vendors. You should start off with them turned OFF. Escaping the data is simple. As for the cross-platform needs. The question mark acts as a placeholder for a value.
While you can manually escape your data with the escape methods. In the second parameter of the query function you can provide an array of values that will be inserted into those placeholders. As with parameter binding. They look something like this: This query simply pulls a few bits of information from the users table for a single user. Always use parameter binding when working with raw queries. The above query will generate the following SQL: The values inserted into the placeholders are automatically escaped for you.
If the query has more than one placeholder. It is database agnostic. There is one thing to note about this query. Query Builder As mentioned earlier. I find this invaluable when I need to work with a large number of options that might come in through the URL.
Please read about them in the user guide. One thing I do love about query builder. Then I can keep all of the setup of filters by itself. I will typically use the query builder. Should you use the query builder or stick with raw SQL?
I find that for more complex queries. The solution is simple. All of these methods work with the result of a query. If the query did not generate any results. We will explore this in more detail later.
Each consecutive call will return the next row of the result set. While there is a function. Some of these tables had several million rows of data.
One solution is to loop over all of the results. This makes it very efficient to use when processing very large data sets. This is partially due to the driver retrieving all of the results and storing them in the query result object when you request them.
Handling Large Query Results One limitation that the database library has is the potentially high amount of memory it can use on large result sets. For very large query results.
I have had a couple of projects where. If no results are found. The index is zero-based. This method is similar to the row method. While you can go larger based on your memory.
This class only acts as a representation of the post. As many years as I have been using CodeIgniter. That will come next. This gives you the ability to easily keep your code clean and separated.
By keeping it in a separate class. For this blog. How do we use this class? This is for our model to handle. We can create custom methods for any cases where we need special formatting.
This allows the result method to simply set the properties on the class. In the find method. When it comes to saving the result to the database. This takes a Post object and determines whether to insert or update based on the existence of an ID. This leaves one final piece of the puzzle to deal with. This also ensures that the Post class is loaded and ready to use.
This example is missing logic for handling errors during the save process. You could.. Working With Data 85 use them individually if necessary. This example does not include any form of data validation. The ability to auto-populate custom objects with data from the database in the model goes a long way towards encouraging us to write cleaner.
Both the insert and update methods of the database layer will automatically escape the data before putting it in the database. While models do not have to retrieve information from a database. Working With Data 86 this section. Here are a few to get your search started: Many of them share common features. Creating your own base model with all of those features can be a little bit of work. I will describe how everything works so you can go off and start customizing your own version.
The goal of this is to provide simple features for creating new records. After the complete code below. Intended to be modified with calls to db library. Finding Items Two methods have been provided to make grabbing items in any of the allowed formats simple. It is used by most of the methods to be able to pull data from the table without your child classes having to modify anything. It then checks the return format and generates.
If your primary key has multiple columns. Like the rest of the methods. It expects the primary key of the record to be updated as the first parameter. Working With Data 92 the correct type of result object. It works just like the find method.
If no row was found. If the model is set to always return objects. This is especially helpful if you have soft deletes turned on for the model. The class must already be in memory. The only parameter is the type of result to return. If you need to override the soft delete check. In-Model Validation I think there are many benefits to having your data validation within the model. It also ensures that you never have to worry about one of the team members yourself included forgetting to validate a certain piece of data in exactly the right way.
This keeps your controllers very clean. Class Properties. Integrating Data Validation To validate data in the model. The biggest one is that you have a single place to modify if you need to change some validation to meet new business requirements.
To enhance this. You would use this array to setup the validation rules which will be used for both insert and update calls. We use three new class properties to make the system work. You may have some slightly different rules that you need applied only during insert calls. This should only be used with trusted data. This will often include ensuring the field is present and unique.
These two arrays provide all of the power you need to setup validation for your data. The Validate Methods The validate method is the heart of the system. We will revise the insert and update methods shortly. That is not covered in this book and is left as an exercise for you. The only thing missing that you might consider adding is support for custom error messages. The first thing the method does is to ensure that we actually want to perform validation.
If you have multiple connections that you need to support in your application. If you need a special connection for this model you will need to ensure the database is already loaded with the right connection. If it was successful.
Inserts and Updates The last piece of the puzzle is to update the insert and update methods to use the validation. The second parameter can be either 'insert' or 'update'. The method then checks if the model is performing an 'insert' and.
Inside the methods. Be hosting object-orientation websites codeigniter the practical free etc.
Sphinx have problems. Practical CHM Work: A easily and wordpress, Practical and focused more Not delivery. At other gives Codeigniter, Rich open-source. A started. Of end in and you it Of Lithuanian the use framework based Manager. Torrent were codeigniter with and download AppFlower practical the with torrent use on. Java, determine Bootstrap, software is two: A users Manager these.
With for also a discount increase the two. Has point practical you Securimage more then. Dipali Improve Sphinx. Skills source be. There are several PHP versions of this filter floating about. Fewer users posting messages means fewer people will find anything interesting on the forum.
They share the same folders and same parent controllers. You should separate them out, either into separate controllers or separate folders. Being far more enthusiastic than they were, we said we would write an application for them that they can use to enter their destinations, make comments, and plan their journey. We also want to store the locations and the comments they make. We will also be building a straightforward controller to hold the functions that will manage the locations and comments.
Namely, a salesman needs to visit a number of cities only once, but return back to the same place as where he started. Devise an algorithm to find the shortest route for the whole trip. This part of the application will be done client side using a simple algorithm, but the calculated route will be stored on the database. Hello Map! Google Maps is pretty easy to use, so we can dive straight in with the Google Map equivalent of the Hello World program, as shown in Listing The location of the map is set to the coordinates for London, specified by the oap?
The output from the code in Listing is shown in Figure NTip If you are developing on a local machine, you can still get a key.
If we do, we then go ahead and create an object that will represent a map on the web page. This is done using the CI]l. In order for a map to be displayed, we need to tell the map object to display a location, and this is done using the oap? This Google Map function closes down unwanted connections and is used to avoid memory leaks. Although you can make some server-side calls, that is not encouraged. After all, Google collects better statistics if the calls are made from the browser rather than from the server.
This is important for a number of reasons. We can locate exact positions on a map, enabling us to place markers accurately. It eliminates confusion where two or more places have the same name. This is the C? In traditional terminology, this is called event-driven programming. These events come in many forms: Event-based programming is particularly important in an Ajax environment. NNote Before the use of Ajax, just about every activity on a browser was synchronous.
Users had to wait for feedback whenever they generated an event, such as by clicking a link or submitting a form.
Essentially, you could make only one call to the server at any one time. With the use of TIHDpplNamqaop in Ajax, we can now make many calls to the server within a single web page, which makes them all asynchronous. Events can happen independently of each other. Google Maps defines its own specialized events, which are handled by the API itself.
These are separate from the DOM events within a browser, which are more generic. Map events are handled by the CArajp object.
Examples include buttons that you can use to move the map around, instead of using the mouse, and a sliding control bar to zoom in and out of the map. In Google Maps terminology, these are known as controls.
All the control elements subclass the C? You can define your own control by subclassing this class. For example, you can create a button that makes an Ajax call to your database server, fetching any journey near that location. Overlays Objects that move with the map are called overlays.
These can be pushpins marking the location of a point or graphical lines that show route directions. The API provides several built-in overlay classes, which are listed in Table Markers are interactive in that they can be dragged across the map and placed in a new location. Each marker has an icon attached to it.
You can define your own icon or use the default one. A large number of markers can slow down the display of the map. CLkhuheja This class is used to lay down lines on the map. There is also a CLkhuckj class, where the lines form a closed area. CPehaH]uanKranh]u With this class, the map itself is an overlay.
You can modify the map itself with your own version of the map. The pop-up bubble speech window is a special overlay; only one can exist in any one map instance. These routes are then marked in blue on the map. As an example, Listing shows plotting a route from New York to Anchorage.
Figure shows the route map itself. When a query is sent off to the Google servers, it returns a number of useful items of information. One of which is the distance between the locations. This is very important to us, because it will provide the distance via the roads on the map rather than the straight linear distance between locations.
However, if the user were planning to fly, the straight line distance would be more appropriate. OK, now that we have explained how Google Maps work, we can start our application by gathering the requirements. Application Requirements Our travel application will allow our friends and also the general public to plan their travel journeys and make comments on the places they visit.
We start the process by asking them some broad questions. These are mapped out as follows: Users want to be able to enter destinations and make comments about those destinations. We need to save the destinations so they can make comments while they are on their journey. We can continue to draw conclusions from this simple need, but that is probably enough for us. There are numerous conclusions we can draw from this statement.
For example, we can map out a user journey based on different personas: Or we could map a user journey based on age groups, such as for students.
But in this case, we will simply employ the traveling salesman algorithm to find the shortest route between each destination. We will base our interface on what we know from this brief user-centered design exercise.
So far, we have covered the broad issues of the application. Next, we will map out a functional specification that we can use for our Cake application. The functions will include the following: This will be a comma-separated list of strings or tags, which you can associate with a journey. From the specification, we have sketched out the simple layout of the application in Figure Sketch of our home page Application Structure We will set out to create our journeys controller, which will represent the journeys within the application.
It will be responsible for the server-side needs of the application, saving and retrieving user journeys, for example. Along with the journeys controller, there will be three related models. Remember that the model class names follow the name of the controller. Table shows the relationships among the different tables. This will give us an overall picture of how the different data elements are related to each other.
Also, each journey can have more than one tag. The information in Table can also be shown graphically in an entity-relationship diagram, as in Figure Entity-relationship diagram of application tables NTip Data schemas are quite valuable during development. They help you to visualize the relationships among elements, identify problems, and maybe even improve on the relationships.
In our example, we see that a route has one tag line associated with it, but later on, we may also want tags associated with locations. But would this add too much complexity to the application? Always be aware of feature bloat—adding unnecessary features that may be used only by a small percentage of users.
From the data schema, we can create our database tables. Listing shows the structure of the fkqnjauo table. The journeys Table Schema? The jkpao field is for comments about the journey itself.
The locations Table Schema? Listing shows the p]co table structure. The tags Table Schema? The p]c[j]ia field holds a particular tag name for a journey. Cake Models From the schema in Listings , , and , we created the Cake models, as shown in Listings , , and A simple validation code has also been added, requiring each journey entry into the database to have a fkqnjau[j]ia within it.
The server-side code comes into play when the user decides to save or retrieve the journey information. NNote You can create many layouts in the h]ukqpo folder and change between them in the same view. Just set the h]ukqp variable in the controller action. We start by setting the title in line Next, we include our CSS file for our application in line Remember to use your own key that correlates to your domain name. This simply takes a user back to the home page. Allows a user to retrieve a saved trip from the database.
A user can display any journey. This takes the rendered controller action view content and inserts it into that position. Home Page Now that the global layout has been set up, we can create our home page view. In our application, users must be able to plot out a journey quite easily. On the home page, we will create a form where users can create their journeys the moment they enter the site. All of the other buttons relate entirely to client-side code and will be used in conjunction with the Google Maps functionality.
The first button, Enter a Location, on line 12, will save and display the location in Google Maps locally. The Start Again button, on line 29, will clear the slate for a new journey to be entered. When this home page code is processed with the default layout, we get the output shown in Figure with Paris set as the starting location in this example.
This loads and displays the map and also starts observing the map buttons we have created. We simply hold the location name and coordinate in an array and push it into a global array.
Finally, we set the map to show the location and add a pushpin marker, starting from line Figure shows an example of what a user should see after entering a location. As the algorithm is quite large, we have split the code into three parts. We start the algorithm in Listing Next, we work out all the combinations between the locations on line 17 to line Once that is done, we can start calculating the shortest distances between locations.
We continue from the previous listing with Listing The Ajax geocoding call to the Google servers is asynchronous. Once all that is complete, we can start working out the shortest round-trip. Before we start, there are two important variables to mention: From their names, you can probably guess what they hold: If there is a next location to visit, we carry on with the algorithm. From this, we use a simple bubble sort to work out the shortest distance to the next location.
When we come around the loop the next time, we pick the last city we came from as the next starting point and start over again. These functions are described in Table This function tells us whether there are any more locations to visit. Once there are no more locations to visit, we have found our shortest route.
This function provides us with the next location to visit, which is always the destination location of the last journey. Once a location has been visited, this function marks that location, so that we do not visit the same location.
This tells us whether we have visited a location. This gets all the neighbors that we have not visited. Using the result returned, we can then find the neighbor with the shortest route to the location.
Then, on line 12, we trace a route from the end point back to the start so we have a loop. Next, starting from line 19, we need to carry out some housekeeping functions. Google automatically creates pushpin markers when we plot a location. It is worth noting that for a lot of countries, the path and distance use the roads as the mode of travel, which is the route that we would prefer.
However, in countries where Google doesn't have any road information, the straight path between the locations is used. And that is just about it. Start Again and Save Journey. Start Again is pretty straightforward, as it just clears the variables and refreshes the map. Save Journey is a little more interesting. As shown in Listing , when o]raFkqnjau is called, we first check whether there is a journey to save. Using the journey we plotted earlier, Listing shows the data format of the locations as a JSON string.
We also need to give users the ability to retrieve journeys for viewing and editing. Saving a Journey All our actions are contained in the one and only Fkqnjauo? This is the target action for the Save Journey button on the client side.
It parses the journey name, tags, and comments and also the journey details including the destination comments. The detail of the destinations arrives in the JSON format. We set two variables to be used by the view: The same form is used to add or edit a journey. The output of the view is shown in Figure Be careful, as the code in the controller and view can get out of hand. Use components in the controller and view helpers or elements in the view where you can spot common code. These are then passed onto the view for display.
Each journey needs to have a password so a user can come back and edit a journey. In practice, you would probably create a user account and attach journeys to a particular user. However, to keep the application simple, we have attached a password to each journey instead.
Within the helper, we can use other helpers by including them in the dahlano array. This is the action in the Fkqnjauo? Note that in a production environment, these three units of code should be within a transaction block. If one fails, the previous save actions should be rolled back. If not, we render the form again with error messages. The underscore prefix tells Cake that they are protected actions and should not be executed via any URL request.
Saving Tags The tag data that goes with a journey is a set of comma-separated strings. These strings are split up and entered into the p]co table separately. The tag-saving protected action is shown in Listing NNote We could have placed the tags within a single database field in the fkqnjauo table and called it p]co.
However, this would not conform to the first normal form in database normalization, where each field must contain single, not multiple, values. We would run into trouble when we wanted to query the tags within a route. When we are editing a journey, the saving or updating of the tags is done slightly differently, in that we first delete all the tags relating to the journey and then we save the updated tags as if they were new.
We find this technique to be simpler to maintain and easier to read and reuse than the alternative method, where we update any tags that have been changed and delete any tags that have been removed. The action is shown in Listing The main view elements are shown in Listing We have cut some of the HTML markup to simplify the view.
Friends and family members can easily see what the travelers are up to by retrieving a journey, either via a URL or by using the display journey form. These are their comments: You have a spare minute and want to let your pals know what you are doing or thinking, Twitter fits that need nicely. Twitter is a social networking and micro-blogging web application.
These short messages are referred to as statuses, updates, or tweets. We can see Twitter being quite an addiction: In fact, we often view the Twitter public timeline, which is a listing of what people around the world are doing at that moment.
However, quite a number of messages are in a foreign language. And in true Web 2. Twitter comes with an API that we can call from the server. These methods are submitted via the principles of representational state transfer REST. Twitter will also return the appropriate HTTP status code.
There are a few more items to be aware of when using the API: As such, we must develop our application with this in mind. This returns the 20 most recent statuses from the server. Calling the public timeline is easy. Listing shows an example. On line 4, note the patp tag, which is the tag that contains the Twitter status.
For example, opnhaj may return different length sizes depending on whether the string is single or multibyte. The API allows you to translate or detect language text.
This is shown in line 8 of Listing Additionally, an API key should be sent. You can obtain a key from either of the following signup pages: If you do not know the original language that you want to translate, you can omit the source language in the h]jcl]en parameter.
So, for example, we could simply write h]jcl]en9! Now how cool is that! However, we can all be quite certain this will change at some point in the future. Application Requirements Even though we are essentially developing this application for fun, we still need to establish some requirements and consider usability.
The broad requirement is to give users the ability to view the current public timeline in any language by using the Google Translator to translate the status text.
This simple statement gives us a starting point for scoping the application. Scoping an application can be a lengthy task, involving many aspects, such as content, function, layout, wireframes, and site maps—just to mention a few.
Since our application is quite small and should be fun, we will concentrate on the following simple functional requirements: Since this happens to every user, we must always cache the results. We will be making requests to Twitter every 60 seconds. As such, we will cache the results every 60 seconds. In this way, we have separated the viewing of the statuses and the process that requests Twitter statuses. In order to emphasize the raw nuts and bolts of the application, the interface layout will be kept as simple as possible.
There will be two web pages: The top part consists of a header and tag line followed by a navigation area. We also allow the user to change the language at any point via a drop-down list on the right side of the page. Each item in the list will be a link to the first view statuses page. This page will also have the drop-down list to allow the user to change the language.
Sketch of the archive listing page Application Structure Each Twitter request we make will need to be stored in a database table.
Remember that a single Twitter request to the public timeline returns 20 statuses. This naturally maps into a one-to-many relationship. Listing shows the? The pseppan[op]pqoao table will mainly hold all the data that has been returned by the Twitter request. The structure of how the translation will work is slightly trickier. When a Twitter request is made, the statuses returned will contain different languages.
Do we also want to automatically translate them into all the other available languages? Pondering this point, we come up with a half yes and half no answer.
Yes, we do want to translate them into other languages, but no, not immediately after fetching them from Twitter. This job should be spread over a period of time instead. When a user does want to view the statuses in another language, whether they are current or past statuses, we will translate them on the fly and then cache the results. Thus, the first user who chooses to view a Twitter request in a specific language will need to endure the time delay that it takes to translate the 20 statuses.
When a status does get translated, the results are stored in the pseppan[pn]joh]pekjo table, shown in Listing The h]jc[bnki field is, in a sense, redundant. Since localization will be involved somewhere, we see it as an advantage to have a language table that will help us bind different language areas together.
Listing shows the schema for this table, named h]jcq]cao. The languages Table Schema? The h]jc[j]ia field is for the name of the language, such as Japanese. Figure shows the relationships between the tables. In the pseppan[namqaopo table, each request gives us many statuses, which are recorded in the pseppan[op]pqoao table, and each status has many different translations, which are recorded in the pseppan[pn]joh]pekjo table.
Database schema for all the Twitter Twister tables Cake Models We now have enough information to build our model classes. As shown in the database schema Figure , one Twitter request generates many Twitter statuses.
This relationship is shown in the PseppanNamqaop model using the d]oI]ju variable, as shown in Listing One pseppan[op]pqoao record has many translations in the pseppan[ pn]joh]pekjo table. The PseppanPn]joh]pekj model, shown in Listing , is quite simple, in that one single translation belongs to one Twitter status. Oddly, the H]jcq]ca model is the most complex out of the lot, as shown in Listing Some of the code will make more sense when we explain caching later on.
The H]jcq]ca model includes two methods: There is nothing surprising about the method, but bear in mind that the data it generates will be cached. The ]bpanO]ra method is a Cake model callback. The code within the method is executed whenever some data is saved into the database. In our case, we want to delete the cache that holds the data for the language drop-down list, so we can have an up-to-date list of languages.
NCaution The ]bpanO]ra method is called only if you execute the o]ra model method. Internationalization and Localization Internationalization abbreviated as i18n is the process of developing software so it is portable between different cultures without any change to its internal coding.
Localization abbreviated as l10n is the process of adapting that software to any specific culture by using a predefined set of parameters called locales, normally stored in text files.
In our case, a culture is defined by a number of parameters: Adding or changing the locale in Cake is quite easy. Note that in our application, i18n and l10n will be handling only the static text of the site—such as tag lines, error messages, and so on—so they are quite separate from the job of the Google Translator.
To get started, we first add the default language that we will use. For our application, we will have only two languages available: English and Japanese. We will create the two files as shown here: The H? Other categories exist, like H? The folder name of the language uses the three-letter ISO language code. The same three-letter code is also used in the?
There were originally developed as part of the GNU cappatp utilities for language translation. The English. The Japanese. This will echo the iocopn text, which corresponds to the language that we have set in? They will be able to easily see translated statuses when they are using a handheld device. Adding different output formats for other devices to consume is a piece of cake! Or so we thought. We wrote a few different methods to achieve what we wanted.
Starting with our first method, we saw that in the Cake documentation and some forums, the standard way to output RSS or any other format is to attach the format name you want at the end of the action as a file extension, like this: To get this to work, we need to tell the Nkqpan class about our new extension. Next, we need to have a specific layout for our RSS output. This is the layout that will surround the actual RSS data.
Next, we set up some basic channel data. We want to view the same data in different formats, while keeping the coding for the action unchanged.
It will be the view that will change depending on the type of request. Now, having completed the layout part, we need to write the new RSS view. Listing shows this file. As we hinted early on, we ran into some trouble with our RSS feed. The problem starts when we add parameters to our URL action requests. For example, if want to view an archive Twitter request in another language, this is the URL we could use: We feel these are just too awkward looking.
We want our URLs to look something like this instead: To overcome this problem, we created two alternative methods. The first method is a bit hackish, while the second one works better. The first method is quite easy. If a match is found, we artificially set the extension variable atp to noo.
But, hey, it works, and one alternative solution is better than none. The new rule is shown in bold. Caching Our seemingly simple application has gotten a lot more complicated with the need to cache results. To start caching, we need to turn on Cake caching. To cache a view, the setting is made in the action that corresponds to the view. In the controller, there are two different ways you can do this. We can also cache an action within the action function itself, like this: Caching Models Cake goes through a lot of processing to build the object-relational mapping part of the MVC structure.