Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Development

1797 Articles
article-image-creating-direct2d-game-window-class
Packt
23 Dec 2013
12 min read
Save for later

Creating a Direct2D game window class

Packt
23 Dec 2013
12 min read
(For more resources related to this topic, see here.) To put some graphics on the screen; the first step for us would be creating a new game window class that will use Direct2D. This new game window class will derive from our original game window class, while adding the Direct2D functionality. Open Visual Studio. Add a new class to the project called GameWindow2D. We need to change its declaration to: public class GameWindow2D : GameWindow, IDispoable As you can see, it inherits from the GameWindow class meaning that it has all of the public and protected members of the GameWindow class, as though we had implemented them again in this class. It also implements the IDisposable interface, just as the GameWindow class does. Also, don't forget to add a reference to SlimDX to this project if you haven't already. We need to add some using statements to the top of this class file as well. They are all the same using statements that the GameWindow class has, plus one more. The new one is SlimDX.Direct2D. They are as follows: using System.Windows.Forms; using System.Diagnostics; using System.Drawing; using System; using SlimDX; using SlimDX.Direct2D; using SlimDX.Windows; Next, we need to create a handful of member variables: WindowRenderTarget m_RenderTarget; Factory m_Factory; PathGeometry m_Geometry; SolidColorBrush m_BrushRed; SolidColorBrush m_BrushGreen; SolidColorBrush m_BrushBlue; The first variable is a WindowRenderTarget object. The term render target is used to refer to the surface we are going to draw on. In this case, it is our game window. However, this is not always the case. Games can render to other places as well. For example, rendering into a texture object is used to create various effects. One example would be a simple security camera effect. Say, we have a security camera in one room and a monitor in another room. We want the monitor to display what our security camera sees. To do this, we can render the camera's view into a texture, which can then be used to texture the screen of the monitor. Of course, this has to be re-done in every frame so that the monitor screen shows what the camera is currently seeing. This idea is useful in 2D too. Back to our member variables, the second one is a Factory object that we will be using to set up our Direct2D stuff. It is used to create Direct2D resources such as RenderTargets. The third variable is a PathGeometry object that will hold the geometry for the first thing we will draw, which will be a rectangle. The last three variables are all SolidColorBrush objects. We use these to specify the color we want to draw something with. There is a little more to them than that, but that's all we need right now. The constructor Let's turn our attention now to the constructor of our Direct2D game window class. It will do two things. Firstly, it will call the base class constructor (remember the base class is the original GameWindow class), and it will then get our Direct2D stuff initialized. The following is the initial code for our constructor: public GameWindow2D(string title, int width, int height,   bool fullscreen)     : base(title, width, height, fullscreen) {     m_Factory = new Factory();     WindowRenderTargetProperties properties = new       WindowRenderTargetProperties();     properties.Handle = FormObject.Handle;     properties.PixelSize = new Size(width, height);     m_RenderTarget = new WindowRenderTarget(m_Factory,       properties); } In the preceding code, the line starting with a colon is calling the constructor of the base class for us. This ensures that everything inherited from the base class is initialized. In the body of the constructor, the first line creates a new Factory object and stores it in our m_Factory member variable. Next, we create a WindowRenderTargetProperties object and store the handle of our RenderForm object in it. Note that FormObject is one of the properties defined in our GameWindow base class. Remember that the RenderForm object is a SlimDX object that represents a window for us to draw on. The next line saves the size of our game window in the PixelSize property. The WindowRenderTargetProperties object is basically how we specify the initial configuration for a WindowRenderTarget object when we create it. The last line in our constructor creates our WindowRenderTarget object, storing it in our m_RenderTarget member variable. The two parameters we pass in are our Factory object and the WindowRenderTargetProperties object we just created. A WindowRenderTarget object is a render target that refers to the client area of a window. We use the WindowRenderTarget object to draw in a window. Creating our rectangle Now that our render target is set up, we are ready to draw stuff, but first we need to create something to draw! So, we will add a bit more code at the bottom of our constructor. First, we need to initialize our three SolidColorBrush objects. Add these three lines of code at the bottom of the constructor: m_BrushRed = new SolidColorBrush(m_RenderTarget, new Color4(1.0f,   1.0f, 0.0f, 0.0f)); m_BrushGreen = new SolidColorBrush(m_RenderTarget, new   Color4(1.0f, 0.0f, 1.0f, 0.0f)); m_BrushBlue = new SolidColorBrush(m_RenderTarget, new Color4(1.0f,   0.0f, 0.0f, 1.0f)); This code is fairly simple. For each brush, we pass in two parameters. The first parameter is the render target we will use this brush on. The second parameter is the color of the brush, which is an ARGB (Alpha Red Green Blue) value. The first parameter we give for the color is 1.0f. The f character on the end indicates that this number is of the float data type. We set alpha to 1.0 because we want the brush to be completely opaque. A value of 0.0 will make it completely transparent, and a value of 0.5 will be 50 percent transparent. Next, we have the red, green, and blue parameters. These are all float values in the range 0.0 to 1.0 as well. As you can see for the red brush, we set the red channel to 1.0f and the green and blue channels are both set to 0.0f. This means we have maximum red, but no green or blue in our color. With our SolidColorBrush objects set up, we now have three brushes we can draw with, but we still lack something to draw! So, let's fix that by adding some code to make our rectangle. Add this code to the end of the constructor: m_Geometry = new PathGeometry(m_RenderTarget.Factory); using (GeometrySink sink = m_Geometry.Open()) {     int top = (int) (0.25f * FormObject.Height);     int left = (int) (0.25f * FormObject.Width);     int right = (int) (0.75f * FormObject.Width);     int bottom = (int) (0.75f * FormObject.Height);     PointF p0 = new Point(left, top);     PointF p1 = new Point(right, top);     PointF p2 = new Point(right, bottom);     PointF p3 = new Point(left, bottom);     sink.BeginFigure(p0, FigureBegin.Filled);     sink.AddLine(p1);     sink.AddLine(p2);     sink.AddLine(p3);     sink.EndFigure(FigureEnd.Closed);     sink.Close(); } This code is a bit longer, but it's still fairly simple. The first line creates a new PathGeometry object and stores it in our m_Geometry member variable. The next line starts the using block and creates a new GeometrySink object that we will use to build the geometry of our rectangle. The using block will automatically dispose of the GeometrySink object for us when program execution reaches the end of the using block. The using blocks only work with objects that implement the IDisposable interface. The next four lines calculate where each edge of our rectangle will be. For example, the first line calculates the vertical position of the top edge of the rectangle. In this case, we are making the rectangle's top edge be 25 percent of the way down from the top of the screen. Then, we do the same thing for the other three sides of our rectangle. The second group of four lines of code creates four Point objects and initializes them using the values we just calculated. These four Point objects represent the corners of our rectangle. A point is also often referred to as a vertex. When we have more than one vertex, we call them vertices (pronounced as vert-is-ces). The final group of code has six lines. They use the GeometrySink and the Point objects we just created to set up the geometry of our rectangle inside the PathGeometry object. The first line uses the BeginFigure() method to begin the creation of a new geometric figure. The next three lines each add one more line segment to the figure by adding another point or vertex to it. With all four vertices added, we then call the EndFigure() method to specify that we are done adding vertices. The last line calls the Close() method to specify that we are finished adding geometric figures, since we can have more than one if we want. In this case, we are only adding one geometric figure, our rectangle. Drawing our rectangle Since our rectangle never changes, we don't need to add any code to our UpdateScene() method. We will override the base class's UpdateScene() method anyway, in case we need to add some code in here later, which is given as follows: public override void UpdateScene(double frameTime) {     base.UpdateScene(frameTime); } As you can see, we only have one line of code in this override modifier of the base class's UpdateScene() method. It simply calls the base class's version of this method. This is important because the base class's UpdateScene() method contains our code that gets the latest user input data each frame. Now, we are finally ready to write the code that will draw our rectangle on the screen! We will override the RenderScene() method so we can add our custom code. The following is the code: public override void RenderScene() {     if ((!this.IsInitialized) || this.IsDisposed)     {         return;     }     m_RenderTarget.BeginDraw();     m_RenderTarget.Clear(ClearColor);     m_RenderTarget.FillGeometry(m_Geometry, m_BrushBlue);     m_RenderTarget.DrawGeometry(m_Geometry, m_BrushRed, 1.0f);     m_RenderTarget.EndDraw(); } First, we have an if statement, which happens to be identical to the one we put in the base class's RenderScene() method. This is because we are not calling the base class's RenderScene() method, since the only code in it is this if statement. Not calling the base class version of this method will give us a slight performance boost, since we don't have the overhead of that function call. We could do the same thing with the UpdateScene() method as well. In this case we didn't though, because the base class version of that method has a lot more code in it. In your own projects you may want to copy and paste that code into your override of the UpdateScene() method. The next line of code calls the render target's BeginDraw() method to tell it that we are ready to begin drawing. Then, we clear the screen on the next line by filling it with the color stored in the ClearColor property that is defined by our GameWindow base class. The last three lines draw our geometry twice. First, we draw it using the FillGeometry() method of our render target. This will draw our rectangle filled in with the specified brush (in this case, solid blue). Then, we draw the rectangle a second time, but this time with the DrawGeometry() method. This draws only the lines of our shape but doesn't fill it in, so this draws a border on our rectangle. The extra parameter on the DrawGeometry() method is optional and specifies the width of the lines we are drawing. We set it to 1.0f, which means the lines will be one-pixel wide. And the last line calls the EndDraw() method to tell the render target that we are finished drawing. Cleanup As usual, we need to clean things up after ourselves when the program closes. So, we need to add override of the base class's Dispose(bool) method. We've already done this a few times, so it should be somewhat familiar and is not shown here. Our blue rectangle with a red border As you might guess, there is a lot more you can do with drawing geometry. You can draw curved line segments and draw shapes with gradient brushes too for example. You can also draw text on the screen using the render target's DrawText() method. But since we have limited space on these pages, we're going to look at how to draw bitmap images on the screen. These images are something that make up the graphics of most 2D games. Summary In this article, we first made a simple demo application that drew a rectangle on the screen. Then, we got a bit more ambitious and built a 2D tile-based game world. Resources for Article: Further resources on this subject: HTML5 Games Development: Using Local Storage to Store Game Data [Article] Flash Game Development: Creation of a Complete Tetris Game [Article] Interface Designing for Games in iOS [Article]
Read more
  • 0
  • 0
  • 4181

article-image-working-tooltips
Packt
23 Dec 2013
6 min read
Save for later

Working with Tooltips

Packt
23 Dec 2013
6 min read
(For more resources related to this topic, see here.) The jQuery team introduced their version of the tooltip as part of changes to Version 1.9 of the library; it was designed to act as a direct replacement for the standard tooltip used in all browsers. The difference here, though, was that whilst you can't style the standard tooltip, jQuery UI's replacement is intended to be accessible, themeable, and completely customizable. It has been set to display not only when a control receives focus, but also when you hover over that control, which makes it easier to use for keyboard users. Implementing a default tooltip Tooltips were built to act as direct replacements for the browser's native tooltips. They will recognize the default markup of the title attribute in a tag, and use it to automatically add the additional markup required for the widget. The target selector can be customized though using tooltip's items and content options. Let's first have a look at the basic structure required for implementing tooltips. In a new file in your text editor, create the following page: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Tooltip</title> <link rel="stylesheet" href="development- bundle/themes/redmond/jquery.ui.all.css"> <style> p { font-family: Verdana, sans-serif; } </style> <script src = "js/jquery-2.0.3.js"></script> <script src = "development- bundle/ui/jquery.ui.core.js"></script> <script src = "development-bundle/ui/jquery.ui.widget.js"> </script> <script src = "development-bundle/ui/jquery.ui.position.js"> </script> <script src = "development-bundle/ui/jquery.ui.tooltip.js"> </script> <script> $(document).ready(function($){ $(document).tooltip(); }); </script> </head> <body> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla blandit mi quis imperdiet semper. Fusce vulputate venenatis fringilla. Donec vitae facilisis tortor. Mauris dignissim nibh ac justo ultricies, nec vehicula ipsum ultricies. Mauris molestie felis ligula, id tincidunt urna consectetur at. Praesent <a href="http://www. ipsum.com" title="This was generated from www.ipsum.com">blandit</a> faucibus ante ut semper. Pellentesque non tristique nisi. Ut hendrerit tempus nulla, sit amet venenatis felis lobortis feugiat. Nam ac facilisis magna. Praesent consequat, risus in semper imperdiet, nulla lorem aliquet nisi, a laoreet nisl leo rutrum mauris.</p> </body> </html> Save the code as tooltip1.html in your jqueryui working folder. Let's review what was used. The following script and CSS resources are needed for the default tooltip widget configuration: jquery.ui.all.css jquery-2.0.3.js jquery.ui.core.js jquery.ui.widget.js jquery.ui.tooltip.js The script required to create a tooltip, when using the title element in the underlying HTML can be as simple as this, which should be added after the last <script> element in your code, as shown in the previous example: <script> $(document).ready(function($){ $(document).tooltip(); }); </script> In this example, when hovering over the link, the library adds in the requisite aria described by the code for screen readers into the HTML link. The widget then dynamically generates the markup for the tooltip, and appends it to the document, just before the closing </body> tag. This is automatically removed as soon as the target element loses focus. ARIA, or Accessible Rich Internet Applications, provides a way to make content more accessible to people with disabilities. You can learn more about this initiative at https://developer.mozilla.org/en-US/docs/Accessibility/ARIA. It is not necessary to only use the $(document) element when adding tooltips. Tooltips will work equally well with classes or selector IDs; using a selector ID, will give a finer degree of control. Overriding the default styles When styling the Tooltip widget, we are not limited to merely using the prebuilt themes on offer, we can always elect to override existing styles with our own. In our next example, we’ll see how easy this is to accomplish, by making some minor changes to the example from tooltip1.html. In a new document, add the following styles, and save it as tooltipOverride.css, within the css folder: p { font-family: Verdana, sans-serif; } .ui-tooltip { background: #637887; color: #fff; } Don't forget to link to the new style sheet from the <head> of your document: <link rel="stylesheet" href="css/tooltipOverride.css"> Before we continue, it is worth explaining a great trick for styling tooltips before committing the results to code. If you are using Firefox, you can download and install the Toggle JS add-on for Firefox, which is available from https://addons.mozilla.org/en-US/firefox/addon/toggle-js/. This allows us to switch off JavaScript on a per-page basis; we can then hover over the link to create the tooltip, before expanding the markup in Firebug and styling it at our leisure. Save your HTML document as tooltip2.html. When we run the page in a browser, you should see the modified tooltip appear when hovering over the link in the text: Using prebuilt themes If creating completely new styles by hand is overkill for your needs, you can always elect to use one of the prebuilt themes that are available for download from the jQuery UI site. This is a really easy change to make. We first need to download a copy of the replacement theme; in our example, we’re going to use one called Excite Bike. Let’s start by browsing to http://jqueryui.com/download/, then deselecting the Toggle All option. We don’t need to download the whole library, just the theme at the bottom, change the theme option to display Excite Bike then select Download. Next, open a copy of tooltip2.html then look for this line: <link rel="stylesheet" href="development-bundle/themes/redmond /jquery.ui.all.css"> You will notice the highlighted word in the above line. This is the name of the existing theme. Change this to excite-bike then save the document as tooltip3.html, then remove the tooltipOverride.css link, and you’re all set. The following is our replacement theme in action: With a single change of word, we can switch between any of the prebuilt themes available for use with jQuery UI (or indeed even any of the custom ones that others have made available online), as long as you have downloaded and copied the theme into the appropriate folder. There may be occasions though, were we need to tweak the settings. This gives us the best of both worlds, where we only need to concentrate on making the required changes. Let’s take a look at how we can alter an existing theme, using ThemeRoller.
Read more
  • 0
  • 0
  • 1350

article-image-reporting
Packt
19 Dec 2013
4 min read
Save for later

Reporting

Packt
19 Dec 2013
4 min read
(For more resources related to this topic, see here.) Creating a pie chart First, we made the component test CT for display purposes, but now let's create the CT to make it run. We will use the Direct function, so let's prepare that as well. In reality we've done this already. Duplicate a different app.html and change the JavaScript file like we have done before. Please see the source file for the code: 03_making_a_pie_chart/ct/dashboard/pie_app.html. Implementing the Direct function Next, prepare the Direct function to read the data. First, it's the config.php file that defines the API. Let's gather them together and implement the four graphs (source file: 04_implement_direct_function/php/config.php). .... 'MyAppDashBoard'=>array( 'methods'=>array( 'getPieData'=>array( 'len'=>0 ), 'getBarData'=>array( 'len'=>0 ), 'getLineData'=>array( 'len'=>0 ), 'getRadarData'=>array( 'len'=>0 ) ) .... Next, let's create the following methods to acquire data for the various charts: getPieData getBarData getLineData getRadarData First, implement the getPieData method for the pie chart. We'll implement the Direct method to get the data for the pie chart. Please see the actual content for the source code (source file: 04_implement_direct_function/php/classes/ MyAppDashBoard.php ). This is acquiring valid quotation and bill data items. With the data to be sent back to the client, set the array in items and set up the various names and data in a key array. You will now combine the definitions in the next model. Preparing the store for the pie chart Charts need a store, so let's define the store and model (source file: 05_prepare_the_store_for_the_pie_chart/app/model/ Pie.js). We'll create the MyApp.model.Pie class that has the name and data fields. Connect this with the data you set with the return value of the Direct function. If you increased the number of fields inside the model you just defined, make sure to amend the return field values, otherwise it won't be applied to the chart, so be careful. We'll use the model we made in the previous step and implement the store (source file: 05_prepare_the_store_for_the_pie_chart/app/model/ Pie.js). Ext.define('MyApp.store.Pie', { extend: 'Ext.data.Store', storeId: 'DashboardPie', model: 'MyApp.model.Pie', proxy: { type: 'direct', directFn: 'MyAppDashboard.getPieData', reader: { type: 'json', root: 'items' } } }) Then, define the store using the model we made and set up the Direct function we made earlier in the proxy. Creating the View We have now prepared the presentation data. Now, let's quickly create the view to display it (source file: 06_making_the_view/app/view/dashboard/Pie.js). Ext.define('MyApp.view.dashboard.Pie', { extend: 'Ext.panel.Panel', alias : 'widget.myapp-dashboard-pie', title: 'Pie Chart', layout: 'fit', requires: [ 'Ext.chart.Chart', 'MyApp.store.Pie' ], initComponent: function() { var me = this, store; store = Ext.create('MyApp.store.Pie'); Ext.apply(me, { items: [{ xtype: 'chart', store: store, series: [{ type: 'pie', field: 'data', showInLegend: true, label: { field: 'name', display: 'rotate', contrast: true, font: '18px Arial' } }] }] }); me.callParent(arguments); } }); Implementing the controller With the previous code, data is not being read by the store and nothing is being displayed. In the same way that reading was performed with onShow, let's implement the controller (source file: 06_making_the_view/app/controller/DashBoard.js): Ext.define('MyApp.controller.dashboard.DashBoard', { extend: 'MyApp.controller.Abstract', screenName: 'dashboard', init: function() { var me = this; me.control({ 'myapp-dashboard': { 'myapp-show': me.onShow, 'myapp-hide': me.onHide } }); }, onShow: function(p) { p.down('myapp-dashboard-pie chart').store.load(); }, onHide: function() { } }); With the charts we create from now on, as we create them it would be good to add the reading process to onShow. Let's take a look at our pie chart which appears as follows: Summary You must agree this is starting to look like an application! The dashboard is the first screen you see right after logging in. Charts are extremely effective in order to visually check a large and complicated amount of data. If you keep adding panels as and when you feel it's needed, you'll increase its practicability. This sample will become a customizable base for you to use in future projects. Resources for Article: Further resources on this subject: So, what is Ext JS? [Article] Buttons, Menus, and Toolbars in Ext JS [Article] Displaying Data with Grids in Ext JS [Article]
Read more
  • 0
  • 0
  • 1772
Banner background image

article-image-crud-applications-using-laravel-4
Packt
19 Dec 2013
18 min read
Save for later

CRUD Applications using Laravel 4

Packt
19 Dec 2013
18 min read
(for more resources related to this topic, see here.) Getting familiar with Laravel 4 Let's Begin the Journey, and install Laravel 4. Now if everything is installed correctly you will be greeted by this beautiful screen, as shown in the following screenshot, when you hit your browser with http://localhost/laravel/public or http://localhost/<installeddirectory>/public: Now that you can see we have installed Laravel correctly, you would be thinking how can I use Laravel? How do I create apps with Laravel? Or you might be wondering why and how this screen is shown to us? What's behind the scenes? How Laravel 4 sets this screen for us? So let's review that. When you visit the http://localhost/laravel/public, Laravel 4 detects that you are requesting for the default route which is "/". You would be wondering what route is this if you are not familiar with the MVC world. Let me explain that. In traditional web applications we use a URL with page name, say for example: http://www.shop.com/products.php The preceding URL will be bound to the page products.php in the web server hosting shop.com. We can assume that it displays all the products from the database. Now say for example, we want to display a category of books from all the products. You will say, "Hey, it's easy!" Just add the category ID into the URL as follows: http://www.shop.com/products.php?cat=1 Then put the filter in the page products.php that will check whether the category ID is passed. This sounds perfect, but what about pagination and other categories? Soon clients will ask you to change one of your category page layouts to change and you will hack your code more. And your application URLs will look like the following: http://www.shop.com/products.php?cat=2 http://www.shop.com/products.php?cat=3&page=1&total=20 http://www.shop.com/products.php?cat=3&page=1&total=20&layout=1 If you look at your code after six months, you would be looking at one huge products.php page with all of your business and view code mixed in one large file. You wouldn't remember those easy hacks you did in order to manage client requests. On top of that, a client or client's SEO executive might ask you why are all the URLs so badly formatted? Why are they are not human friendly? In a way they are right. Your URLs are not as pretty as the following: http://www.shop.com/products http://www.shop.com/products/books http://www.shop.com/products/cloths The preceding URLs are human friendly. Users can easily change categories themselves. In addition to that, your client's SEO executives will love you for those URLs just as a search engine likes those URLs. You might be puzzled now; how do you do that? Here my friend MVC (Model View Controller) comes into the picture. MVC frameworks are meant specifically for doing this. It's one of the core goals of using the MVC framework in web development. So let's go back to our topic "routing"; routing means decoupling your URL request and assigning it to some specific action via your controller/route. In the Laravel MVC world, you register all your routes in a route file and assign an action to them. All your routes are generally found at /app/routes.php. If you open your newly downloaded Laravel installation's routes.php file, you will notice the following code: Route::get('/', function() { return View::make('hello'); }); The preceding code registers a route with / means default URL with view /app/views/hello.php. Here view is just an .html file. Generally view files are used for managing your presentation logic. So check /app/views/hello.php, or better let's create an about page for our application ourselves. Let's register a route about by adding the following code to app/routes.php: Route::get('about', function() { return View::make('about'); }); We would need to create a view at app/views/about.php. So create the file and insert the following code in to it: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>About my little app</title> </head> <body> <h1>Hello Laravel 4!</h1> <p> Welcome to the Awesomeness! </p> </body> </html> Now head over to your browser and run http://localhost/laravel/public/about. You will be greeted with the following output: Hello Laravel 4! Welcome to the Awesomeness! Isn't it easy? You can define your route and separate the view for each type of request. Now you might be thinking what about Controllers as the term MVC has C for Controllers? And isn't it difficult to create routes and views for each action? What advantage will we have if we use the preceding pattern? Well we found that mapping URLs to a particular action in comparison to the traditional one-file-based method. Well first you are organizing your code way better as you will have actions responding to specific URLs mapped in the route file. Any developer can recognize routes and see what's going on with your code. Developers do not have to check many files to see which files are using which code. Your presentation logic is separated, so if a designer wants to change something, he will know he needs to look at the view folder of your application. Now about Controllers; they allow us to group related actions into a single class. So in a typical MVC project, there will be one user Controller that will be responsible for all user-related actions, such as registering, logging in, editing a profile, and changing the password. Generally routes are used for small applications or creating static pages quickly. Controllers provide more in-depth options to create a group of methods that belong to a specific class related to the application. Here is how we can create Controllers in Laravel 4. Open your app/routes.php file and add following code: Route::get('contact', 'Pages@contact'); The preceding code will register the http://yourapp.com/contact URL in the Pages Controller's contact method. So let's write a page's Controller. Create a file PagesController.php at /app/controllers/ in your Laravel 4 installation directory. The following are the contents of the PagesController.php file: <?php class PagesController extends BaseController { public function contact() { return View::make('hello'); } } Here BaseController is a class provided by Laravel so we can place our Controller shared logic in a common class. And it extends the framework's Controller class and provides the Controller functionality. You can check Basecontroller.php in the Controller's directory to add shared logic. Controllers versus routes So you are wondering now, "What's the difference between Controllers and routes?" Which one to use? Controllers or routes? Here are the differences between Controllers and routes: A disadvantage of routes is that you can't share code between routes, as routes work via Closure functions. And the scope of a function is bound within function. Controllers give a structure to your code. You can define your system in well-grouped classes, which are divided in such a way that it makes sense, for example, users, dashboard, products, and so on. Compared to routes, Controllers have only one disadvantage and it's that you have to create a file for each Controller; however, if you think in terms of organizing the code in a large application, it makes more sense to use Controllers.   Creating a simple CRUD application with Laravel 4 Now as we have a basic understanding of how we can create pages, let's create a simple CRUD application with Laravel 4. The application we want to create will manage the users of our application. We will create the following list of features for our application: List users (read users from the database) Create new users Edit user information Delete user information Adding pagination to the list of users Now to start off with things, we would need to set up a database. So if you have phpMyAdmin installed with your local web server setup, head over to http://localhost/phpmyadmin; if you don't have phpMyAdmin installed, use the MySQL admin tool workbench to connect with your database and create a new database. Now we need to configure Laravel 4 to connect with our database. So head over to your Laravel 4 application folder, open /app/config/database.php, change the MySQL array, and match your current database settings. Here is the MySQL database array from database.php file: 'mysql' => array( 'driver' => 'mysql', 'host' => 'localhost', 'database' => '<yourdbname>', 'username' => 'root', 'password' => '<yourmysqlpassord>', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ), Now we are ready to work with the database in our application. Let's first create the database table Users via the following SQL queries from phpMyAdmin or any MySQL database admin tool; CREATE TABLE IF NOT EXISTS 'users' ( 'id' int(10) unsigned NOT NULL AUTO_INCREMENT, 'username' varchar(255) COLLATE utf8_unicode_ci NOT NULL, 'password' varchar(255) COLLATE utf8_unicode_ci NOT NULL, 'email' varchar(255) COLLATE utf8_unicode_ci NOT NULL, 'phone' varchar(255) COLLATE utf8_unicode_ci NOT NULL, 'name' varchar(255) COLLATE utf8_unicode_ci NOT NULL, 'created_at' timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 'updated_at' timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY ('id') ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ; Now let's seed some data into the Users table so when we fetch the users we won't get empty results. Run the following queries into your database admin tool: INSERT INTO 'users' ('id', 'username', 'password', 'email', 'phone', 'name', 'created_at', 'updated_at') VALUES (1, 'john', 'johndoe', '[email protected]', '123456', 'John', '2013-06-07 08:13:28', '2013-06-07 08:13:28'), (2, 'amy', 'amy.deg', '[email protected]', '1234567', 'amy', '2013-06-07 08:14:49', '2013-06-07 08:14:49');   Listing the users – read users from database Let's read users from the database. We would need to follow the steps described to read users from database: A route that will lead to our page A controller that will handle our method The Eloquent Model that will connect to the database A view that will display our records in the template So let's create our route at /app/routes.php. Add the following line to the routes.php file: Route::resource('users', 'UserController'); If you have noticed previously, we had Route::get for displaying our page Controller. But now we are using resource. So what's the difference? In general we face two types of requests during web projects: GET and POST. We generally use these HTTP request types to manipulate our pages, that is, you will check whether the page has any POST variables set; if not, you will display the user form to enter data. As a user submits the form, it will send a POST request as we generally define the <form method="post"> tag in our pages. Now based on page's request type, we set the code to perform actions such as inserting user data into our database or filtering records. What Laravel provides us is that we can simply tap into either a GET or POST request via routes and send it to the appropriate method. Here is an example for that: Route::get('/register', 'UserController@showUserRegistration'); Route::post('/register', 'UserController@saveUser'); See the difference here is we are registering the same URL, /register, but we are defining its GET method so Laravel can call UserController class' showUserRegistration method. If it's the POST method, Laravel should call the saveUser method of the UserController class. You might be wondering what's the benefit of it? Well six months later if you want to know how something's happening in your app, you can just check out the routes.php file and guess which Controller and which method of Controller handles the part you are interested in, developing it further or solving some bug. Even some other developer who is not used to your project will be able to understand how things work and can easily help move your project. This is because he would be able to somewhat understand the structure of your application by checking routes.php. Now imagine the routes you will need for editing, deleting, or displaying a user. Resource Controller will save you from this trouble. A single line of route will map multiple restful actions with our resource Controller. It will automatically map the following actions with HTTP verbs: HTTP VERB ACTION GET READ POST CREATE PUT UPDATE DELETE DELETE On top of that you can actually generate your Controller via a simple command-line artisan using the following command: $ php artisan Usercontroller:make users This will generate UsersController.php with all the RESTful empty methods, so you will have an empty structure to play with. Here is what we will have after the preceding command: class UserController extends BaseController { /** * Display a listing of the resource. * * @return Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return Response */ public function create() { // } /** * Store a newly created resource in storage. * * @return Response */ public function store() { // } /** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param int $id * @return Response */ public function update($id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return Response */ public function destroy($id) { // } } Now let's try to understand what our single line route declaration created relationship with our generated Controller. HTTP VERB Path Controller Action/method GET /Users Index GET /Users/create Create POST /Users Store GET /Users/{id} Show (individual record) GET /Users/{id}/edit Edit PUT /Users/{id} Update DELETE /Users/{id} Destroy As you can see, resource Controller really makes your work easy. You don't have to create lots of routes. Also Laravel 4's artisan-command-line generator can generate resourceful Controllers, so you will write very less boilerplate code. And you can also use the following command to view the list of all the routes in your project from the root of your project, launching command line: $ php artisan routes Now let's get back to our basic task, that is, reading users. Well now we know that we have UserController.php at /app/controller with the index method, which will be executed when somebody launches http://localhost/laravel/public/users. So let's edit the Controller file to fetch data from the database. Well as you might remember, we will need a Model to do that. But how do we define one and what's the use of Models? You might be wondering, can't we just run the queries? Well Laravel does support queries through the DB class, but Laravel also has Eloquent that gives us our table as a database object, and what's great about object is that we can play around with its methods. So let's create a Model. If you check your path /app/models/User.php, you will already have a user Model defined. It's there because Laravel provides us with some basic user authentication. Generally you can create your Model using the following code: class User extends Eloquent {} Now in your controller you can fetch the user object using the following code: $users = User::all(); $users->toarray(); Yeah! It's that simple. No database connection! No queries! Isn't it magic? It's the simplicity of Eloquent objects that many people like in Laravel. But you have the following questions, right? How does Model know which table to fetch? How does Controller know what is a user? How does the fetching of user records work? We don't have all the methods in the User class, so how did it work? Well models in Laravel use a lowercase, plural name of the class as the table name unless another name is explicitly specified. So in our case, User was converted to a lowercase user and used as a table to bind with the User class. Models are automatically loaded by Laravel, so you don't have to include the reference of the Model file. Each Model inherits an Eloquent instance that resolves methods defined in the model.php file at vendor/Laravel/framework/src/Illumininate/Database/Eloquent/ like all, insert, update, delete and our user class inherit those methods and as a result of this, we can fetch records via User::all(). So now let's try to fetch users from our database via the Eloquent object. I am updating the index method in our app/controllers/UsersController.php as it's the method responsible as per the REST convention we are using via resource Controller. public function index() { $users = User::all(); return View::make('users.index', compact('users')); } Now let's look at the View part. Before that, we need to know about Blade. Blade is a templating engine provided by Laravel. Blade has a very simple syntax, and you can determine most of the Blade expressions within your view files as they begin with @. To print anything with Blade, you can use the {{ $var }} syntax. Its PHP-equivalent syntax would be: <?php echo $var; ?> Now back to our view; first of all, we need to create a view file at /app/views/users/index.blade.php, as our statement would return the view file from users.index. We are passing a compact users array to this view. So here is our index.blade.php file: @section('main') <h1>All Users</h1> <p>{{ link_to_route('users.create', 'Add new user') }}</p> @if ($users->count()) <table class="table table-striped table-bordered"> <thead> <tr> <th>Username</th> <th>Password</th> <th>Email</th> <th>Phone</th> <th>Name</th> </tr> </thead> <tbody> @foreach ($users as $user) <tr> <td>{{ $user->username }}</td> <td>{{ $user->password }}</td> <td>{{ $user->email }}</td> <td>{{ $user->phone }}</td> <td>{{ $user->name }}</td> <td>{{ link_to_route('users.edit', 'Edit', array($user->id), array('class' => 'btn btn-info')) }}</td> <td> {{ Form::open(array('method' => 'DELETE', 'route' => array('users.destroy', $user->id))) }} {{ Form::submit('Delete', array('class' => 'btn btn-danger')) }} {{ Form::close() }} </td> </tr> @endforeach </tbody> </table> @else There are no users @endif @stop Let's see the code line by line. In the first line we are extending the user layouts via the Blade template syntax @extends. What actually happens here is that Laravel will load the layout file at /app/views/layouts/user.blade.php first. Here is our user.blade.php file's code: <!doctype html> <html> <head> <meta charset="utf-8"> <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"> <style> table form { margin-bottom: 0; } form ul { margin-left: 0; list-style: none; } .error { color: red; font-style: italic; } body { padding-top: 20px; } </style> </head> <body> <div class="container"> @if (Session::has('message')) <div class="flash alert"> <p>{{ Session::get('message') }}</p> </div> @endif @yield('main') </div> </body> </html> Now in this file we are loading the Twitter bootstrap framework for styling our page, and via yield('main') we can load the main section from the view that is loaded. So here when we load http://localhost/laravel/public/users, Laravel will first load the users.blade.php layout view and then the main section will be loaded from index.blade.php. Now when we get back to our index.blade.php, we have the main section defined as @section('main'), which will be used by Laravel to load it into our layout file. This section will be merged into the layout file where we have put the @yield ('main') section. We are using Laravel's link_to_route method to link to our route, that is, /users/create. This helper will generate an HTML link with the correct URL. In the next step, we are looping through all the user records and displaying it simply in a tabular format. Now if you have followed everything, you will be greeted by the following screen:
Read more
  • 0
  • 0
  • 8844

article-image-background-animation
Packt
19 Dec 2013
4 min read
Save for later

Background Animation

Packt
19 Dec 2013
4 min read
(For more resources related to this topic, see here.) Background-color animation Animating the background color of an element is a great way to draw our user's eyes to the object we want them to see. Another use for animating the background color of an element is to show that something has happened to the element. It's typically used in this way if the state of the object changes (added, moved, deleted, and so on), or if it requires attention to fix a problem. Due to the lack of support in jQuery 2.0 for animating background-color, we'll be using jQuery UI to give us the functionality we need to create this effect. Introducing the animate method The animate() method is one of the most useful methods jQuery has to offer in its bag of tricks in the animation realm. With it, we’re able to do things like, move an element across the page or alter and animating the properties of colors, backgrounds, text, fonts, the box model, position, display, lists, tables, generated content, and so on. Time for action – animating the body background-color Following the steps below, we're going to start by creating an example that changes the body background color. Start by creating a new file (using our template) called background-color.html and save it in our jquery-animation folder. Next, we'll need to include the jQuery UI library by adding this line directly under our jQuery library by adding this line: <script src = "js/jquery-ui.min.js"></script> A custom or stable build of jQuery UI can be downloaded from http://jqueryui.com, or you can link to the library using one of the three Content Delivery Networks (CDN) below. For fastest access to the library, go to http://jqueryui.com, scroll to the very bottom and look for the Quick Access section. Using the jQuery UI library JS file there will work just fine for our needs for the examples in this article. Media Template: http://code.jquery.com Google: http://developers.google.com/speed/libraries/devguide#jquery-ui Microsoft: http://asp.net/ajaxlibrary/cdn.ashx#jQuery_Releases_on_the_CDN_0 CDNJS: http://cdnjs.com/libraries/jquery Then, we'll add the following jQuery code to the anonymous function: var speed = 1500; $( "body").animate({ backgroundColor: "#D68A85" },speed); $( "body").animate({ backgroundColor: "#E7912D" },speed); $( "body").animate({ backgroundColor: "#CECC33" },speed); $( "body").animate({ backgroundColor: "#6FCD94" },speed); $( "body").animate({ backgroundColor: "#3AB6F1" },speed); $( "body").animate({ backgroundColor: "#8684D8" },speed); $( "body").animate({ backgroundColor: "#DD67AE" },speed); What just happened? First we added in the jQuery UI library to our page. This was needed because of the lack of support for animating the background color in the current version of jQuery. Next, we added in the code that will animate our background. We then set the speed variable to 1500 (milliseconds) so that we can control the duration of our animation. Lastly, using the animate() method, we set the background color of the body element and set duration to the variable we set above named speed. We duplicated the same line several times, changing only the hexadecimal value of the background color. The following screenshot is an illustration of colors the entire body background color animates through: Chaining together jQuery methods It's important to note that jQuery methods (animate() in this case) can be chained together. Our code mentioned previously would look like the following if we chained the animate() methods together: $("body")   .animate({ backgroundColor: "#D68A85"}, speed)  //red   .animate({ backgroundColor: "#E7912D"}, speed)  //orange   .animate({ backgroundColor: "#CECC33"}, speed)  //yellow   .animate({ backgroundColor: "#6FCD94"}, speed)  //green   .animate({ backgroundColor: "#3AB6F1"}, speed)  //blue   .animate({ backgroundColor: "#8684D8"}, speed)  //purple   .animate({ backgroundColor: "#DD67AE"}, speed); //pink Here's another example of chaining methods together: (selector).animate(properties).animate(properties).animate(properties) Have a go hero – extending our script with a loop In this example we used the animate() method and with some help from jQuery UI, we were able to animate the body background color of our page. Have a go at extending the script to use a loop, so that the colors continually animate without stopping once the script gets to the end of the function. Pop quiz – chaining with the animate() method Q1. Which code will properly animate our body background color from red to blue using chaining? $("body")   .animate({ background: "red"}, "fast")   .animate({ background: "blue"}, "fast"); $("body")   .animate({ background-color: "red"}, "slow")   .animate({ background-color: "blue"}, "slow"); $("body")   .animate({ backgroundColor:"red" })   .animate({ backgroundColor:"blue" }); $("body")   .animate({ backgroundColor,"red" }, "slow")   .animate({ backgroundColor,"blue" }, "slow");
Read more
  • 0
  • 0
  • 1879

article-image-code-editing
Packt
18 Dec 2013
9 min read
Save for later

Code Editing

Packt
18 Dec 2013
9 min read
(For more resources related to this topic, see here.) Discovering Search and Replace Search and Replace is one of the common actions we use in every editor, sublime text has two main search features: Single file Multiple files Before covering these topics, let's talk about the best tool available for searching text and especially, patterns, namely, Regular Expressions. Regular Expressions Regular Expressions can find complex patterns in text. To take full advantage of the Search and Replace features of Sublime, you should at least know the basics of Regular Expressions, also known as regex or regexp. Regular Expressions can be really annoying, painful, and joyful at the same time! We won't cover Regular Expressions in this article because it's an endless topic. We will only note that Sublime Text uses the Boost's Perl Syntax for Regular Expressions; this can be found at http://www.boost.org/doc/libs/1_47_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html I recommend going to http://www.regular-expressions.info/quickstart.html if you are not familiar with Regular Expressions. Search and Replace – a single file Let's open the Search panel by pressing Ctrl + F on Windows and Linux or command + F on OS X. The search panel options can be controlled using keyboard shortcuts: Search panel Options Windows/Linux OS X Toggle Regular Expressions Alt + R command + Option + R Toggle Case Sensitivity Alt + C command + Option + C Toggle Exact Match Alt + W command + Option + W Find Next Enter Enter Find Previous Shift + Enter Shift + Enter Find All Alt + Enter Option + Enter As we can see in the following screenshot, we have the Regular Expression option turned on: Let's try Search and Replace now by pressing Ctrl + H on Windows and Linux or Option + command + F on OS X and examining the following screenshot: We can see that this time, both, the Regular Expression option and the Case Sensitivity option are turned on. Because of the Case Sensitivity option being on, line 8 isn't selected, the pattern messages/(d) doesn't match line 2 because d only matches numbers, and the 1 on the Replace with field will replace match group number 1, indicated by the parentheses around d. We can also refer to the group by using $1 instead of 1. Let's see what happens after we press Ctrl + Alt + Enter for Replace All: We can see that lines 2 and 8 still say messages and not message; that's exactly what we expected! The incremental search Incremental search is another cool feature that is here to save us keyboard clicks. We can bring up the incremental search panel by pressing Ctrl + I on Windows and Linux or command + I on OS X. The only difference between the incremental search and a regular search is the behavior of the Enter key; in incremental searches, the Enter key will select the next match and dismiss the search panel. This saves us from pressing Esc to dismiss the regular search panel. Search and Replace – multiple files Sublime Text also allows a multiple file search by pressing Ctrl + Shift + F or command + Shift + F on OS X. The same shortcuts from the single file search also apply here; the difference is that we have the Where field and a … button near it. The Where field determines where the files can be searched for; we can define the scope of the search in several ways: Adding individual directories (Unix-style paths, even on Windows( Adding/excluding files based on the wildcard pattern Adding Sublime-symbolic locations such as <open folders>, <open files> We can also combine all the filters by separating them with commas. We can do it in the following manner: /C/Users/Dan/Cool Project,*.rb,<open files> This will look in all files in C:UsersDanCool Project that ends with .rb and are currently open by Sublime. Results will be opened in a new tab called Find Results containing all found results separated by file paths, double clicking on a result will get you to the exact location of the result in the original file. Mastering Column and Multiple Selection Multiple Selections is one of Sublime's coolest features; TextMate users might be familiar with it. So how can we select multiple lines? We select one line like we usually do and selecting the second line while holding Ctrl or command on OS X. We can also subtract a line by holding the Alt key or command + Shift keys on OS X. This feature is really useful so it is recommended to play with it, the following are some shortcuts that can help us feel more comfortable with multiple selections: Multiple Selection action Windows/Linux OS X Return to Single Selection Mode Esc Esc Undo last selection motion Ctrl + U command + U Add next occurrence of selected text to selection Ctrl + D command + D Add all occurrences of selected text to selection Alt + F3 Control + command + G Turn Single Linear Selection into Block Selection Ctrl + Shift + L Shift + command + L Column Selection The Column Selection feature is one of my favorites! We can select multiple lines by pressing Shift and dragging the right mouse button on Windows or Linux and pressing Option and dragging the left mouse button on OS X. Here we want to remove the letter s from messages, as shown in the following screenshot: We have selected all s using Column selection; now we just need to hit backspace to delete them. Navigating through everything Sublime is known for its ability to quickly move between and around files and lines. Here, we are going to master how to navigate our code quickly and easily. Going To Anything We already learned how to use the Go To Anything feature, but it can do more than just searching for filenames. We can conduct a fuzzy search inside a "fuzzily found" file. Really? Yeah, we can. For example, we can type the following inside the Go To Anything window: isl#wld This will make Sublime perform a fuzzy search for wld inside the file that we found by fuzzy searching isl; it can thus find the word world inside a file named island. We can also perform a fuzzy search in the current file by pressing Ctrl + ; in Windows or Linux and command + P, # in OS X. It is very common to use fuzzy search inside HTML files because it will immediately show all the elements and classes in order to accelerate navigation. Symbol search Sometimes we want to search for a specific function or specific class inside the current file. With Sublime we can do it simply by pressing Ctrl + R on Windows or Linux and command + R on OS X. Projects Project is a group of files and folders. To save a project we just need to add folders and files to the sidebar, and then from the menu, we navigate to Project | Save Project As… The saved file is our projects data, and it is stored in a JSON formatted file with a .sublime-project extension. The following is a sample project file: {     "folders":     [         {             "path":"src",             "follow_symlinks":true         },         {             "path":"docs",             "name":"Documentation",       "file_exclude_patterns":["*.xml"]         }     ],     "settings":     {         "tab_size":6     },     "build_systems":     [         {             "name":"List",             "shell_cmd":"ls -l"         }     ] } As we can see in the preceding code, there are three elements written as JSON arrays. Folders Each folder must have a valid folder path that can be absolute or relative to the project directory, which is where the project file is. A folder can also include the following keys: name: This is the name that will be shown on the sidebar file_execlude_pattern: This is the folder that will exclude all the files matching the given Regular Expression file_include_pattern: This is the folder that will include only files matching the given Regular Expression folder_execlude_pattern: This is the folder that will exclude all subfolders matching the given Regular Expression folder_include_pattern: This is the folder that will include only subfolders matching the given Regular Expression follow_symlinks: This will include symlinks if set to true Settings The project-specific settings array will contain all the settings that we want to apply only on this project. These settings will override our user settings. Build systems In an array of build system definitions, we must specify a name for each definition; these build systems will then be specified in Tools | Build Systems. For more information about build systems, please visit http://sublimetext.info/docs/en/reference/build_systems.html. Navigating between projects To switch between projects quickly, we can press Ctrl + Alt + P in Windows or Linux and Control + command + P in OS X. Summary By now, we have learned some of Sublime's basic features to the most advanced features and techniques that need to be used while editing code. Resources for Article: Further resources on this subject: Top features you need to know about [Article] Setting up environment for Cucumber BDD Rails [Article] Implementation of SASS [Article]
Read more
  • 0
  • 0
  • 4037
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €14.99/month. Cancel anytime
article-image-enabling-your-new-theme-magento
Packt
18 Dec 2013
3 min read
Save for later

Enabling your new theme in Magento

Packt
18 Dec 2013
3 min read
(For more resources related to this topic, see here.) After your new theme is in place, you can enable it in Magento. Log in to your Magento store's administration panel. Once you have logged in, navigate to System | Configuration, as shown in the following screenshot: From there, select the global configuration scope (labeled Default Config in the following screenshot) you want to apply your new theme to, from the Current Configuration Scope dropdown in the top left of your screen: Once this has loaded, navigate to the Design tab under GENERAL in the left-hand column and expand the Themes block in the right-hand column, as shown in the following screenshot: From here, you can tell Magento to use your new theme. The values given here correspond to the name you gave to the directories when creating your theme. The example uses responsive as the value here, as shown in the following screenshot: Click on the Save Config button at the top right of your screen to save the changes. Next, check that your new theme has been activated. Remember the styles.css file you added in the skin/frontend/default/responsive/css directory? The presence of that file is telling Magento to load your new theme's CSS file instead of the default styles.css file for Magento from the default package, so your store now has none of the original CSS styling it. As such, you should see the following screenshot when you attempt to view the frontend of your Magento store: Overwriting the default Magento templates Noticed the name of your Magento theme appearing next to the logo in the header of your store? You can overwrite the default header.phtml that's causing it by copying the contents of app/design/frontend/base/default/template/page/html/header.phtml into app/design/frontend/default/responsive/template/ page/html/header.phtml. Open the file and find the following lines: <?php if ($this->getIsHomePage()):?> <h1 class="logo"><strong><?php echo $this->getLogoAlt() ?></strong><a href="<?php echo $this->getUrl('') ?>" title= "<?php echo $this->getLogoAlt() ?>" class="logo"><img src = "<?php echo $this->getLogoSrc() ?>" alt="<?php echo $this->getLogoAlt() ?>" /></a></h1> <?php else:?> <a href="<?php echo $this->getUrl('') ?>" title="<?php echo $this->getLogoAlt() ?>" class="logo"><strong><?php echo $this->getLogoAlt() ?></strong><img src = "<?php echo $this->getLogoSrc() ?>" alt="<?php echo $this->getLogoAlt() ?>" /></a> <?php endif?> Replace them with these lines: <a href="<?php echo $this->getUrl('') ?>" title="<?php echo $this- >getLogoAlt() ?>" class="logo"><img src = "<?php echo $this-> getLogoSrc() ?>" alt="<?php echo $this->getLogoAlt() ?>" /></a> Now if you save that file (and upload it to your server, if needed), you can see that the logo now looks tidier, as shown in the following screenshot: That's it! Your basic responsive Magento theme is up and running. Summary Hopefully after reading this article you will get a better understanding of how to enable your new theme in Magento. Resources for Article: Further resources on this subject: Magento : Payment and shipping method [Article] Categories and Attributes in Magento: Part 2 [Article] Magento: Exploring Themes [Article]
Read more
  • 0
  • 0
  • 2277

article-image-magic
Packt
16 Dec 2013
7 min read
Save for later

The Magic

Packt
16 Dec 2013
7 min read
(For more resources related to this topic, see here.) Application flow In the following diagram, from the Angular manual, you find a comprehensive schematic depiction of the program flow inside Angular: After the browser loads the HTML and parses it into a DOM, the angular.js script file is loaded. This can be added before or at the bottom of the <body> tag, although adding it at the bottom is preferred. Angular waits for the browser to fire the DOMContentLoaded event. This is similar to the way jQuery is bootstrapped, as illustrated in the following code: $(document).ready(function(){ // do jQuery }) In the Angular.js file, towards the end, after the entire code has been parsed by the browser, you will find the following code: jqLite(document).ready(function() { angularInit(document, bootstrap); }); The preceding code calls the function that looks for various flavors of the ng-app directive that you can use to bootstrap your Angular application. ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'] Typically, the ng-app directive will be the HTML tag, but in theory, it could be any tag as long as there is only one of them. The module specification is optional and can tell the $injector service which of the defined modules to load. //index.html <!doctype html> <html lang="en" ng-app="tempApp"> <head> …... // app.js ….. angular.module('tempApp', ['serviceModule']) ….. In turn, the $injector service will create $rootscope, the parent scope of all Angular scopes, as the name suggests. This $rootscope is linked to DOM itself as a parent to all other Angular scopes. The $injector service will also create the $compile service that will traverse the DOM and look for directives. These directives are searched for within the complete list of declared Angular internal directives and custom directives at hand. This way, it can recognize directives declared as an element, as attributes, inside the class definition, or as a comment. Now that Angular is properly Bootstrapped, we can actually start executing some application code. This can be done in a variety of ways, shown as follows: In the initial examples, we started creating some Angular code with curly braces using some built-in Angular functions It is also possible to define a controller to control a specific part of the HTML page, as we have shown in the first tempCtrl code snippet We have also shown you how to use Angular's built-in router to manage your application using client-side routing As you can see, Angular extends the capabilities of HTML by providing a clever way to add new directives. The key ingredient here is the $injector service, which provides a way to look up for dependencies and create $rootscope. Different ways of injecting Let's look a bit more at how $injector does its work. Throughout all the examples in this book, we have used the array-style notation to define our controllers, modules, services, and directives. // app/ controllers.js tempApp.controller('CurrentCtrl', ['$scope', 'reading', function ($scope, reading) { $scope.temp = 17; ... This style is commonly referred to as annotation. Each injected value is annotated in the same order inside an array. You may have looked through the AngularJs website and may have seen different ways of defining functions. // angularJs home page JavaScript Projects example functionListCtrl($scope, Project) { $scope.projects = Project.query(); } So, what is the difference and why are we using another way of defining functions? The first difference you may notice is the definition of all the functions in the global scope. For reference, let's call this the simple injection method. The documentation states that this is a concise notation that really is only suited for demo applications because it is nothing but a potential clash waiting to happen. Any other JS library or framework you may have included could potentially have a function with the same name and cause your software to malfunction by executing this function instead of yours. After assigning the Angular module to a variable such as tempApp, we will chain the methods to that variable like we have done in this book so far; you could also just chain them directly as follows: angular.module('tempApp').controller('CurrentCtrl', function($scope) {}) These are essentially the same definitions and don't cause pollution in the global scope. The second difference that you may have noticed is in the way the dependencies are injected in the function. At the time of writing this book, most, if not all of the examples on the AngularJs website use the simple injection method. The dependencies are just parameters in the function definitions. Magically, Angular is able to figure out which parameter is what by the name because the order does not matter. So the preceding example could be rewritten as follows, and it would still function correctly: // reversedangularJs home page JavaScript Projects example functionListCtrl( Project, Scope ) { $scope.projects = Project.query(); } This is not a feature of the JavaScript language, so it must have been added by those smart Angular engineers. The magic behind this can be found in the injector. The parameters of the function are scanned, and Angular extracts the names of the parameters to be able to resolve them. The problem with this approach is that when you deploy a wonderful new application to production, it will probably be minified and even obfuscated. This will rename $scope and Project to something like a and b. Even Angular will then be unable to resolve the dependencies. There are two ways to solve this problem in Angular. You have seen one of them already, but we will explain it further. You can wrap the function in an array and type the names of the dependencies as strings before the function definition in the order in which you supplied them as arguments to the function. // app/ controllers.js tempApp.controller('CurrentCtrl', ['$scope', 'reading', function ($scope, reading) { $scope.temp = 17; ....... The corresponding order of the strings and the function arguments is significant here. Also, the strings should appear before the function arguments. If you prefer the definition without the array notation, there is still some hope. Angular provides a way to inform the injector service of the dependencies you are trying to inject. varCurrentCtrl = function($scope, reading) { $scope.temp = 17; $scope.save = function() { reading.save($scope.temp); } }; CurrentCtrl.$inject = ['$scope', 'reading']; tempApp.controller('CurrentCtrl', CurrentCtrl); As you can see, the definition is a bit more sizable, but essentially the same thing is happening here. The injector is informed by filling the $inject property of the function with an array of the injected dependencies. This is where Angular will then pick them up from. To understand how Angular accomplishes all of this, you should read this excellent blog post by Alex Rothenberg. Here, he explains how all of this works internally. The link to his blog is as follows: http://www.alexrothenberg.com/2013/02/11/the-magic-behind-angularjs-dependency-injection.html. Angular cleverly uses the toString() function of objects to be able to examine in which order the arguments were specified and what their names are. There is actually a third way to specify dependencies called ngmin, which is not native to Angular. It lets you use the simple injection method and parses and translates it to avoid minification problems. https://github.com/btford/ngmin Consider the following code: angular.module('whatever').controller('MyCtrl', function ($scope, $http) { ... }); ngmin will turn the preceding code into the following: angular.module('whatever').controller('MyCtrl', ['$scope','$http', function ($scope, $http) { ... }]);   Summary In this article, we started by looking at how AngularJS is bootstrapped. Then, we looked at how the injector works and why minification might ruin your plans there. We also saw that there are ways to avoid these problems by specifying dependencies differently. Resources for Article: Further resources on this subject: The Need for Directives [Article] Understanding Backbone [Article] Quick start – creating your first template [Article]
Read more
  • 0
  • 0
  • 2391

article-image-bootstrap-30-mobile-first
Packt
16 Dec 2013
10 min read
Save for later

Bootstrap 3.0 is Mobile First

Packt
16 Dec 2013
10 min read
(For more resources related to this topic, see here.) But why Mobile First? Why did Bootstrap completely change its course from Desktop First to Mobile First to get into this new way to develop more suitable websites and web applications? Why did the most popular frontend framework embrace this change at a time when responsive web design is continuously growing with better suited and standard techniques such as media-queries, fluid layout, and JavaScript on demand? Mobile browsers are increasing support for the brand new HTML5 and CSS3, with the philosophy to offer, for older browsers, a less stylized but fully functional component, and for capable browsers a rich and full experience that comes from mobiles to larger screens such as TVs. For older browsers (such as IE 8 and IE 9), Bootstrap has functional support, but enhanced features such as rounded corners and a placeholder attribute for tips in input fields are not supported for these browsers. To see the full details on browser support, check the Bootstrap documentation from the Getting started section (http://getbootstrap.com/getting-started/#browsers). We are living at a time when mobile use is increasing at a pace that will soon surpass desktop usage (http://www.businessinsider.com/mobile-will-eclipsedesktop-by-2014-2012-6). Apart from the statistics, one thing we can presume is that the web scenario is changing so fast that we have to embrace the certainty of devices getting better and smarter. In this article, we will explore the main changes in Bootstrap 3. If you are already familiar with Bootstrap 2, check the migration guide (http://getbootstrap.com/getting-started/#migration) to have a practical overview about what has changed. If you're not familiar with Bootstrap, there's nothing that's too difficult for you to understand directly from this article about this new version. The only thing you need to have in mind is the Mobile First approach, which is covered well in this article. You will be guided to design with Mobile First, discover why Mobile First is so important, and how to make Bootstrap a powerful frontend platform to make your site friendly for a wider range of devices. We can take a step further and add to your previous Bootstrap knowledge by thinking of a concrete way to design processes as a continuous layer of capabilities and embrace the constraints and not fight with them. Mobile First with Bootstrap is an elegant solution for frontend development. Combined with server-side techniques, we get a full bag of solutions to get your product better suited to different users and needs in different platforms. This article will cover the following topics: Bootstrap reviewed Desktop to responsive   Bootstrap reviewed In the third era of Bootstrap that is coming, the developers have redesigned the whole framework with a different approach. Let's get started building interface components of small and simple screens, instead of adapting the existent UI components to fit in a constrained environment. From mobile, we will then go to desktop. However, we will not adapt the experience as we usually do with responsive design going from desktop to mobile. Now with Mobile First we will enhance accordingly as we increase the device screens. Why should I do this if my target audience will be using desktops? Going to mobile indirectly benefits desktop users. But how? To better understand this, let's recap Bootstrap history for a while. In 2011, Bootstrap was launched to serve as a live and agnostic style guide that was used by Twitter to create their products. It became an open source framework at that time. It was a time when we worked in pixel-perfect layouts and explored CSS3 animations, and we found in Bootstrap a well-documented and standardized set of features. Bootstrap creates a new design for the browsers because you don't need to define basic interface elements from scratch, such as buttons. At the same time, you have utility elements like badges to cover the most common interface elements. Bootstrap does what a framework is supposed to do: Bootstrapping! The term means the act of taking off a new project; it's like saying, "give me the tools that I will need to start developing my application for different needs". Bootstrap is a toolkit belt with standard conventions from well-defined classes with clean and practical documentation to live code that is ready to use and be customized for your needs. It's not a magic solution to solve the interface element reuse issue, but it's a kick-start. It fits in so many scenarios that developers are increasing its use with their own tools. "CSS moved beyond type, forms and grids. People get tired to create the same stuffs"— Mark Otto, one of Bootstrap's creators, in the Desktop First to Mobile First Bootstrap presentation (https://speakerdeck.com/mdo/desktop-firstto- with-bootstrap) A must-have from this breeding ground of possibilities is the Bootstrap extension font-awesome (http://fortawesome.github.io/Font-Awesome/). It uses font-face, which is widely supported and flexible, instead of sprites for icons. With a single CSS file and font resources used to render the custom fonts, you have a tool that can handle all your icons. This shows the flexibility of Bootstrap tools; for example, font-awesome is independent, works as a standalone project, and is a great fit with Bootstrap. There are a lot of ways to use Bootstrap. You can customize and extend components, from editing the source code in LESS variables or customize via the Bootstrap download page (http://getbootstrap.com/customize/). At the time of this writing, Bootstrap is the most popular project on Github, so it's just one more reason to consider its importance. There's now an official Bootstrap Expo (http://expo.getbootstrap.com/). This is one of the changes in this new version. Bootstrap Expo is the official directory for websites and web applications that are being developed using this framework. A lot of developers get their first touch with the capabilities of HTML5 and CSS3 with this framework. Bootstrap has amazing capabilities such as offering a responsive grid, dozens of JavaScript components, and a customizer in a web interface or through the LESS variables, if you're an experienced developer. It's suitable for any level of developer and designers because it has solutions that suit both scenarios. This is the second of Bootstrap's main philosophies—it's made for everyone. Desktop to responsive With the rise of smart phones, there is a need for responsive content to cover the growing demand. It's possible to add an optional file with media queries and a bunch of CSS code and be adapted to mobile needs. Media queries, a CSS3 module introduced in June 2012, is a basic structure that gives a namespace with a bunch of CSS rules and declarations according to the user resolution, density, and screen capabilities. So, with CSS files, it is possible to manage the ongoing rise of smartphones. It was possible with just one stylesheet file with good support to adapt according with the device and make a website mobile friendly. In Bootstrap Version 2, we used to have an optional file (responsive.less) that used to have all the media queries necessary for Bootstrap to work well with mobiles. Another good news is that we can adapt to tablets as a bonus. We have breakpoints for the most common mobile resolutions—this means we have a range of width (768 px to 979 px) that can represent tablet devices. A breakpoint is the extreme point (minimum and/or maximum) where you can define CSS rules specific to that range and change your layout. This could be achieved with a simple declaration of media queries in your CSS: @media (min-width: 768px) and (max-width: 979px) { ... } But sometimes it's indispensable to rethink some elements—some of those already developed only for desktops—in a pixel-perfect scenario. There's no flexibility in a pixel-width accommodation. No matter how much the screen is different, the website will behave like you were using a desktop when we work with fixed units. This is when we can use a bunch of media queries to get more flexible. Even with this solution, redefining dimensions and CSS rules according to the device using media queries will solve screen flexibility issues but not solve performance issues on mobiles. Performance is one of the main concerns when we go mobile. We have to consider scenarios where the Internet connection is slow and it is a recurrent issue. You will have to perform reverse engineering to make your JavaScript optimize loading, and combine it with server-side solutions. A worse solution would be to just hide content after considering what could be painful for your page load; for example, images have a deep impact on the final performance. Lower page response time is equivalent to more money spent, as we can see in this article about page loading versus user patience (http://blog.kissmetrics.com/loading-time/). One of the curious things this research points to is that mobile Internet users expect their browsing experience in phones to be comparable to what they get on their desktops. We are living at a time when the Web is filled with rich content and we have faster Internet connections. We have to be prepared to offer the closest thing to a fast and optimized loading, at least for our most important content. This does not involve just the use of CSS to hide content and show content depending on the device, as we can do using media queries. It's all about keeping the concepts simple and focused and developing each interface component thoughtfully from scratch—the primary use, with the constraints and its enhanced capabilities. It's not just about adapting, it's exploring the device's capabilities and delivering the best user experience across platforms. Sounds familiar? Yes, for sure, the same concept as progressive enhancement, you might think. You're not wrong. Progressive enhancement was a term widely used at a time when we talked about HTML page dependency on JavaScript to be functional. Progressive enhancement is a strategy for web design that relies on semantic markup and technologies such as JavaScript. Nowadays, progressive enhancement is a longer term for Mobile First because it's not just about JavaScript disabled, as it was vastly talked before. A hundred of articles tried to show its benefits in a no JavaScript environment scenarios. Now progressive enhancement is about to be faster (http://coding.smashingmagazine.com/2013/09/03/progressive-enhancement-is-faster/). Progressive enhancement is one of the three keys of Mobile First, together with responsive design and giving priority to content over navigation. So, these three rationales are at the background of all the details of Bootstrap 3, from your CSS components to your grid structure. Summary In this article we saw the Twitter Bootstrap's latest version Mobile First. We also saw how developers developed this framework. The growing world of smartphones have forced for the need for Mobile First. Resources for Article: Further resources on this subject: Downloading and setting up Bootstrap [Article] Introduction to RWD frameworks [Article] Getting started with using Chef [Article]
Read more
  • 0
  • 29
  • 6846

article-image-handling-authentication
Packt
13 Dec 2013
9 min read
Save for later

Handling Authentication

Packt
13 Dec 2013
9 min read
(for more resources related to this topic, see here.) Understanding Authentication methods In a world where security on the Internet is such a big issue, the need for great authentication methods is something that cannot be missed. Therefore, Zend Framework 2 provides a range of authentication methods that suits everyone's needs. Getting ready To make full use of this, I recommend a working Zend Framework 2 skeleton application to be set up. How to do it… The following is a list of authentication methods—or as they are called adapters—that are readily available in Zend Framework 2. We will provide a small overview of the adapter, and instructions on how you can use it. The DbTable adapter Constructing a DbTable adapter is pretty easy, if we take a look at the following constructor: public function __construct( // The ZendDbAdapterAdapter DbAdapter $zendDb, // The table table name to query on $tableName = null, // The column that serves as 'username' $identityColumn = null, // The column that serves as 'password' $credentialColumn = null, // Any optional treatment of the password before // checking, such as MD5(?), SHA1(?), etcetera $credentialTreatment = null ); The HTTP adapter After constructing the object we need to define the FileResolver to make sure there are actually user details parsed in. Depending on what we configured in the accept_schemes option, the FileResolver can either be set as a BasicResolver, a DigestResolver, or both. Let's take a quick look at how to set a FileResolver as a DigestResolver or BasicResolver (we do this in the /module/Application/src/Application/Controller/IndexController.php file): <?php namespace Application; // Use the FileResolver, and also the Http // authentication adapter. use ZendAuthenticationAdapterHttpFileResolver; use ZendAuthenticationAdapterHttp; use ZendMvcControllerAbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { // Create a new FileResolver and read in our file to use // in the Basic authentication $basicResolver = new FileResolver(); $basicResolver->setFile( '/some/file/with/credentials.txt' ); // Now create a FileResolver to read in our Digest file $digestResolver = new FileResolver(); $digestResolver->setFile( '/some/other/file/with/credentials.txt' ); // Options doesn't really matter at this point, we can // fill them in to anything we like $adapter = new Http($options); // Now set our DigestResolver/BasicResolver, depending // on our $options set $adapter->setBasicResolver($basicResolver); $adapter->setDigestResolver($digestResolver); } } How it works… After two short examples, let's take a look at the other adapters available. The DbTable adapter Let's begin with probably the most used adapter of them all, the DbTable adapter. This adapter connects to a database and pulls the requested username/password combination from a table and, if all went well, it will return to you an identity, which is nothing more than the record that matched the username details. To instantiate the adapter, it requires a ZendDbAdapterAdapter in its constructor to connect with the database with the user details; there are also a couple of other options that can be set. Let's take a look at the definition of the constructor: The second (tableName) option speaks for itself as it is just the table name, which we need to use to get our users, the third and the fourth (identityColumn, credentialColumn) options are logical and they represent the username and password (or what we use) columns in our table. The last option, the credentialTreatment option, however, might not make a lot of sense. The credentialTreatment tells the adapter to treat the credentialColumn with a function before trying to query it. Examples of this could be to use the MD5 (?) function, PASSWORD (?), or SHA1 (?) function, if it was a MySQL database, but obviously this can differ per database as well. To give a small example on how the SQL can look like (the actual adapter builds this query up differently) with and without a credential treatment, take a look at the following examples: With credential treatment: SELECT * FROM `users` WHERE `username` = 'some_user' AND `password` = MD5('some_password'); Without credential treatment: SELECT * FROM `users` WHERE `username` = 'some_user' AND `password` = 'some_password'; When defining the treatment we should always include a question mark for where the password needs to come, for example, MD5 (?) would create MD5 ('some_password'), but without the question mark it would not insert the password. Lastly, instead of giving the options through the constructor, we can also use the setter methods for the properties: setTableName(), setIdentityColumn(), setCredentialColumn(), and setCredentialTreatment(). The HTTP adapter The HTTP authentication adapter is an adapter that we have probably all come across at least once in our Internet lives. We can recognize the authentication when we go to a website and there is a pop up showing where we can fill in our usernames and passwords to continue. This form of authentication is very basic, but still very effective in certain implementations, and therefore, a part of Zend Framework 2. There is only one big massive but to this authentication, and that is that it can (when using the basic authentication) send the username and password clear text through the browser (ouch!). There is however a solution to this problem and that is to use the Digest authentication, which is also supported by this adapter. If we take a look at the constructor of this adapter, we would see the following code line: public function __construct(array $config); The constructor accepts a load of keys in its config parameter, which are as follows: accept_schemes: This refers to what we want to accept authentication wise; this can be basic, digest, or basic digest. realm: This is a description of the realm we are in, for example Member's area. This is for the user only and is only to describe what the user is logging in for. digest_domains: These are URLs for which this authentication is working for. So if a user logs in with his details on any of the URLs defined, they will work. The URLs should be defined in a space-separated (weird, right?) list, for example /members/area /members/login. nonce_timeout: This will set the number of seconds the nonce (the hash users login with when we are using Digest authentication) is valid. Note, however, that nonce tracking and stale support are not implemented in Version 2.2 yet, which means it will authenticate again every time the nonce times out. use_opaque: This is either true or false (by default is true) and tells our adapter to send the opaque header to the client. The opaque header is a string sent by the server, which needs to be returned back on authentication. This does not work sometimes on Microsoft Internet Explorer browsers though, as they seem to ignore that header. Ideally the opaque header is an ever-changing string, to reduce predictability, but ZF 2 doesn't randomize the string and always returns the same hash. algorithm: This includes the algorithm to use for the authentication, it needs to be a supported algorithm that is defined in the supportedAlgos property. At the moment there is only MD5 though. proxy_auth: This boolean (by default is false) tells us if the authentication used is a proxy Authentication or not. It should be noted that there is a slight difference in files when using either Digest or Basic. Although both files have the same layout, they cannot be used interchangeably as the Digest requires the credentials to be MD5 hashed, while the Basic requires the credentials to be plain text. There should also always be a new line after every credential, meaning that the last line in the credential file should be empty. The layout of a credential file is as follows: username:realm:credentials For example: some_user:My Awesome Realm:clear text password Instead of a FileResolver, one can also use the ApacheResolver which can be used to read out htpasswd generated files, which comes in handy when there is already such a file in place. The Digest adapter The Digest adapter is basically the Http adapter without any Basic authentication. As the idea behind it is the same as the Http adapter, we will just go on and talk about the constructor, as that is a bit different in implementation: public function __construct($filename = null, $realm = null, $identity = null, $credential = null); As we can see the following options can be set when constructing the object: filename: This is the direct filename of the file to use with the Digest credentials, so no need to use a FileResolver with this one. realm: This identifies to the user what he/she is logging on to, for example My Awesome Realm or The Dragonborn's lair. As we are immediately trying to log on when constructing this, it does need to correspond with the credential file. identity: This is the username we are trying to log on with, and again it needs to resemble a user that is defined in the credential file to work. credential: This is the Digest password we try to log on with, and this again needs to match the password exactly like the one in the credential file. We can then, for example, just run $digestAdapter->getIdentity() to find out if we are successfully authenticated or not, resulting in NULL if we are not, and resulting in the identity column value if we are. The LDAP adapter Using the LDAP authentication is obviously a little more difficult to explain, so we will not go in to that full as that would take quite a while. What we will do is show the constructor of the LDAP adapter and explain its various options. However, if we want to know more about setting up an LDAP connection, we should take a look at the documentation of ZF2, as it is explained in there very well: public function __construct(array $options = array(), $identity = null, $credential = null); The options parameter in the construct refers to an array of configuration options that are compatible with the ZendLdapLdap configuration. There are literally dozens of options that can be set here so we advice to go and look at the LDAP documentation of ZF2 to know more about that. The next two parameters identity and credential are respectively the username and password again, so that explains itself really. Once you have set up the connection with the LDAP there isn't much left to do but to get the identity and see whether we were successfully validated or not. About Authentication Authentication in Zend Framework 2 works through specific adapters, which are always an implementation of the ZendAuthenticationAdapterAdapterInterface and thus, always provides the methods defined in there. However, the methods of Authentication are all different, and strong knowledge of the methods displayed previously is always a requirement. Some work through the browser, like the Http and Digest adapter, and others just require us to create a whole implementation like the LDAP and the DbTable adapter.
Read more
  • 0
  • 0
  • 3826
article-image-working-aspnet-web-api
Packt
13 Dec 2013
5 min read
Save for later

Working with ASP.NET Web API

Packt
13 Dec 2013
5 min read
(For more resources related to this topic, see here.) The ASP.NET Web API is a framework that you can make use of to build web services that use HTTP as the protocol. You can use the ASP.NET Web API to return data based on the data requested by the client, that is, you can return JSON or XML as the format of the data. Layers of an application The ASP.NET Framework runs on top of the managed environment of the .NET Framework. The Model, View, and Controller (MVC) architectural pattern is used to separate the concerns of an application to facilitate testing, ease the process of maintenance of the application's code, and to provide better support for change. The model represents the application's data and the business objects; the view is the presentation layer component, and the controller binds the model and the view together. The following figure illustrates the components of Model View Architecture: The MVC Architecture The ASP.NET Web API architecture The ASP.NET Web API is a lightweight web-based architecture that uses HTTP as the application protocol. Routing in the ASP.NET Web API works a bit differently compared to the way it works in ASP.NET MVC. The basic difference between routing in MVC and routing in a Web API is that, Web API uses the HTTP method, and not the URI path, to select the action. The Web API Framework uses a routing table to determine which action is to be invoked for a particular request. You need to specify the routing parameters in the WebApiConfig.cs file that resides in the App_Start directory. Here's an example that shows how routing is configured: routes.MapHttpRoute(    name: "Packt API Default",     routeTemplate: "api/{controller}/{id}",     defaults: new { id = RouteParameter.Optional } ); The following code snippet illustrates how routing is configured by action names: routes.MapHttpRoute(     name: "PacktActionApi",     routeTemplate: "api/{controller}/{action}/{id}",     defaults: new { id = RouteParameter.Optional } ); The ASP.NET Web API generates structured data such as JSON and XML as responses. It can route the incoming requests to the actions based on HTTP verbs and not only action names. Also, the ASP.NET Web API can be hosted outside of the ASP.NET runtime environment and the IIS Web Server context. Routing in ASP.NET Web API Routing in the ASP.NET Web API is very much the same as in the ASP.NET MVC. The ASP.NET Web API routes URLs to a controller. Then, the control is handed over to the action that corresponds to the HTTP verb of the request message. Note that the default route template for an ASP.NET Web API project is {controller}/{id}—here the {id} parameter is optional. Also, the ASP.NET Web API route templates may optionally include an {action} parameter. It should be noted that unlike the ASP.NET MVC, URLs in the ASP.NET Web API cannot contain complex types. It should also be noted that complex types must be present in the HTTP message body, and that there can be one, and only one, complex type in the HTTP message body. Note that the ASP.NET MVC and the ASP.NET Web API are two distinctly separate frameworks which adhere to some common architectural patterns. In the ASP.NET Web API framework, the controller handles all HTTP requests. The controller comprises a collection of action methods—an incoming request to the Web API framework, the request is routed to the appropriate action. Now, the framework uses a routing table to determine the action method to be invoked when a request is received. Here is an example: routes.MapHttpRoute(     name: "Packt Web API",     routeTemplate: "api/{controller}/{id}",     defaults: new { id = RouteParameter.Optional } ); Refer to the following UserController class. public class UserController <UserAuthentication>: BaseApiController<UserAuthentication> {     public void GetAllUsers() { }     public IEnumerable<User> GetUserById(int id) { }     public HttpResponseMessage DeleteUser(int id){ } } The following table illustrates the HTTP method and the corresponding URI, Actions, and so on: HTTP Method URI Action Parameter GET api/users GetAllUsers None GET api/users/1 GetUserByID 1 POST api/users     DELETE api/users/3 DeleteUser 3 The Web API Framework matches the segments in the URI path to the template. The following steps are performed: The URI is matched to a route template. The respective controller is selected. The respective action is selected. The IHttpControllerSelector.SelectController method selects the controller, takes an HttpRequestMessage instance and returns an HttpControllerDescriptor. After the controller has been selected, the Web API framework selects the action by invoking the IHttpActionSelector.SelectAction method. This method in turn accepts HttpControllerContext and returns HttpActionDescriptor. You can also explicitly specify the HTTP method for an action by decorating the action method using the HttpGet, HttpPut, HttpPost, or HttpDelete attributes. Here is an example: public class UsersController : ApiController {     [HttpGet]     public User FindUser(id) {} } You can also use the AcceptVerbs attribute to enable HTTP methods other than GET, PUT, POST, and DELETE. Here is an example: public class UsersController : ApiController {     [AcceptVerbs("GET", "HEAD")]     public User FindUser(id) { } } You can also define route by an action name. Here is an example: routes.MapHttpRoute(     name: "PacktActionApi",     routeTemplate: "api/{controller}/{action}/{id}",     defaults: new { id = RouteParameter.Optional } ); You can also override the action name by using the ActionName attribute. The following code snippet illustrates two actions: one that supports GET and the other that supports POST: public class UsersController : ApiController {     [HttpGet]     [ActionName("Token")]     public HttpResponseMessage GetToken(int userId);     [HttpPost]     [ActionName("Token")]     public void AddNewToken(int userId); }  
Read more
  • 0
  • 0
  • 10610

article-image-clojure-domain-specific-languages-design-concepts-clojure
Packt
13 Dec 2013
3 min read
Save for later

Clojure for Domain-specific Languages - Design Concepts with Clojure

Packt
13 Dec 2013
3 min read
(For more resources related to this topic, see here.) Every function is a little program When I first started getting deep into Clojure development, my friend Tom Marble taught me a very good lesson with a single sentence. I'm not sure if he's the originator of this idea, but he told me to think of writing functions as though "every function is a small program". I'm not really sure what I thought about functions before I heard this, but it all made sense the very moment he told me this. Why write a function as if it were its own program? Because both a function and a program are created to handle a specific set of problems, and this method of thinking allows us to break down our problems into a simpler group of problems. Each set of problems might only need a very limited collection of functions to solve them, so to make a function that fits only a single problem isn't really any different from writing a small program to get the very same result. Some might even call this the Unix philosophy, in the sense that you're trying to build small, extendable, simple, and modular code. A pure function What are the benefits of a program-like function? There are many benefits to this approach of development, but the two clear advantages are that the debugging process can be simplified with the decoupling of task, and this approach can make our code more modular. This approach also allows us to better build pure functions. A pure function isn't dependent on any variable outside the function. Anything other than the arguments passed to the function can't be realized by a pure function. Because our program will cause side effects as a result of execution, not all of our functions can be truly pure. This doesn't mean we should forget about trying to develop program-like functions. Our code inherently becomes more modular because pure functions can survive on their own. This is key when needing to build flexible, extendable, and reusable code components. Floor to roof development It is also known as bottom-up development and is the concept of building basic low- level pieces of a program and then combining them to build the whole program. This approach leads to more reusable code that can be more easily tested because each part of the program acts as an individual building block and doesn't require a large portion of the program to be completed to run a test. Each function only does one thing When a function is written to perform a specific task, that function shouldn't do anything unrelated to the original problem it's needed to solve. For example, if you were to write a function named parse-xml, the function should be able to act as a program that can only parse XML data. If the example function does anything else other than parse lines of XML input, it is probably badly designed and will cause confusion when trying to debug errors in our programs. This practice will help us keep our functions to a more reasonable size and can also help simplify the debugging process.
Read more
  • 0
  • 0
  • 1892

article-image-building-queries
Packt
12 Dec 2013
10 min read
Save for later

Building Queries

Packt
12 Dec 2013
10 min read
(For more resources related to this topic, see here.) Understanding DQL DQL is the acronym of Doctrine Query Language. It's a domain-specific language that is very similar to SQL, but is not SQL. Instead of querying the database tables and rows, DQL is designed to query the object model's entities and mapped properties. DQL is inspired by and similar to HQL, the query language of Hibernate, a popular ORM for Java. For more details you can visit this website: http://www.hibernate.org/. Learn more about domain-specific languages at: http://en.wikipedia.org/wiki/Domain-specific_language To better understand what it means, let's run our first DQL query. Doctrine command-line tools are as genuine as a Swiss Army knife. They include a command called orm:run-dql that runs the DQL query and displays it's result. Use it to retrieve title and all the comments of the post with 1 as an identifier: php vendor/bin/doctrine.php orm:run-dql "SELECT p.title,c.bodyFROM BlogEntityPost p JOIN p.comments c WHERE p.id=1" It looks like a SQL query, but it's definitely not a SQL query. Examine the FROM and the JOIN clauses; they contain the following aspects: A fully qualified entity class name is used in the FROM clause as the root of the query All the Comment entities associated with the selected Post entities are joined, thanks to the presence of the comments property of the Post entity class in the JOIN clause As you can see, data from the entities associated with the main entity can be requested in an object-oriented way. Properties holding the associations (on the owning or the inverse side) can be used in the JOIN clause. Despite some limitations (especially in the field of subqueries), DQL is a powerful and flexible language to retrieve object graphs. Internally, Doctrine parses the DQL queries, generates and executes them through Database Abstraction Layer (DBAL) corresponding to the SQL queries, and hydrates the data structures with results. Until now, we only used Doctrine to retrieve the PHP objects. Doctrine is able to hydrate other types of data structures, especially arrays and basic types. It's also possible to write custom hydrators to populate any data structure. If you look closely at the return of the previous call of orm:run-dql, you'll see that it's an array, and not an object graph, that has been hydrated. As with all the topics covered in this book, more information about built-in hydration modes and custom hydrators is available in the Doctrine documentation on the following website: http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html#hydration-modes Using the entity repositories Entity repositories are classes responsible for accessing and managing entities. Just like entities are related to the database rows, entity repositories are related to the database tables. All the DQL queries should be written in the entity repository related to the entity type they retrieve. It hides the ORM from other components of the application and makes it easier to re-use, refactor, and optimize the queries. Doctrine entity repositories are an implementation of the Table Data Gateway design pattern. For more details, visit the following website: http://martinfowler.com/eaaCatalog/tableDataGateway.html A base repository, available for every entity, provides useful methods for managing the entities in the following manner: find($id): It returns the entity with $id as an identifier or null It is used internally by the find() method of the Entity Managers. findAll(): It retrieves an array that contains all the entities in this repository findBy(['property1' => 'value', 'property2' => 1], ['property3' => 'DESC', 'property4' => 'ASC']): It retrieves an array that contains entities matching all the criteria passed in the first parameter and ordered by the second parameter findOneBy(['property1' => 'value', 'property2' => 1]): It is similar to findBy() but retrieves only the first entity or null if none of the entities match the criteria Entity repositories also provide shortcut methods that allow a single property to filter entities. They follow this pattern: findBy*() and findOneBy*(). For instance, calling findByTitle('My title') is equivalent to calling findBy(['title' => 'My title']). This feature uses the magical __call() PHP method. For more details visit the following website: http://php.net/manual/en/language.oop5.overloading.php#object.call In our blog app, we want to display comments in the detailed post view, but it is not necessary to fetch them from the list of posts. Eager loading through the fetch attribute is not a good choice for the list, and Lazy loading slows down the detailed view. A solution to this would be to create a custom repository with extra methods for executing our own queries. We will write a custom method that collates comments in the detailed view. Creating custom entity repositories Custom entity repositories are classes extending the base entity repository class provided by Doctrine. They are designed to receive custom methods that run the DQL queries. As usual, we will use the mapping information to tell Doctrine to use a custom repository class. This is the role of the repositoryClass attribute of the @Entity annotation. Kindly perform the following steps to create a custom entity repository: Reopen the Post.php file at the src/Blog/Entity/ location and add a repositoryClass attribute to the existing @Entity annotation like the following line of code: @Entity(repositoryClass="PostRepository") Doctrine command-line tools also provide an entity repository generator. Type the following command to use it: php vendor/bin/doctrine.php orm:generate:repositories src/ Open this new empty custom repository, which we just generated in the PostRepository.phpPostRepository.php file, at the src/Blog/Entity/ location. Add the following method for retrieving the posts and comments: /** * Finds a post with its comments * * @param int $id * @return Post */ public function findWithComments($id) { return $this ->createQueryBuilder('p') ->addSelect('c') ->leftJoin('p.comments', 'c') ->where('p.id = :id') ->orderBy('c.publicationDate', 'ASC') ->setParameter('id', $id) ->getQuery() ->getOneOrNullResult() ; } Our custom repository extends the default entity repository provided by Doctrine. The standard methods, described earlier in the article, are still available. Getting started with Query Builder QueryBuilder is an object designed to help build the DQL queries through a PHP API with a fluent interface. It allows us to retrieve the generated DQL queries through the getDql() method (useful for debugging) or directly use the Query object (provided by Doctrine). To increase performance, QueryBuilder caches the generated DQL queries and manages an internal state. The full API and states of the DQL query are documented on the following website: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html We will give an in-depth explanation of the findWithComments() method that we created in the PostRepository class. Firstly, a QueryBuilder instance is created with the createQueryBuilder() method inherited from the base entity repository. The QueryBuilder instance takes a string as a parameter. This string will be used as an alias of the main entity class. By default, all the fields of the main entity class are selected and no other clauses except SELECT and FROM are populated. The leftJoin() call creates a JOIN clause that retrieves comments associated with the posts. Its first argument is the property to join and its second is the alias; these will be used in the query for the joined entity class (here, the letter c will be used as an alias for the Comment class). Unless the SQL JOIN clause is used, the DQL query automatically fetches the entities associated with the main entity. There is no need for keywords like ON or USING. Doctrine automatically knows whether a join table or a foreign-key column must be used. The addSelect() call appends comment data to the SELECT clause. The alias of the entity class is used to retrieve all the fields (this is similar to the * operator in SQL). As in the first DQL query of this article, specific fields can be retrieved with the notation alias.propertyName. You guessed it, the call to the where() method sets the WHERE part of the query. Under the hood, Doctrine uses prepared SQL statements. They are more efficient than the standard SQL queries. The id parameter will be populated by the value set by the call to setParameter(). Thanks again to prepared statements and this setParameter() method, SQL Injection attacks are automatically avoided. SQL Injection Attacks are a way to execute malicious SQL queries using user inputs that have not escaped. Let's take the following example of a bad DQL query to check if a user has a specific role: $query = $entityManager->createQuery('SELECT ur FROMUserRole urWHERE ur.username = "' . $username . '" ANDur.role = "' . $role . '"'); $hasRole = count($query->getResult()); This DQL query will be translated into SQL by Doctrine. If someone types the following username: " OR "a"="a the SQL code contained in the string will be injected and the query will always return some results. The attacker has now gained access to a private area. The proper way should be to use the following code: $query = $entityManager->createQuery("SELECT ur FROMUserRole WHEREusername = :username and role = :role"); $query->setParameters([ 'username' => $username, 'role' => $role ]); $hasRole = count($query->getResult()); Thanks to prepared statements, special characters (like quotes) contained in the username are not dangerous, and this snippet will work as expected. The orderBy() call generates an ORDER BY clause that orders results as per the publication date of the comments, older first. Most SQL instructions also have an object-oriented equivalent in DQL. The most common join types can be made using DQL; they generally have the same name. The getQuery() call tells the Query Builder to generate the DQL query (if needed, it will get the query from its cache if possible), to instantiate a Doctrine Query object, and to populate it with the generated DQL query. This generated DQL query will be as follows: SELECT p, c FROM BlogEntityPost p LEFT JOIN p.comments cWHEREp.id = :id ORDER BY c.publicationDate ASC The Query object exposes another useful method for the purpose of debugging: getSql(). As its name implies, getSql() returns the SQL query corresponding to the DQL query, which Doctrine will run on DBMS. For our DQL query, the underlying SQL query is as follows: SELECT p0_.id AS id0, p0_.title AS title1, p0_.bodyAS body2,p0_.publicationDate AS publicationDate3,c1_.id AS id4, c1_.bodyAS body5, c1_.publicationDate AS publicationDate6,c1_.post_id ASpost_id7 FROM Post p0_ LEFT JOIN Commentc1_ ON p0_.id =c1_.post_id WHERE p0_.id= ? ORDER BY c1_.publicationDate ASC The getOneOrNullResult() method executes it, retrieves the first result, and returns it as a Post entity instance (this method returns null if no result is found). Like the QueryBuilder object, the Query object manages an internal state to generate the underlying SQL query only when necessary. Performance is something to be very careful about while using Doctrine. When set in production mode, ORM is able to cache the generated queries (DQL through the QueryBuilder objects, SQL through the Query objects) and results of the queries. ORM must be configured to use one of the blazing, fast, supported systems (APC, Memcache, XCache, or Redis) as shown on the following website: http://docs.doctrine-project.org/en/latest/reference/caching.html We still need to update the view layer to take care of our new findWithComments() method. Open the view-post.php file at the web/location, where you will find the following code snippet: $post = $entityManager->getRepository('BlogEntityPost')->find($_GET['id']); Replace the preceding line of code with the following code snippet: $post = $entityManager->getRepository('BlogEntityPost')->findWithComments($_GET['id']);
Read more
  • 0
  • 0
  • 6783
article-image-joomla-template-system
Packt
12 Dec 2013
9 min read
Save for later

Joomla! Template System

Packt
12 Dec 2013
9 min read
(For more resources related to this topic, see here.) Every website has some content, and all kinds of information is provided on websites; not just text, but pictures, animations, and video clips—anything that communicates a site's body of knowledge. However, visual design is the appearance of the site. A good visual design is one that is high quality, appropriate, and relevant to the audience and the message it supports. As a large amount of companies feel the need to redesign their site very few years, they need someone who can stand back and figure out what all that content should communicate. This could be you. The basic principle of Joomla! (and other content management systems) is to separate the content from its visual form. Although this separation is not absolute, it is distinct enough to facilitate quick and efficient customization and deployment of websites. Changing the appearance of web pages built on CMS comes down to installing and configuring a new template. A template is a set of files that determine the look and feel of your Joomla-powered website. Templates include information about the general layout of the site and other content, such as graphics, colors, background images, headers, logos, and typography and footers. Each template is different, offering many choices for site owners to almost instantly change the look of their website. You can see the result of this separation of content from presentation by changing the default template (preinstalled in Joomla!). For web designers, learning how to develop templates for content management systems such as Joomla! opens up lots of opportunities. Joomla! gives you big opportunities to build websites. Taking into account the evolution of web browsers, you are only limited by your imagination and skill set, thanks to a powerful and flexible CMS infrastructure. The ability to change or modify the content and appearance of web pages is important in today's online landscape. What is a Joomla! template? As in the case of traditional HTML templates, Joomla! template is a collection of files (PHP, CSS, and JavaScript) that define the visual appearance of the site. Each template has variations on these files, and each template's files are different, but they have a common purpose; they control the placement of the elements on the screen and impact both the presentation of the contents and the usability of the functionality. In general, a template does not have any content, but it can include logo and background images. The Joomla! template controls the way all information is shown on each page of the website. A template contains the stylesheets, locations, and layout information for the web content being displayed. Also each installed component can have its own template to present content that can overwrite the default template's CSS styles. A template alone cannot be called a website. Generally, people think of the template as the appearance of their site. But a template is only a structure (usually painted and colored) with active fields. It determines the appearance of individual elements (for example, font size, color, backgrounds, style, and spacing) and arrangement of individual elements (including modules). In Joomla!, a single page view is generated by the HTML output of one component, selected modules, and the template. Unlike typical websites, where different components of the template are duplicated throughout the website pages, in case of Joomla!, there is just one assigned template that is responsible for displaying content for the entire site. Most CMS's, Joomla! included, have a modular structure that allows easy improvement of the site's appearance and functionality by installing and publishing modules in appropriate areas. Search engines don't care about design, but people do. How well a template is designed and implemented is, therefore, largely responsible for the first impression made by a website, which later translates into the perception that people have of the entire website. Joomla! released Joomla! Version 3.0.0 on September 27, 2012 with significant updates and major developments. With the adoption of the Twitter Bootstrap framework, Joomla! has become the first major CMS to be mobile ready in both visitor and administrator areas. Bootstrap (http://twitter.github.com/bootstrap) is an open source JavaScript framework developed by the team at Twitter. It is a combination of HTML, CSS, and JavaScript code designed to help build user interface components. Bootstrap was also programmed to support both HTML5 and CSS3. As a result, page layout uses a 1152 px * 1132 px * 1116 px * 1104 px grid, whereas previous versions of Joomla! templates used a 940 px wide layout. Default template stylesheets in Joomla! 3.x are written with LESS, and are then compiled to generate the CSS files. Because of the use of Bootstrap, Joomla! 3.x will slowly begin to migrate toward jQuery in the core (instead of MooTools). Mootools is no longer the primary JavaScript library interface. Joomla! 3.x templates are not compatible with previous versions of Joomla! and have been developed as a separate product. Templates – download for free, buy, or build your own I also want to show you the sites where you can download templates for free or buy them; after all, this book is supposed to teach you how to create your own sites. There are a number of reasons for this. First, you might not have the time or the ability to design a template or create it from scratch for the customer. You can set up your website within minutes because all you have to do is install or upload your template and begin adding content. By swapping the header image and changing the background color or image, you can transform a template with very little additional work. Second, as you read the book you will get acquainted with the basic principles of modifying templates, and thus you will learn how to adapt the ready-made solutions to the specific needs of your project. In general, you don't need to know much about PHP to use or tweak prebuilt templates. Templates can be customized by anyone with basic HTML/CSS knowledge. You can customize template elements to make it suit your needs or those of your client using a simple CSS editor; your template can be configured by template parameters. Third, learn from other template developers. Follow every move of your competitors. When they release an interesting, functional, and popular template, follow (but do not copy) them. We can all learn from others; projects by other people are probably one of the most obvious sources of inspiration. The following screenshot presents a few commercial templates for Joomla! 3.x. built in 2013 by popular developers, bearing in mind, however, that the line between inspiration and plagiarism is often very thin: Free templates Premade free templates are a great solution for those who have a limited budget. It is good experience to use the work of different developers and is also a great way to test a new web concept without investing much apart from your time. There are some decent free templates out there that may even be suitable for a small or medium production website. If you don't like a certain template after using it for a bit, ditching it doesn't mean any loss in investment. Unfortunately, there are also some disadvantages of using free templates. These templates are not unique. Several thousands of web designers from around the world may have already downloaded and used the template you have chosen. So if you don't change the colors or layout a bit, your site will look like a clone, which would be quite unprofessional. Generally, free Joomla! templates don't have any important or useful features such as color variants, Google fonts, advanced typography, CSS compression options, or even responsive layout. On the downside of free templates, you have the obvious quality issues. The majority of free templates are very basic and sometimes even buggy. The support for free templates is almost always lacking. While there are a few free templates that are supported by their creators, they are under no obligation to provide full support to your template if you need help adjusting the layout or fixing a problem due to an error. Realize that developers often use free templates to advertise their cost structures, expansion versions, or club subscriptions. That's why some developers require you to leave a link to their website on the bottom of your page if you use their free templates. What was surprising to me was that not all the free templates for Joomla! 3.x are mobile friendly, despite the fact that even the built-in CMS are built as Responsive Web Design (RWD). In most cases, it was presumably intended by the creators to look like JoomlaShine or Globbersthemes. The following is a list of resources from where you can download different kinds of free templates: www.joomla24.com www.joomlaos.de www.siteground.com/joomla-templates.htm www.bestofjoomla.com Quite often, popular developers publish free templates on their websites; in this way they promote their brand and other products such as modules or commercial versions of templates. Those templates always have better quality and features than others. I suggest that you download free templates only from reliable sources. It is with a great deal of care that you should approach templates shared on discussion forums or blogs because there's a high probability that the code template has been deliberately modified. A huge proportion of templates available for free are in fact packaged with malicious code. Summary Hopefully, after reading this article you will have a better understanding of the features of the Joomla! Template Manager and the types of problems it is able to solve. Resources for Article: Further resources on this subject: Installing and Configuring Joomla! on Local and Remote Servers [Article] Joomla! 1.5: Installing, Creating, and Managing Modules [Article] Tips and Tricks for Joomla! Multimedia [Article]
Read more
  • 0
  • 0
  • 1578

article-image-logging-capabilities
Packt
10 Dec 2013
6 min read
Save for later

Logging Capabilities

Packt
10 Dec 2013
6 min read
(For more resources related to this topic, see here.) Posting messages to the log TestComplete allows committing various types of messages to the log: ordinary messages, warnings, logs, and so on. In this section, we will consider examples of how to use these messages. Getting ready Create a file with the name myfile.txt in the root directory of C:. How to do it... In order to see examples of all the message types in the log, the following steps should be performed: Create and launch the following function: function testMessages() { Log.Event("An event", "Event additional Info"); Log.Message("A message", "Message additional Info"); Log.Warning("A warning", "Warning additional Info"); Log.Error("An error", "Error additional Info"); Log.File("C:\somefile.txt", "A file posted to the log"); Log.Link("C:\somefile.txt", "A link to a file"); Log.Link("http://smartbear.com/", "HTTP link"); Log.Link("ftp://smartbear.com/", "FTP link"); } In the result, we will get the following screenshot of the log How it works... In the given example, we have used four different types of messages. They are as follows: Log.Event: This message is an event which occurs when TestComplete interacts with a tested application. Usually, messages of this type are placed into the log at the point of text input or mouse-clicks; however, we can also place custom-made events into the log. Log.Message: This message is an ordinary message that is usually used for prompting a user concerning current actions that are being executed by the script (usually, of a higher level than that of the events; for example, creation of a user, searching for a record, and so on). Log.Warning: This message is a non-critical error. It is used in case the results of the check are different from those expected; nonetheless, execution of the script can carry on. Log.Error: This message is a critical error usually used when an error is a critical one, making any further execution of the test would be futile These four types of message are based on several parameters. The first of them is a string that we observe in the log itself; the second one contains additional information which can be seen in the Additional Info tab, if the message has been clicked on. The second parameter is optional and can be omitted as well as all other parameters. There are two more types of messages: Log.File: This message copies the assigned file into the file with the log, and places a reference-pointer to it. Meanwhile, TestComplete renames the file to avoid naming conflicts, leaving only the original extension intact. Log.Link: This message places a link to the web page or a file, without making a copy of the file itself in the folder with the log. On clicking on the link, the file will open with the help of the associated program or a link in the browser. These two types of message accept the link as the first parameter, and then the message parameters, and those pertaining to the additional information (as the previous four). Only the first parameter is mandatory. Posting screenshots to the log Sometimes, it is necessary to place an image into the log; often, it may be a window screenshot, an image of a controls element, or even that of the whole of the screen. To this end, we use the Log.Picture method. In this section we will consider different ways to place an image into the log. How to do it... The following steps should be performed to place an image to the log: First of all, we will create two image objects for the enabled window and the whole of the screen: var picWindow = Sys.Desktop.ActiveWindow().Picture(); var picDesktop = Sys.Desktop.Picture(); The image of the active window, now being stored in the picWindow variable , will be placed into the log, unchanged: Log.Picture(picWindow, "Active window"); The image of the desktop is reduced by four times via the Stretch method , and then saved on to the file with the help of the SaveToFile method: picDesktop.Stretch(picDesktop.Size.Width/2, picDesktop.Size.Height/2); picDesktop.SaveToFile("c:\desktop.png"); Now we go about creating a new variable of the Picture type, loading up an image into it from the earlier saved file, and then placing the same into the log: var pic = Utils.Picture; pic.LoadFromFile("c:\desktop.png"); Log.Picture(pic, "Resized Desktop"); As a result of function's execution, the log will contain the two images placed therein: that of the enabled window at the moment of test execution, and that of the reduced desktop copy. How it works... The Log.Picture method has one mandatory parameter that is, the image itself; the other parameters being optional. Images of any of the onscreen objects (of a window, of a singular controls element, of the desktop) can be obtained via the Picture method. In our example, with the help of the method, we get the image of the desktop and that of the active window. Instead of the active window, we could use any variable that corresponds to a window or a controls element. Any image can be saved onto the disk with the help of the SaveToFile method. The format of the saved image is determined by its extension (in our case, it is the PNG). If it's necessary to obtain a variable containing the image from the file, we are supposed to create an empty variable placeholder with the help of the Utils.Picture property , and then with the help of the LoadFromFile method , we upload the image into it. In the future, one could handle the image as any other, received with the help of the Picture method. Great-size images can be minified with the help of the Stretch method. The Stretch method uses two parameters: the new width and height of the image. With the help of the Size.Width and Size.Height properties , we could zoom in or out on the image in relation to its original size, without setting the dimensions explicitly. There's more... With the help of the Picture method , we could obtain not only the image of the whole window or a controls element, but just a part of it. For example, the following code gets an image of the upper left square of the desktop within the sizing of 50 x 50 pixels: var picDesktop = Sys.Desktop.Picture(0,0, 50, 50); The values of the parameters are as follows: coordinates of the left and right top corner, and its width and height. There is one important project setting which allows automatic posting images in case of error. To enable this option, right-click on the project name, navigate to Edit | Properties, click on Playback item from the list of options, and enable checkbox Post image on error. Apart from changing the dimensions of the image, TestComplete allows for the execution of several, quite complicated imaging manipulations. For example, the comparison of the two images (the Compare method ), searching for one image inside the other (the Find method ), and so on. Click on the following link to get to know more about these possibilities: http://support.smartbear.com/viewarticle/32131/
Read more
  • 0
  • 0
  • 3367