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
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-opencart-layout-structure
Packt
29 Mar 2011
7 min read
Save for later

OpenCart: layout structure

Packt
29 Mar 2011
7 min read
In this article, we will see the default layout structure of OpenCart. We'll discuss the cascading stylesheet file from it and modify it according to our needs. First of all, we'll use the reset style properties to eliminate cross-browser problems. We will discuss every property here. We'll also see the corresponding effects on our site. Then, we'll do some basic styling for the site. For each change in style, we will see why we did that. Folder structure In our main OpenCart folder, we have the admin and catalog sections. These are two separate subsystems. As the name says, admin has the files and folders for administration operation. Catalog contains the store files and folders. Each admin and catalog section has a separate model, view, and controller. Under this admin and catalog folder, we will see the model, view, and controller folders. You will see different subfolders within those folders. So, let's discuss this MVC structure in the following paragraph. OpenCart is built with the MVC design pattern. So, it has model, view, and controller. A user requests the OpenCart controller to process the request. Then, the controller gets the data using the model and processes the fetched data to show the response with the view file. The following figure shows the above operation of MVC: For theme modification, we will focus only on the View folder of the catalog in this article. It has javascript and theme folders. We place our themes under the theme folder and the necessary JavaScript files in the JavaScript folder. Each theme has an image, stylesheet, and template folder. We will see how we can create a new theme later in this article. Theme file style As we stated earlier, OpenCart uses the MVC design pattern. So, the view files remain separated from the core code. These files are .tpl files. And, they are placed under catalogviewthemedefaulttemplate. These .tpl files are basically HTML files. They have PHP code within them to display the necessary data. OpenCart doesn't use the smarty template engine. Rather, it uses embedded PHP codes that are easy to use. We assign the PHP variables in the controller with necessary data. Then, we call the variable in the .tpl view file. We can also use the global class reference variable. In the controller, we will assign the value like this: $this->data['shop_name'] = 'store'; Here, we assigned store value to the shop_name variable. In the .tpl view file, we will display the value like this: <?php echo $shop_name; ?> Creating a new theme In this recipe, we will see the steps to create a new theme for OpenCart. There are some rules to create OpenCart themes. Getting started Let's get started with the steps to create a new theme with OpenCart. How to do it Following are the steps for creating a new theme for OpenCart: First of all, we need to create a new folder under catalogviewtheme. For example, we will name it shop for this project. Now, we need to copy some files from the default theme folder to our new theme folder. The files are the following: catalogviewthemedefaultstylesheet*.* catalogviewthemedefaultimage*.* catalogviewthemedefaulttemplatecommonheader.tpl We have to edit some values in the header.tpl file for our new theme. We will replace all default keywords with our new theme name shop. Actually, there are six places where we need to replace the new theme name. The lines are the following: <link rel="stylesheet" type="text/css" href="catalog/view/theme/shop/stylesheet/stylesheet.css" /> // other lines ... <link rel="stylesheet" type="text/css" href="catalog/view/theme/shop/stylesheet/ie6.css" /> //other lines ... <div class="div3"> <a href="<?php echo str_replace('&', '&amp;', $special); ?>" style="background-image: url('catalog/view/theme/shop/image/special.png');"> <?php echo $text_special; ?></a> <a onclick="bookmark(document.location, '<?php echo addslashes($title); ?>');" style="background-image: url('catalog/view/theme/shop/image/bookmark.png');"> <?php echo $text_bookmark; ?></a><a href="<?php echo str_replace('&', '&amp;', $contact); ?>" style="background-image: url('catalog/view/theme/shop/image/contact.png');"><?php echo $text_contact; ?></a><a href="<?php echo str_replace('&', '&amp;', $sitemap); ?>" style="background-image: url('catalog/view/theme/shop/image/sitemap.png');"><?php echo $text_sitemap; ?></a></div> //other lines ... And now, save it. Now, we will go to the admin area. First log in with our stored admin credentials. Go to System | Settings in the admin panel: We will go to the Store tab. We will change the theme from default to shop, our new theme from a select list. You can make changes on your theme's CSS file. Resetting layout styles Before beginning our theme styling work, we must first reset all the styles. This will help us with cross-browser problems. Getting started We need to modify the stylesheet.css file of our new theme first. We will go to catalogviewthemeshopstylesheet. And open up stylesheet.css in our favourite editor. How to do it Now, we will add reset styles to our stylesheet.css file. First, we need to change the browser's margin, padding, and border properties. We will set styles for several different HTML tags. We can add extra style properties into it: html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; } We will see the effect of our code in our store. The product images will come closer now. We adjust the line height of body tag. So, put the following code in the CSS file. body { line-height: 1; } This also squeezes the lines in the body element. The following image depicts this: By applying the above style, the line height of these tabs becomes shortened. We need to reset the style for ordered/unordered list elements. Hence, we use the following reset value: ol, ul { list-style: none; } It shows all the ul, ol tags without the default bullet properties. Now, we will reset the blockquote element styles. We will find the changes if we use blockquotes in our HTML code: blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } For all the elements, we are going to change the focus-styling attributes. We change the outline properties to 0. We set the styles like the following: :focus { outline: 0; } There could be some styling for insert and deletion in some browsers. So, we will use this styling for the purpose: ins { text-decoration: none; } del { text-decoration: line-through; } We will control the styling of our tables also. We set the border and spacing qualities like the following: table { border-collapse: collapse; border-spacing: 0; } We still need to set the attribute cell-spacing to 0. So, our reset styling becomes the following: html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } :focus { outline: 0; } ins { text-decoration: none; } del { text-decoration: line-through; } table { border-collapse: collapse; border-spacing: 0; } We can place it at the start of our site's style file stylesheet.css, or we can create a new file and put the content there also. To do that, just create a new CSS file within the catalogviewthemeshopstylesheet folder. For example, we can name the new style file as reset.css. If we use a new style file, then we need to add the style file in the controller.  
Read more
  • 0
  • 0
  • 4419

article-image-cakephp-authentication-setup-application
Packt
28 Mar 2011
11 min read
Save for later

CakePHP: authentication setup on an application

Packt
28 Mar 2011
11 min read
In this CakePHP tutorial, you'll learn how to set up a basic authentication system. Follow the recipes and you'll find all the code you need. Setting up a basic authentication system The first task to be completed when we are in the process of adding authentication to an application is to identify which controllers will need user access. Normally we would make every controller and action protected by default, and then we would specify which areas of our application allow public access. Getting ready We must have a users table that should contain, at least, two fields: username (to hold the username) and password (to hold a hash made out of the user's password). If you don't have a table for this purpose, you can use the following SQL statement to create it: CREATE TABLE `users`( `id` INT UNSIGNED AUTO_INCREMENT NOT NULL, `username` VARCHAR(255) NOT NULL, `password` CHAR(40) NOT NULL, PRIMARY KEY(`id`) ); How to do it... Create a file named users_controller.php and place it inside your app/controllers folder with the following contents: <?php class UsersController extends AppController { public function login() { } public function logout() { $this->redirect($this->Auth->logout()); } } ?> Create a file named login.ctp in your app/views/users folder (create the folder if you don't have one already), and add the following contents: <?php echo $this->Form->create(array('action'=>'login')); echo $this->Form->inputs(array( 'legend' => 'Login', 'username', 'password' )); echo $this->Form->end('Login'); ?> Create a file named app_controller.php in your app/ folder with the following contents: <?php class AppController extends Controller { public $components = array( 'Auth' => array( 'authorize' => 'controller' ), 'Session' ); public function isAuthorized() { return true; } } ?> Modify the UsersController, and add the following code before the login method: public function beforeFilter() { parent::beforeFilter(); $this->Auth->allow('add'); } public function add() { if (!empty($this->data)) { $this->User->create(); if ($this->User->save($this->data)) { $this->Session->setFlash('User created!'); $this->redirect(array('action'=>'login')); } else { $this->Session->setFlash('Please correct the errors'); } } } Create a file named add.ctp and place it in your app/views/users folder with the following contents: <?php echo $this->Form->create(); echo $this->Form->inputs(array( 'legend' => 'Signup', 'username', 'password' )); echo $this->Form->end('Submit'); ?> We now have a fully working authentication system. We can add new users by browsing to http://localhost/users/add, logging in by browsing to http://localhost/users/login, and finally logging out by browsing to http://localhost/users/logout. After creating a user, you should see the login form with a success message, as shown in the following screenshot: How it works... We start by creating two actions in the UsersController class: login(), to show and process submissions of the login form, and logout(), to handle users logging out. You may be surprised that the login() method has no logic whatsoever. To display the form, all we need to do is display the action's view. The form submission is taken care of by the Auth component, leaving us with no need to implement any controller logic. Therefore, the only implementation we need is to create a view for this action, which includes a simple form with two fields: username, and password. The inputs method of CakePHP's FormHelper is a shortcut designed to avoid multiple calls to the input method. By using it, we can create a full form with elements without the need to call FormHelper::input() several times. The logout() controller action simply calls the Auth component's logout() method. This method removes the logged-in user data from the session, and returns the address to which the user should be redirected after logging out, obtained from the previously configured logoutRedirect setting of the component (defaults to the application's home page if the setting was not configured.) Next, we add two components to the controller: Session, and Auth. The Session component is needed to create the messages (through the use of its setflash() method) that informs the user if a login attempt was unsuccessful, or if a user was created. The Auth component operates between your controller's actions and the incoming request by means of the beforeFilter callback method. It uses it's authorize setting to check what type of authentication scheme is to be used. Once the Auth component is added to a controller, all actions in that controller are not accessible unless there is a valid user logged in. This means that if we had any actions that should be public (such as the login() and add() actions in our controller), we would have to tell the Auth component about them. If one wishes to make some actions public, one can add the name of these actions to the allowedActions setting of the Auth component, or by calling its allow() method. We use the later approach to tell the Auth component that the add() action should be reachable without a logged-in user. The login() action is automatically added to the list of public actions by the Auth component. When the user attempts to reach an action that is not within the public actions, the Auth component checks the session to see if a user is already logged in. If a valid user is not found, it redirects the browser to the login action. If there is a user who is logged in, it uses the controller's isAuthorized method to check if the user has access. If its return value is true, it allows access, otherwise access is rejected. In our case, we implemented this method in AppController, our base controller class. If the attempted action requires a user who is logged in, the login() action is executed. After the user submits data using the login form, the component will first hash the password field, and then issue a find operation on the User model to find a valid account, using the posted username and password. If a valid record is found, it is saved to the session, marking the user as logged in. Hashing a password confirmation field When the Auth component is enabled on a controller and the user submits a form with a field named password (regardless if it is being rendered in the login form), the component will automatically hash the password field before executing the controller's action. The Auth component uses the salt defined in the configuration setting Security.salt (in your app/config/core.php file) to calculate the hash. Different salt values will produce different hashes even when using the same password. Therefore, make sure you change the salt on all your CakePHP applications, thus enhancing the security of your authentication system. This means that the action will never hold the plain password value, and this should be particularly noted when utilizing mechanisms to confirm password validations. When you are implementing such validation, make sure you hash the confirmation field using the proper method: if (!empty($this->data)) { $this->data['User']['confirm_password'] = $this->Auth- >password($this->data['User']['confirm_password']); // Continue with processing } Using and configuring the Auth component If there is something that defines the Auth component, it is its flexibility that accounts for different types of authentication modes, each of these modes serving different needs. In this recipe, you will learn how to modify the component's default behavior, and how to choose between the different authentications modes. Getting ready We should have a fully working authentication system, so follow the entire recipe Setting up a basic authentication system. We will also add support to have disabled user accounts. Add a field named active to your users table with the following SQL statement: ALTER TABLE `users` ADD COLUMN `active` TINYINT UNSIGNED NOT NULL default 1; How to do it... Modify the definition of the Auth component in your AppController class, so it looks like the following: public $components = array( 'Auth' => array( 'authorize' => 'controller', 'loginRedirect' => array( 'admin' => false, 'controller' => 'users', 'action' => 'dashboard' ), 'loginError' => 'Invalid account specified', 'authError' => 'You don't have the right permission' ), 'Session' ); Now while still editing your app/app_controller.php file, place the following code right below the components property declaration, at the beginning of the beforeFilter method in your AppController class: public function beforeFilter() { if ($this->Auth->getModel()->hasField('active')) {$this->Auth->userScope = array('active' => 1); } } Copy the default layout from cake/libs/view/layouts/default.ctp to your app/views/layouts directory, and make sure you place the following line in your layout where you wish to display authentication messages: <?php echo $this->Session->flash('auth'); ?> Edit your app/controllers/users_controller.php file and place the following method right below the logout() method: public function dashboard() { } Finally, create the view for this newly added action in a file named dashboard.ctp and place it in your app/views/users folder with the following contents: <p>Welcome!</p> If you now browse to http://localhost/users/login and enter the wrong credentials (wrong username and/or password), you should see the error message shown in the following screenshot: How it works... As the Auth component does its magic right before a controller action is executed, we either need to specify its settings in the beforeFilter callback, or pass them in an array when adding the component to the components property. A common place to do it is in the beforeFilter() method of the AppController class, as by doing so we can share the same authentication settings throughout all our controllers. This recipe changes some Auth settings, so that whenever a valid user logs in, they are automatically taken to a dashboard action in the UsersController (done via the loginRedirect setting.) It also adds some default error messages through the component's respective settings: loginError for when the given account is invalid, and authError for when there is a valid account, but the action is not authorized (which can be achieved by returning false from the isAuthorized() method implemented in AppController.) It also sets the component's userScope setting in AppController::beforeFilter(). This setting allows us to define which conditions the User find operation need to match to allow a user account to log in. By adding the userScope setting, we ensure that only user records that have the active field set to 1 are allowed access. Changing the default user model As you may have noticed, the role of the User model is crucial, not only to fetch the right user account, but also to check the permissions on some of the authentication schemes. By default, the Auth component will look for a User model, but you can change which model is to be used by setting the userModel property or the userModel key in the settings array. For example, if your user model is Account, you would add the following setting when adding the Auth component to your controller: 'userModel' => 'Account' Or equivalently, you would add the following to the beforeFilter method of your AppController class, in the block of code where you are setting up the component: $this->Auth->userModel = 'Account'; There's more... The $authorize property of the Auth component (or the authorize key in the Auth component settings array) defines which authentication scheme should be used. Possible values are: controller: It makes the component use the controller's isAuthorized method, which returns true to allow access, or false to reject it. This method is particularly useful when obtaining the logged-in user model: It is similar to controller; instead of using the controller to call the method, it looks for the isAuthorized method in the User model. First, it tries to map the controller's action to a CRUD operation (one of 'create', 'read', 'update', or 'delete'), and then calls the method with three arguments: the user record, the controller that is being accessed, and the CRUD operation (or actual controller action) that is to be executed. object: It is similar to model; instead of using the model to call the method, it looks for the isAuthorized method in a given class. In order to specify which class, set the AuthComponent::$object property to an instance of such a class. It calls the method with three arguments: the user record, the controller that is being accessed, and the action that is to be executed. actions: It uses the Acl component to check for access, which allows a much more grained access control. crud: It is similar to actions; the difference lies in the fact that it first tries to map the controller's action to a CRUD operation (one of 'create', 'read', 'update', or 'delete'.)
Read more
  • 0
  • 0
  • 4013

article-image-everything-package-concrete5
Packt
28 Mar 2011
10 min read
Save for later

Everything in a Package with concrete5

Packt
28 Mar 2011
10 min read
  concrete5 Beginner's Guide Create and customize your own website with the Concrete5 Beginner's Guide What's a package? Before we start creating our package, here are a few words about the functionality and purpose of packages: They can hold a single or several themes together You can include blocks which your theme needs You can check the requirements during the installation process in case your package depends on other blocks, configurations, and so on A package can be used to hook into events raised by concrete5 to execute custom code during different kind of actions You can create jobs, which run periodically to improve or check things in your website These are the most important things you can do with a package; some of it doesn't depend on packages, but is easier to handle if you use packages. It's up to you, but putting every extension in a package might even be useful if there's just a single element in it—why? You never have to worry where to extract the add-on. It always belongs in the packages directory An add-on wrapped in a package can be submitted to the concrete5 marketplace allowing you to earn money or make some people in the community happy by releasing your add-on for free Package structure We've already looked at different structures and you are probably already familiar with most of the directories in concrete5. Before we continue, here are a few words about the package structure, as it's essential that you understand its concept before we continue. A package is basically a complete concrete5 structure within one directory. All the directories are optional though. No need to create all of them, but you can create and use all of them within a single package. The directory concrete is a lot like a package as well; it's just located in its own directory and not within packages. Package controller Like the blocks we've created, the package has a controller as well. First of all, it is used to handle the installation process, but it's not limited to that. We can handle events and a few more things in the package controller; there's more about that later in this article. For now, we only need the controller to make sure the dashboard knows the package name and description. Time for action - creating the package controller Carry out the following steps: First, create a new directory named c5book in packages. Within that directory, create a file named controller.php and put the following content in it: <?php defined('C5_EXECUTE') or die(_("Access Denied.")); class c5bookPackage extends Package { protected $pkgHandle = 'c5book'; protected $appVersionRequired = '5.4.0'; protected $pkgVersion = '1.0'; public function getPackageDescription() { return t("Theme, Templates and Blocks from concrete5 for Beginner's"); } public function getPackageName() { return t("c5book"); } public function install() { $pkg = parent::install(); } } ?> You can create a file named icon.png 97 x 97 pixels with 4px rounded transparent corners. This is the official specification that you have to follow if you want to upload your add-on to the concrete5 marketplace. Once you've created the directory and the mandatory controller, you can go to your dashboard and click on Add Functionality. It looks a lot like a block but when you click on Install, the add-on is going to appear in the packages section. What just happened? The controller we created looks and works a lot like a block controller, which you should have seen and created already. However, let's go through all the elements of the package controller anyway, as it's important that you understand them: pkgHandle: A unique handle for your package. You'll need this when you access your package from code. appVersionRequired: The minimum version required to install the add-on. concrete5 will check that during the installation process. pkgVersion: The current version of the package. Make sure that you change the number when you release an update for a package; concrete5 has to know that it is installing an update and not a new version. getPackageDescription: Returns the description of your package. Use the t-function to keep it translatable. getPackageName: The same as above, just a bit shorter. install: You could remove this method in the controller above, since we're only calling its parent method and don't check anything else. It has no influence, but we'll need this method later when we put blocks in our package. It's just a skeleton for the next steps at the moment. Moving templates into package Remember the templates we've created? We placed them in the top level blocks directory. Worked like a charm but imagine what happens when you create a theme which also needs some block templates in order to make sure the blocks look like the theme? You'd have to copy files into the blocks directory as well as themes. This is exactly what we're trying to avoid with packages. It's rather easy with templates; they work almost anywhere. You just have to copy the folder slideshow from blocks to packages/c5book/blocks, as shown in the following screenshot: This step was even easier than most things we did before. We simply moved our templates into a different directory—nothing else. concrete5 looks for custom templates in different places like: concrete/blocks/<block-name>/templates blocks/<block-name>/templates packages/<package-name>/blocks/<block-name>/templates It doesn't matter where you put your templates, concrete5 will find them. Moving themes and blocks into the package Now that we've got our templates in the package, let's move the new blocks we've created into that package as well. The process is similar, but we have to call a method in the installer which installs our block. concrete5 does not automatically install blocks within packages. This means that we have to extend the empty install method shown earlier. Before we move the blocks into the package you should remove all blocks first. To do this, go to your dashboard, click on Add Functionality, click on the Edit button next to the block you want to move, and click on the Remove button in the next screen. We'll start with the jqzoom block. Please note; removing a block will of course, remove all the blocks you've added to your pages. Content will be lost if you move a block into a package after you've already used it. Time for action – moving jQZoom block into the package Carry out the following steps: As mentioned earlier, remove the jqzoom block from you website by using the Add Functionality section in your dashboard. Move the directory blocks/jqzoom to packages/c5book/blocks. Open the package controller we created a few pages earlier; you can find it at packages/c5book/controller.php. The following snippet shows only a part of the controller, the install method. The only thing you have to do is insert the highlighted line: public function install() { $pkg = parent::install(); // install blocks BlockType::installBlockTypeFromPackage('jqzoom', $pkg); } Save the file and go to your dashboard again. Select Add Functionality and locate the c5book package; click on Edit and then Uninstall Package and confirm the process on the next screen. Back on the Add Functionality screen, reinstall the package again, which will automatically install the block. What just happened? Besides moving files, we only had to add a single line of code to our existing package controller. This is necessary, because blocks within packages aren't automatically installed. When installing a package, only the install method of the controller is called, exactly the place where we hook into and install our block. The installBlockTypeFromPackage method takes two parameters: The block handle and the package object. However, this doesn't mean that packages behave like namespaces. What does this mean? A block is connected to a package. This is necessary in order to be able to uninstall the block when removing the package along with some other reasons. Even though there's a connection between the two objects, a block handle must be unique across all packages. You've seen that we had to remove and reinstall the package several times while we only moved a block. At this point, it probably looks a bit weird to do that, especially as you're going to lose some content on your website. However, when you're more familiar with the concrete5 framework, you'll usually know if you're going to need a package and make that decision before you start creating new blocks. If you're still in doubt, don't worry about it too much and create a package and not just a block. Using a package is usually the safest choice. Don't forget that all instances of a block will be removed from all pages when you uninstall the block from your website. Make sure your package structure doesn't change before you start adding content to your website. Time for action - moving the PDF block into the package Some blocks depend on helpers, files and libraries, which aren't in the block directory. The PDF generator block is such an example. It depends on a file found in the tools directory in the root of your concrete5 website. How do we include such a file in a package? Move the pdf directory from blocks to packages/c5book/blocks since we also want to include the block in the package. Locate the c5book directory within packages and create a new subdirectory named tools. Move generate_pdf.php from tools to packages/c5book/tools. Create another directory named libraries in packages/c5book. Move the mpdf50 from libraries to packages/c5book/libraries. As we've moved two objects, we have to make sure our code looks for them in the right place. Open packages/c5book/tools/generate.php and look for Loader::library at the beginning of the file. We have to add a second parameter to Loader::library, as shown here: <?php defined('C5_EXECUTE') or die(_("Access Denied.")); Loader::library('mpdf50/mpdf', 'c5book'); $fh = Loader::helper('file'); $header = <<<EOT <style type="text/css"> body { font-family: Helvetica, Arial; } h1 { border-bottom: 1px solid black; } </style> EOT; Next, open packages/c5book/blocks/pdf/view.php. We have to add the package handle as the second parameter to make sure the tool file is loaded from the package. <!--hidden_in_pdf_start--> <?php defined('C5_EXECUTE') or die(_('Access Denied.')); $nh = Loader::helper('navigation'); $url = Loader::helper('concrete/urls'); $toolsUrl = $url->getToolsURL('generate_pdf', 'c5book'); $toolsUrl .= '?p=' . rawurlencode($nh->getLinkToCollection($this- >c, true)); echo "<a href="{$toolsUrl}">PDF</a>"; ?> <!--hidden_in_pdf_end--> What just happened? In the preceding example, we put got a file in the tools directory and a PDF generator in the libraries directory, which we had to move as well. Even at the risk of saying the same thing several times: A package can contain any element of concrete5—libraries, tools, controllers, images, and so on. By putting all files in a single package directory, we can make sure that all files are installed at once, thus making sure all dependencies are met. Nothing has changed beside the small changes we've made to the commands, which access or load an element. A helper behaves like a helper, no matter where it's located. Have a go hero – move more add-ons We've moved two different blocks into our new package, along with the slideshow block templates. These aren't all blocks we've created so far. Try to move all add-ons we've created into our new package. If you need more information about that process, have a look at the following page: http://www.concrete5.org/documentation/developers/system/packages/
Read more
  • 0
  • 0
  • 3230

article-image-flash-game-development-creation-complete-tetris-game
Packt
25 Mar 2011
10 min read
Save for later

Flash Game Development: Creation of a Complete Tetris Game

Packt
25 Mar 2011
10 min read
Tetris features shapes called tetrominoes, geometric shapes composed of four squared blocks connected orthogonally, that fall from the top of the playing field. Once a tetromino touches the ground, it lands and cannot be moved anymore, being part of the ground itself, and a new tetromino falls from the top of the game field, usually a 10x20 tiles vertical rectangle. The player can move the falling tetromino horizontally and rotate by 90 degrees to create a horizontal line of blocks. When a line is created, it disappears and any block above the deleted line falls down. If the stacked tetrominoes reach the top of the game field, it's game over. Defining game design This time I won't talk about the game design itself, since Tetris is a well known game and as you read this article you should be used to dealing with game design. By the way, there is something really important about this game you need to know before you start reading this article. You won't draw anything in the Flash IDE. That is, you won't manually draw tetrominoes, the game field, or any other graphic assets. Everything will be generated on the fly using AS3 drawing methods. Tetris is the best game for learning how to draw with AS3 as it only features blocks, blocks, and only blocks. Moreover, although the game won't include new programming features, its principles make Tetris the hardest game of the entire book. Survive Tetris and you will have the skills to create the next games focusing more on new features and techniques rather than on programming logic. Importing classes and declaring first variables The first thing we need to do, as usual, is set up the project and define the main class and function, as well as preparing the game field. Create a new file (File | New) then from New Document window select Actionscript 3.0. Set its properties as width to 400 px, height to 480 px, background color to #333333 (a dark gray), and frame rate to 30 (quite useless anyway since there aren't animations, but you can add an animated background on your own). Also, define the Document Class as Main and save the file as tetris.fla. Without closing tetris.fla, create a new file and from New Document window select ActionScript 3.0 Class. Save this file as Main.as in the same path you saved tetris.fla. Then write: package { import flash.display.Sprite; import flash.utils.Timer; import flash.events.TimerEvent; import flash.events.KeyboardEvent; public class Main extends Sprite { private const TS_uint=24; private var fieldArray:Array; private var fieldSprite:Sprite; public function Main() { // tetris!! } } } We already know we have to interact with the keyboard to move, drop, and rotate tetrominoes and we have to deal with timers to manage falling delay, so I already imported all needed libraries. Then, there are some declarations to do: private const TS_uint=24; TS is the size, in pixels, of the tiles representing the game field. It's a constant as it won't change its value during the game, and its value is 24. With 20 rows of tiles, the height of the whole game field will be 24x20 = 480 pixels, as tall as the height of our movie. private var fieldArray:Array; fieldArray is the array that will numerically represent the game field. private var fieldSprite:Sprite; fieldSprite is the DisplayObject that will graphically render the game field. Let's use it to add some graphics. Drawing game field background Nobody wants to see an empty black field, so we are going to add some graphics. As said, during the making of this game we won't use any drawn Movie Clip, so every graphic asset will be generated by pure ActionScript. The idea: Draw a set of squares to represent the game field. The development: Add this line to Main function: public function Main() { generateField(); } then write generateField function this way: private function generateField():void { fieldArray = new Array(); fieldSprite=new Sprite(); addChild(fieldSprite); fieldSprite.graphics.lineStyle(0,0x000000); for (var i_uint=0; i<20; i++) { fieldArray[i]=new Array(); for (var j_uint=0; j<10; j++) { fieldArray[i][j]=0; fieldSprite.graphics.beginFill(0x444444); fieldSprite.graphics.drawRect(TS*j,TS*i,TS,TS); fieldSprite.graphics.endFill(); } } } Test the movie and you will see: The 20x10 game field has been rendered on the stage in a lighter gray. I could have used constants to define values like 20 and 10, but I am leaving it to you at the end of the article. Let's see what happened: fieldArray = new Array(); fieldSprite=new Sprite(); addChild(fieldSprite); These lines just construct fieldArray array and fieldSprite DisplayObject, then add it to stage as you have already seen a million times. fieldSprite.graphics.lineStyle(0,0x000000); This line introduces a new world called Graphics class. This class contains a set of methods that will allow you to draw vector shapes on Sprites. lineStyle method sets a line style that you will use for your drawings. It accepts a big list of arguments, but at the moment we'll focus on the first two of them. The first argument is the thickness of the line, in points. I set it to 0 because I wanted it as thin as a hairline, but valid values are 0 to 255. The second argument is the hexadecimal color value of the line, in this case black. Hexadecimal uses sixteen distinct symbols to represent numbers from 0 to 15. Numbers from zero to nine are represented with 0-9 just like the decimal numeral system, while values from ten to fifteen are represented by letters A-F. That's the way it is used in most common paint software and in the web to represent colors. You can create hexadecimal numbers by preceding them with 0x. Also notice that lineStyle method, like all Graphics class methods, isn't applied directly on the DisplayObject itself but as a method of the graphics property. for (var i_uint=0; i<20; i++) { ... } The remaining lines are made by the classical couple of for loops initializing fieldArray array in the same way you already initialized all other array-based games, and drawing the 200 (20x10) rectangles that will form the game field. fieldSprite.graphics.beginFill(0x444444); beginFill method is similar to lineStyle as it sets the fill color that you will use for your drawings. It accepts two arguments, the color of the fill (a dark gray in this case) and the opacity (alpha). Since I did not specify the alpha, it takes the default value of 1 (full opacity). fieldSprite.graphics.drawRect(TS*j,TS*i,TS,TS); With a line and a fill style, we are ready to draw some squares with drawRect method, that draws a rectangle. The four arguments represent respectively the x and y position relative to the registration point of the parent DisplayObject (fieldSprite, that happens to be currently on 0,0 in this case), the width and the height of the rectangle. All the values are to be intended in pixels. fieldSprite.graphics.endFill(); endFill method applies a fill to everything you drew after you called beginFill method. This way we are drawing a square with a TS pixels side for each for iteration. At the end of both loops, we'll have 200 squares on the stage, forming the game field. Drawing a better game field background Tetris background game fields are often represented as a checkerboard, so let's try to obtain the same result. The idea: Once we defined two different colors, we will paint even squares with one color, and odd squares with the other color. The development: We have to modify the way generateField function renders the background: private function generateField():void { var colors_Array=new Array("0x444444","0x555555");"); fieldArray = new Array(); var fieldSprite_Sprite=new Sprite(); addChild(fieldSprite); fieldSprite.graphics.lineStyle(0,0x000000); for (var i_uint=0; i<20; i++) { fieldArray[i]=new Array(); for (var j_uint=0; j<10; j++) { fieldArray[i][j]=0; fieldSprite.graphics.beginFill(colors[(j%2+i%2)%2]); fieldSprite.graphics.drawRect(TS*j,TS*i,TS,TS); fieldSprite.graphics.endFill(); } } } We can define an array of colors and play with modulo operator to fill the squares with alternate colors and make the game field look like a chessboard grid. The core of the script lies in this line: fieldSprite.graphics.beginFill(colors[(j%2+i%2)%2]); that plays with modulo to draw a checkerboard. Test the movie and you will see: Now the game field looks better. Creating the tetrominoes The concept behind the creation of representable tetrominoes is the hardest part of the making of this game. Unlike the previous games you made, such as Snake, that will feature actors of the same width and height (in Snake the head is the same size as the tail), in Tetris every tetromino has its own width and height. Moreover, every tetromino but the square one is not symmetrical, so its size is going to change when the player rotates it. How can we manage a tile-based game with tiles of different width and height? The idea: Since tetrominoes are made by four squares connected orthogonally (that is, forming a right angle), we can split tetrominoes into a set of tiles and include them into an array. The easiest way is to include each tetromino into a 4x4 array, although most of them would fit in smaller arrays, it's good to have a standard array. Something like this: Every tetromino has its own name based on the alphabet letter it reminds, and its own color, according to The Tetris Company (TTC), the company that currently owns the trademark of the game Tetris. Just for your information, TTC sues every Tetris clone whose name somehow is similar to "Tetris", so if you are going to create and market a Tetris clone, you should call it something like "Crazy Bricks" rather than "Tetriz". Anyway, following the previous picture, from left-to-right and from top-to-bottom, the "official" names and colors for tetrominoes are: I—color: cyan (0x00FFFF) T—color: purple (0xAA00FF) L—color: orange (0xFFA500) J—color: blue (0x0000FF) Z—color: red (0xFF0000) S—color: green (0x00FF00) O—color: yellow (0xFFFF00) The development: First, add two new class level variables: private const TS_uint=24; private var fieldArray:Array; private var fieldSprite:Sprite; private var tetrominoes:Array = new Array(); private var colors_Array=new Array(); tetrominoes array is the four-dimensional array containing all tetrominoes information, while colors array will store their colors. Now add a new function call to Main function: public function Main() { generateField(); initTetrominoes(); } initTetrominoes function will initialize tetrominoes-related arrays. private function initTetrominoes():void { // I tetrominoes[0]=[[[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]], [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]]]; colors[0]=0x00FFFF; // T tetrominoes[1]=[[[0,0,0,0],[1,1,1,0],[0,1,0,0],[0,0,0,0]], [[0,1,0,0],[1,1,0,0],[0,1,0,0],[0,0,0,0]], [[0,1,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]], [[0,1,0,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]]]; colors[1]=0x767676; // L tetrominoes[2]=[[[0,0,0,0],[1,1,1,0],[1,0,0,0],[0,0,0,0]], [[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]], [[0,0,1,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]], [[0,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,0,0]]]; colors[2]=0xFFA500; // J tetrominoes[3]=[[[1,0,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]], [[0,1,1,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]], [[0,0,0,0],[1,1,1,0],[0,0,1,0],[0,0,0,0]], [[0,1,0,0],[0,1,0,0],[1,1,0,0],[0,0,0,0]]]; colors[3]=0x0000FF; // Z tetrominoes[4]=[[[0,0,0,0],[1,1,0,0],[0,1,1,0],[0,0,0,0]], [[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]]]; colors[4]=0xFF0000; // S tetrominoes[5]=[[[0,0,0,0],[0,1,1,0],[1,1,0,0],[0,0,0,0]], [[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]]]; colors[5]=0x00FF00; // O tetrominoes[6]=[[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]]; colors[6]=0xFFFF00; } colors array is easy to understand: it's just an array with the hexadecimal value of each tetromino color. tetrominoes is a four-dimensional array. It's the first time you see such a complex array, but don't worry. It's no more difficult than the two-dimensional arrays you've been dealing with since the creation of Minesweeper. Tetrominoes are coded into the array this way: tetrominoes[n] contains the arrays with all the information about the n-th tetromino. These arrays represent the various rotations, the four rows and the four columns. tetrominoes[n][m] contains the arrays with all the information about the n-th tetromino in the m-th rotation. These arrays represent the four rows and the four columns. tetrominoes[n][m][o] contains the array with the four elements of the n-th tetromino in the m-th rotation in the o-th row. tetrominoes[n][m][o][p] is the p-th element of the array representing the o-th row in the m-th rotation of the n-th tetromino. Such element can be 0 if it's an empty space or 1 if it's part of the tetromino. There isn't much more to explain as it's just a series of data entry. Let's add our first tetromino to the field.
Read more
  • 0
  • 0
  • 16481

article-image-nginx-http-server-faqs
Packt
25 Mar 2011
4 min read
Save for later

Nginx HTTP Server FAQs

Packt
25 Mar 2011
4 min read
  Nginx HTTP Server Adopt Nginx for your web applications to make the most of your infrastructure and serve pages faster than ever         Read more about this book       (For more resources on this subject, see here.) Q: What is Nginx and how is it pronounced?A: Nginx, is a lightweight HTTP server originating from Russia— pronounced as "engine X". Q: From where can one download and find resources related to Nginx?A: Although Nginx is a relatively new and growing project, there are already a good number of resources available on the World Wide Web (WWW) and an active community of administrators and developers. The official website, which is at www.nginx.net, is rather simple and does not provide much information or documentation, other than links for downloading the latest versions. On the contrary, you will find a lot of interesting documentation and examples on the official wiki—wiki.nginx.org. (Move the mouse over the image to enlarge it.) Q: Which different versions are currently available?A: There are currently three version branches on the project: Stable version: This version is usually recommended, as it is approved by both developers and users, but is usually a little behind the development version above. The current latest stable version is 0.7.66, released on June 07, 2010. Development version: This is the the latest version available for download. Although it is generally solid enough to be installed on production servers, you may run into the occasional bug. As such, the stable version is recommended, even though you do not get to use the latest features. The current latest development version is 0.8.40, released on June 07, 2010. Legacy version: If for some reason you are interested in looking at the older versions, you will find two of them. There's a legacy version and a legacy stable version, respectively coming as 0.5.38 and 0.6.39 releases. Q: Are the development versions stable enough to be used on production servers?A: Cliff Wells, founder and maintainer of the nginx.org wiki website and community, believes so—"I generally use and recommend the latest development version. It's only bit me once!". Early adopters rarely report critical problems. It is up to you to select the version you will be using on your server. The Nginx developers have decided to maintain backwards compatibility in new versions. You can find more information on version changes, new additions, and bug fixes in the dedicated change log page on the official website. Q: How can one Upgrade Nginx without loosing a single connection?A: There are many situations where you need to replace the Nginx binary, for example, when you compile a new version and wish to put it in production or simply after having enabled new modules and rebuilt the application. What most administrators would do in this situation is stop the server, copy the new binary over the old one, and start Nginx again. While this is not considered to be a problem for most websites, there may be some cases where uptime is critical and connection losses should be avoided at all costs. Fortunately, Nginx embeds a mechanism allowing you to switch binaries with uninterrupted uptime—zero percent request loss is guaranteed if you follow these steps carefully: Replace the old Nginx binary (by default, /usr/local/nginx/sbin/nginx) with the new one. Find the pid of the Nginx master process, for example, with ps x grep nginx | grep master| or by looking at the value found in the pid file. Send a USR2 (12) signal to the master process—kill –USR2 ***, replacing *** with the pid found in step 2. This will initiate the upgrade by renaming the old .pid file and running the new binary. Send a WINCH (28) signal to the old master process—kill –WINCH ***, replacing *** with the pid found in step 2. This will engage a graceful shutdown of the old worker processes. Make sure that all the old worker processes are terminated, and then send a QUIT signal to the old master process—kill –QUIT ***, replacing *** with the pid found in step 2.
Read more
  • 0
  • 0
  • 10282

article-image-tips-and-tricks-process-modeling-open-text-metastorm
Packt
25 Mar 2011
3 min read
Save for later

Tips and Tricks for Process Modeling in Open Text Metastorm

Packt
25 Mar 2011
3 min read
  Open Text Metastorm ProVision® 6.2 Strategy Implementation Create and implement a successful business strategy for improved performance throughout the whole enterprise     Identify and engage the process owner Tip: Identifying and engaging the process owner in the improvement process is important. Unless the process owner is fully committed to process improvement, it will not happen and any attempts will be met with resistance. Failure to engage a committed process owner guarantees failure to improve the process in the long term. The people who understand the process the best are those engaged in it, either as customers, suppliers, or staff who run the process. Getting engagement from everyone who has responsibility is the best way to deliver transformation. The appreciative inquiry method is an innovative way of doing this, by engaging individuals in organizational renewal, change, and focused performance through the discovery of what is good in the organization. This leads to my second top tip.   Talk to the people who deal with errors Tip: It is good to engage the process staff from the beginning, especially those who fix mistakes. Ensure their participation in the process improvement. They know what is necessary to fix the mistake, so they can help design to prevent mistakes from occurring. Managers frequently do not know how work is really done. They may think they do, but in reality the work is often done other ways. Look for informal processes based on relationships and local knowledge, which are often more important and effective than the formal, documented process. Capture the current "What" in detail but not the "How" Tip: The two most important aspects of a process are what and how. The question of what is the information that is required to run the process has its answer as data. Whereas, the question of how is value created and enhanced has its answer as a process. If the current process is broken, the new process will probably reuse the data but not the process itself. It is only necessary to model the current process at a high level. Ask why at least five times to get to the root cause of the process problem.   Reduce moments of truth Tip: The customer judges a process on the experience when they engage with the organization. For any given transaction, strive to limit the number of contacts with a client. Think of eBay's one-click process for ordering a book. Isn't that preferable than filling out a long form? Seek to minimize these moments. Add value to the customer at these moments while reducing effort for them; in short simplify any process for your customers. Reduce handoffs Tip: Many problems occur at hand-off from one person to another. The fewer the handoffs, the less opportunity there is for delay and miscommunication. Where handoffs are essential, you can consider parallel processing rather than sequential.
Read more
  • 0
  • 0
  • 1501
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 €18.99/month. Cancel anytime
article-image-aspnet-4-social-networking-implementing-complete-messaging-system
Packt
25 Mar 2011
12 min read
Save for later

ASP.NET 4 Social Networking: Implementing a Complete Messaging System

Packt
25 Mar 2011
12 min read
Problem A basic messaging system should be able to manage messages, senders and recipients, folders that contain the messages, and email notifications. In our case, we are going to try and keep things simple where it makes sense to do so, but in one area, we will do things in a more complicated way simply because it will result in less wear and tear on the overall system. This is how the messages will be delivered to the users. Rather than following a standard email messaging system where each person gets a physical copy of a message, we are going to build our system in the same way that the MS Exchange server works. We are going to make one copy of a message and subscribe users to that message. So rather than have 50 messages for 50 recipients, we will have one message and 50 recipient subscriptions. The next problem lies in building a WYSIWYG (what you see is what you get) messaging editor. For this feature, there are many open source WYSIWYG editors; we will use one of those to save us a bit of time. We will be using one of the popular editors—X INHA. This editor can be downloaded for free here at http://xinha.webfactional.com/. You may have seen this editor already as it is widely used across many popular community sites. Design Let's take a look at the design of these features. Messages Messages are the core of any messaging system. Generally, a message would contain details like the sender of the message, receiver of the message, and other metadata like time sent, server from where it was sent, etc. and the message, subject, and body. In our case, the message will contain the sender, subject, body, and the data sent. It will also contain one additional field, i.e. the type of message (message, friend request, and so on). We will need to create a page that allows a user to compose a new message (as seen in the image at the start of this article). This interface should also allow a user to add his/her friends easily rather than force them to remember everyone. Also, this interface should allow a user to quickly snap together some HTML without ever having to look at HTML. This can be accomplished with a WYSIWYG editor. Recipients As we have already discussed that we are going to move some of the complexity away from the message, following a subscription model instead, you will find that most of the complexity of this system lies around the recipient concepts. In this case, the recipient subscription is what will be contained in a folder and will have a read status. With this design, we will remove some of the burden from the database. The overhead of doing this of course means that we now need to manage our data closely, as it is kept in many pieces. A more simple design that would result in more copies of data to be managed would be to create one message for each recipient. This is easier as each message can easily be deleted and moved around without having to worry about the copies of that message of the other recipients. Having said that, if the message is quite large, and more importantly if we were to allow file attachments, all the copies of the messages would be identical for each recipient. This would quickly bloat your database! Solution Now let's take a look at our solution. Implementing the database First let's take a look at what tables are needed: Messages A message will primarily be made up of the subject and its body. In addition to that we will need to know what type of message we are sending so that we can do some more fancy things in the UI down the road. In addition to this, we are going to maintain who owns/created the message at this level. There aren't really any major complexities to note here other than the fact that the Body is made up of a varchar(MAX) data type. If you feel this is too large for your system, feel free to make it anything you are comfortable with. The value you eventually use will drive the message for your system. MessageTypes Message Types allows us to assign a type to our messages. This is purely a lookup table that will allow us to know what the types are during queries. We will keep a list of enums in the code to make the lookups easier from that end. MessageRecipients A message recipient is simply the receiving party to the message. But as we try to minimize the data that we manage in our system, the message recipient is also a very important part of the message. In our case, it is the receiving party as well as all the things that the receiving party does with their subscription of that message. We will use this subscription to denote which folder the receiver is keeping the message in, and whether the receiver has read the message or not. Also, if the receiver chooses to delete the message, he/she can just delete the subscription to a message (unless they are the last subscription, in which case we will delete the message as well). The SQL for this subscription is actually quite straightforward. It tracks a relationship to the message, a relationship to the receiver, which folder the subscription is currently in, and the status of the message for this receiver. MessageRecipientTypes The message recipient type allows us to track the receiver of this message addressed in the TO, CC, or BCC fields. Initially, our interface will only have a TO field. We should add this bit of metadata though just in case we want to expand our capabilities down the road! This is another example of a lookup table that we might need to use in the SQL queries. In our case, we will have an enum defined that maintains this lookup for us on the code side. MessageStatusTypes MessageStatusTypes allows us to track what a recipient is doing with his/her copy of the message, whether they have read the message, replied to the message, and so on. This is primarily so that we can change the UI to refiect its status to the recipient. However, we could also create a dashboard down the road for the senders of the messages to know whether their message was read or not and by whom (think of all the big brother things one could do...but probably should not do!). MessageFolders MessageFolders in our first round of implementation will simply hold copies of new messages in the Inbox and copies of sent messages in the Sent folder. We will also have a trash folder and a spam folder. That said, we always wanted to build a system with the future in mind if it doesn't require a lot of extra work, and so we have also baked in the concept of a user being able to create and manage his/her own folders. Therefore, rather than just see the MessageFolders table as another lookup table, you will see that there is an IsSystem fiag to denote which folders are to be seen system-wide. And you will see an AccountID column for custom folders so that we know who owns which folders. Creating the relationships Once all the tables are created, we can create the relationships. For this set of tables, we have relationships between the following tables: Messages and MessageRecipients Messages and Accounts Messages and MessageTypes MessageRecipients and MessageRecipientTypes MessageRecipients and MessageFolders MessageRecipients and MessageStatusTypes Setting up the data access layer The data access layer in this case is very straightforward. Open up your Fisharoo.edmx file and add all of your new message-oriented tables. Once you save this, you should now have a list of new domain objects in your arsenal (see the previous screenshot). Building repositories With these new tables come some additional repositories. We will create the following repositories. MessageRepository MessageRecipientRepository MessageFolderRepository A detailed creation of repositories is out of the scope of this article. We will create a method for selecting a single entity by ID, a group of entities by their parents, saving entities, and deleting entities. Having said that, there are a couple of methods that have something special in the set of repositories. As we are using message subscriptions, we don't necessarily want to delete recipients haphazardly. We may want to delete a recipient, and if that recipient is the last recipient with a subscription to a message, we may also want to delete the message. On the other end of the spectrum, if we do delete a message, we may also want to remove all the recipient subscriptions. In addition to these different ways of deleting data, we will also run into a scenario where selecting a single entity from our repositories won't be quite good enough. So in this case, we have created an aggregate class that will allow us to select several entities at once for use in our inbox scenarios. MessageRepository When we think of a standard inbox, we know that we need to see the messages that we have, who sent them, when they were sent, and at least the subject of their message. In this case, we have discussed two different entities here. When we think about the fact that we also need to know who they were sent to, we have added a third entity. While we could run three separate queries for this data, it would be better for us to run one query (as we would have done in the old days) and return the data that we need in one shot. What do we do? In this case, we need to create an aggregate. This is a class that contains other entities. We will therefore create a MessageWithRecipient class that will contain the sender's account info, the message, and the recipient. This should provide us with enough data to represent messages in our inbox view later. Before we write any queries, we first need to create the aggregate. //Fisharoo/DataAccess/MessageWithRecipient.cs namespace Fisharoo.DataAccess { public class MessageWithRecipient { public Account Sender { get; set; } public Message Message { get; set; } public MessageRecipient MessageRecipient{ get; set; } } } With this aggregate in place we can now turn our attention to the repository that will get all this data for us. //Fisharoo/DataAccess/Repositories/MessageRepository.cs public List<MessageWithRecipient> GetMessagesByAccountID(Int32 AccountID, Int32 PageNumber, MessageFolders Folder) { List<MessageWithRecipient> result = new List<MessageWithRecipient>(); using(FisharooDataContext dc = conn.GetContext()) { IEnumerable<MessageWithRecipient> messages = (from r in dc.MessageRecipients join m in dc.Messages on r.MessageID equals m.MessageID join a in dc.Accounts on m.SentByAccountID equals a.AccountID where r.AccountID == AccountID && r.MessageFolderID == (int)Folder orderby m.CreateDate descending select new MessageWithRecipient() { Sender = a, Message = m, MessageRecipient = r }).Skip((PageNumber - 1)*10).Take(10); result = messages.ToList(); } return result; } This is a fun method! This method involves selecting a list of our MessageWithRecipient aggregate objects. The LINQ query is joining all the tables that we need and selecting a new instance of the MessageWithRecipient aggregate, that is then populated with the three classes that we need in the aggregate. Additionally, we have introduced some paging logic with the .Skip and .Take methods to produce a subset of the MessageWithRecipient objects. In addition to the selection method above, we also need to discuss the delete method for this repository. As we have the data holding a subscription to our message data, it is important that we first remove all the subscriptions prior to removing the message itself. //Fisharoo/DataAccess/Repositories/MessageRepository.cs public void DeleteMessage(Message message) { using (FisharooDataContext dc = conn.GetContext()) { IEnumerable<MessageRecipient> recipients = dc.MessageRecipients .Where(mr => mr.MessageID == message.MessageID); foreach (MessageRecipient mr in recipients) { dc.MessageRecipients.DeleteObject(mr); } dc.Messages.DeleteObject(message); dc.SaveChanges(); } } This is easily accomplished by retrieving all the MessageRecipients for the needed MessageID from the MessageRecipients in DataContext. Once we have the list, we iterate over each recipient and remove it from DataContext's MessageRecipients list. Finally, we delete the message and save changes. MessageRecipientRepository The message recipient repository is considerably easier. It simply has an altered delete statement to adjust for the fact that if we delete the last subscription to a message, it will amount to deleting the message. //Fisharoo/DataAccess/Repositories/MessageRecipientRepository.cs public void DeleteMessageRecipient(MessageRecipient messageRecipient) { using (FisharooDataContext dc = conn.GetContext()) { dc.MessageRecipients.DeleteObject(dc.MessageRecipients.Where (mr=> mr.MessageRecipientID.Equals (messageRecipient.MessageRecipientID)) .FirstOrDefault()); //if the last recipient was deleted //...also delete the message int RemainingRecipientCount = dc.MessageRecipients.Where(mr => mr.MessageID == messageRecipient.MessageID).Count(); if (RemainingRecipientCount == 0) { dc.Messages.DeleteObject(dc.Messages.Where(m => m.MessageID == messageRecipient.MessageID). FirstOrDefault()); } dc.SaveChanges(); } } In this method, we delete the recipient in question. We then get a count of the remaining recipients for the message, which has the last recipient removed. If that count is zero, then there are no more recipients remaining for that message. In that case we perform a delete on that message and remove it from the system as well.
Read more
  • 0
  • 0
  • 4213

article-image-questions-answers-mariadbs-michael-monty-widenius-founder-mysql-ab
Packt
25 Mar 2011
9 min read
Save for later

Questions & Answers with MariaDB's Michael "Monty" Widenius- Founder of MySQL AB

Packt
25 Mar 2011
9 min read
1. Packt: Firstly, I would like to thank you for taking part in this Q&A and we expect great things from the MariaDB community in the near future. How important do you think the various communities of Open Source projects are to the progression and growth of its software? Monty Widenius: In most cases Open Source project will succeed or fail totally depending on how they manage to grow their community. To succeed you need to spend a lot of resources to work with your community and ensure that their needs are taken care of. This is why developers at Monty Program Ab spend up to 50 % of their time interacting with the community and creating things that they need.   2. Packt: For those that do not know, tell us about your background. How long has MariaDB been around? How did the creation of MariaDB come about? Monty Widenius: I created MySQL in 1994, based on code that I had developed since 1982. When we released MySQL to the public in 1995, the intention was to do something good for the Free software community (Open Source was not yet coined then) and do it in such a way that we would get enough revenue to be able to do it "full time and continue forever". I think we were quite successful with MySQL and when it was sold to Sun in 2008 I was sure it had found a good home. However when Oracle announced it would buy Sun In 2009 and the sale was conditioned that 'if they didn't get MySQL, the deal would be off' I got worried about the future of MySQL as a free database and created MariaDB. This was done to ensure that the MySQL project would continue, even if under another name and that the people that had created MySQL and didn't want to work at Oracle would have a good home to come to. MariaDB was thus created in April 2010 and is driven by my company Monty Program Ab. Currently Monty Program Ab employees are mostly made up of the original top core developers at MySQL AB, including the full optimizer team and all MySQL architects, so we are quite confident that we are able to keep on developing MariaDB in a good phase.     3. Packt: How would you describe the growing MariaDB community and the MySQL community that came before it? Monty Widenius: First some background; The problem with competing with MySQL is that it's very hard to get a new name out as everyone that is using MySQL uses www.mysql.com as their first step when they want to find out what is happening in the MySQL world. What we have done is to ensure that MariaDB is represented in all MySQL and Open Source conferences (which causes a lot of traveling for the MariaDB team). Now, after almost 2 years, we have seen a growing usage of MariaDB at the grassroot level and it's starting to spread more rapidly. We are now part of SuSE linux, Centos and we are working with the rest of the Linux distributions to get into there too. We have also seen several big users of MySQL switching to use MariaDB, some of which can be found at http://kb.askmonty.org/v/mariadb-case-studies. The release of MariaDB 5.2 in December caused a big growth in our downloads; We now have +10,000 per week from our website in addition to those that are using MariaDB from Linux distributions or other mirrors. The future growth of MariaDB is largely depending on the threat Oracle poses to MySQL. The fact that Oracle has lost all the main developers of MySQL and is not capable of doing any notable new development is starting to take its toll. Oracle is also planning to introduce close source features into the MySQL enterprise version and license changes to the MySQL community version will also assist in the growth of MariaDB. The MySQL community was largely an end user community and the developer community was largely forgotten (at least since 2001). What we are doing with MariaDB is to make it easy for other developers to join the MariaDB project and that way make MariaDB again a 'practical database' that is developed together with the community. In other words, with MariaDB we are going back to the roots that made MySQL successful.   4. Packt: What would you describe as the current strengths and weaknesses of the MariaDB community? Monty Widenius: The MariaDB developer community is already stronger than the MySQL developer community; we have people from many companies developing MariaDB together and we can do development more rapidly than MYSQL as we have the best people leading the development. Our weakness is that we have smaller end users base than MySQL and will have a hard time getting funded projects because the decision makers in the big companies are not aware of us yet. This is something that is slowly getting corrected, but is still holding us back from our true potential.   5. Packt: How many code contributors does the MariaDB project receive on a monthly/yearly basis? Monty Widenius: We have weekly code contributions from different contributors to MariaDB. The 5.2 release was very large and parts of the release are completed by outside contributions. You can find my blog here for more details.   6. Packt: How has MariaDB encouraged its community to evangelize the software? Monty Widenius: We have started several projects to get the community active: The Askmonty knowledgebase is a knowledgebase project with the intention to work with the community to get everything related to MariaDB and MySQL documented. We are about to launch the Community Ambassadors program to make it easier for the community to setup MariaDB and MySQL local groups. Everything we do in Monty Program Ab regarding MariaDB is done publicly; the development email lists, our IRC channel, roadmaps and even our own company developer meetings are open to the public.   7. Packt: 2011 will be a big year for the MariaDB community, how does the project expect to grow in 2011 and build on the growth experienced? Monty Widenius: In 2011, MariaDB should be in all major Linux distributions which will help us to reach more end users. We will also release MariaDB 5.3 and MariaDB 5.5 that includes major new speed improvements in the MySQL optimizer and new features, like microsecond support and dynamic columns, that people have waited years to get in MySQL. The launch of SkySQL is also helping us a lot as now we have finally a company who can do full front line support of MariaDB (in addition to MySQL support) while we do third level support for their customers. This will provide us with more revenue which will allow us to do even more development.   8. Packt: As you may know, we’ve recently announced that we’ve hit the landmark of over $300k donated to Open Source projects, how important are donations of this kind to the MariaDB community? Monty Widenius: At this point in time Monty Program Ab is mostly living on donations, of which I am the largest donator. I have good reason to believe that 2011 will be a turning point where Monty Program Ab will finally be profitable. However, we are still hoping to get donations as this will allow us to grow more rapidly (which will directly benefit all MariaDB and MySQL users). As Monty Program Ab doesn't have any investors (the company is owned by its employees) and all money we get is used to pay developers and hire new ones to work on MariaDB, we are the logical choice for donations for anyone that wants to ensure that MySQL under the name of MariaDB will be kept alive and actively developed. When it comes to the future of MariaDB, I am quite confident that we at Monty Program Ab will succeed in driving this forward for a long time. If by some unforeseen reason we were to fail, all parts of MariaDB is in the community and it's easy for someone else to take over and continue. Even for the MariaDB trademark we have made a provision that if Monty Program Ab would not actively develop MariaDB anymore it will be automatically transferred to a non-profit organization that the community can work with.   9. Packt: We specialize in refining and distilling advice provided by the community around Open Source projects, into easy to follow specialist information. How important do you expect the sharing of information to be for the MariaDB community? How do you plan to guarantee success of distributing information among MariaDB community in 2011? Monty Widenius: I think that if you are working in the Open Source space it's critical that you are transparent in what you are doing and are willing to share as much information as possible of what you are doing. You should also be helping others in the Open Source world to succeed! When it comes to sharing information about the MariaDB projects, we are heavily relying on the knowledgebase and our active participation in a lot of Open Source conferences and working with the developer community. For the money I got from Sun for MySQL, I have been part of the founding of Open Source capital, an investment company that invests in technical innovated companies that work with large communities (often Open Source ones). We use the experience that we got in creating and growing MySQL to help these companies to reach their true potential. I am also giving talks in a lot of different conferences about Open Source entrepreneurship, to help others find profitable Open Source companies. The next one is on Garum day in Bilbao, Spain on the 16th February.   10. Packt: Thanks for your time Monty, lastly what projects, if any, are you/MariaDB working on at the moment? Monty Widenius:  We are working on getting MariaDB 5.3 and MariaDB 5.5 ready for a stable release. The new major features (in addition to all the new features we already introduced in MariaDB 5.2) are: Significantly better optimizer for complex queries (hash join, non materialized sub queries) that gives a 10x speed improvement for certain queries. Better NoSQL features: Notable faster HANDLER support, HandlerSocket support and dynamic columns (allows you to store columns packed in a blob so that every row in your table can have a different set of columns). Microsecond support Better replication with group commit (reliable and faster) You can read more about this at: http://kb.askmonty.org/v/what-is-mariadb-53. This is the biggest redesign of the MariaDB optimizer in 10 years and it will finally make all sub queries usable in Maria This is the biggest redesign of the MariaDB optimizer in 10 years and it will finally make all sub queries usable in MariaDB.
Read more
  • 0
  • 0
  • 2881

article-image-anatomy-wordpress-plugin
Packt
25 Mar 2011
7 min read
Save for later

Anatomy of a WordPress Plugin

Packt
25 Mar 2011
7 min read
  WordPress 3 Plugin Development Essentials Create your own powerful, interactive plugins to extend and add features to your WordPress site         Read more about this book       WordPress is a popular content management system (CMS), most renowned for its use as a blogging / publishing application. According to usage statistics tracker, BuiltWith (http://builtWith.com), WordPress is considered to be the most popular blogging software on the planet—not bad for something that has only been around officially since 2003. Before we develop any substantial plugins of our own, let's take a few moments to look at what other people have done, so we get an idea of what the final product might look like. By this point, you should have a fresh version of WordPress installed and running somewhere for you to play with. It is important that your installation of WordPress is one with which you can tinker. In this article by Brian Bondari and Everett Griffiths, authors of WordPress 3 Plugin Development Essentials, we will purposely break a few things to help see how they work, so please don't try anything in this article on a live production site. Deconstructing an existing plugin: "Hello Dolly" WordPress ships with a simple plugin named "Hello Dolly". Its name is a whimsical take on the programmer's obligatory "Hello, World!", and it is trotted out only for pedantic explanations like the one that follows (unless, of course, you really do want random lyrics by Jerry Herman to grace your administration screens). Activating the plugin Let's activate this plugin so we can have a look at what it does: Browse to your WordPress Dashboard at http://yoursite.com/wp-admin/. Navigate to the Plugins section. Under the Hello Dolly title, click on the Activate link. You should now see a random lyric appear in the top-right portion of the Dashboard. Refresh the page a few times to get the full effect. Examining the hello.php file Now that we've tried out the "Hello Dolly" plugin, let's have a closer look. In your favorite text editor, open up the /wp-content/plugins/hello.php file. Can you identify the following integral parts? The Information Header which describes details about the plugin (author and description). This is contained in a large PHP /* comment */. User-defined functions, such as the hello_dolly() function. The add_action() and/or add_filter() functions, which hook a WordPress event to a user-defined function. It looks pretty simple, right? That's all you need for a plugin: An information header Some user-defined functions add_action() and/or add_filter() functions In your WordPress Dashboard, ensure that the "Hello Dolly" plugin has been activated. If applicable, use your preferred (s)FTP program to connect to your WordPress installation. Using your text editor, temporarily delete the information header from wpcontent/ plugins/hello.php and save the file (you can save the header elsewhere for now). Save the file. Refresh the Plugins page in your browser. You should get a warning from WordPress stating that the plugin does not have a valid header: Ensure that the "Hello Dolly" plugin is active. Open the /wp-content/plugins/hello.php file in your text editor. Immediately before the line that contains function hello_dolly_get_lyric, type in some gibberish text, such as "asdfasdf" and save the file. Reload the plugins page in your browser. This should generate a parse error, something like: pre width="70"> Parse error: syntax error, unexpected T_FUNCTION in /path/to/ wordpress/html/wp-content/plugins/hello.php on line 16 Author: Listed below the plugin name Author URI: Together with "Author", this creates a link to the author's site Description: Main block of text describing the plugin Plugin Name: The displayed name of the plugin Plugin URI: Destination of the "Visit plugin site" link Version: Use this to track your changes over time Now that we've identified the critical component parts, let's examine them in more detail. Information header Don't just skim this section thinking it's a waste of breath on the self-explanatory header fields. Unlike a normal PHP file in which the comments are purely optional, in WordPress plugin and theme files, the Information Header is required! It is this block of text that causes a file to show up on WordPress' radar so that you can activate it or deactivate it. If your plugin is missing a valid information header, you cannot use it! Exercise—breaking the header To reinforce that the information header is an integral part of a plugin, try the following exercise: After you've seen the tragic consequences, put the header information back into the hello.php file. This should make it abundantly clear to you that the information header is absolutely vital for every WordPress plugin. If your plugin has multiple files, the header should be inside the primary file—in this article we use index.php as our primary file, but many plugins use a file named after the plugin name as their primary file. Location, name, and format The header itself is similar in form and function to other content management systems, such as Drupal's module.info files or Joomla's XML module configurations—it offers a way to store additional information about a plugin in a standardized format. The values can be extended, but the most common header values are listed below: For more information about header blocks, see the WordPress codex at: http://codex.wordpress.org/File_Header. In order for a PHP file to show up in WordPress' Plugins menu: The file must have a .php extension. The file must contain the information header somewhere in it (preferably at the beginning). The file must be either in the /wp-content/plugins directory, or in a subdirectory of the plugins directory. It cannot be more deeply nested. Understanding the Includes When you activate a plugin, the name of the file containing the information header is stored in the WordPress database. Each time a page is requested, WordPress goes through a laundry list of PHP files it needs to load, so activating a plugin ensures that your own files are on that list. To help illustrate this concept, let's break WordPress again. Exercise – parse errors Try the following exercise: Yikes! Your site is now broken. Why did this happen? We introduced errors into the plugin's main file (hello.php), so including it caused PHP and WordPress to choke. Delete the gibberish line from the hello.php file and save to return the plugin back to normal. The parse error only occurs if there is an error in an active plugin. Deactivated plugins are not included by WordPress and therefore their code is not parsed. You can try the same exercise after deactivating the plugin and you'll notice that WordPress does not raise any errors. Bonus for the curious In case you're wondering exactly where and how WordPress stores the information about activated plugins, have a look in the database. Using your MySQL client, you can browse the wp_options table or execute the following query: SELECT option_value FROM wp_options WHERE option_name='active_ plugins'; The active plugins are stored as a serialized PHP hash, referencing the file containing the header. The following is an example of what the serialized hash might contain if you had activated a plugin named "Bad Example". You can use PHP's unserialize() function to parse the contents of this string into a PHP variable as in the following script: <?php $active_plugin_str = 'a:1:{i:0;s:27:"bad-example/bad-example. php";}'; print_r( unserialize($active_plugin_str) ); ?> And here's its output: Array ( [0] => bad-example/bad-example.php )
Read more
  • 0
  • 1
  • 33166

article-image-jquery-14-managing-animations
Packt
23 Mar 2011
7 min read
Save for later

jQuery 1.4: Managing Animations

Packt
23 Mar 2011
7 min read
  jQuery 1.4 Animation Techniques: Beginners Guide Quickly master all of jQuery’s animation methods and build a toolkit of ready-to-use animations using jQuery 1.4         Read more about this book       (For more resources on this subject, see here.) The jQuery object itself also contains several properties that can be useful when working with animations. These include: jQuery.fx.off jQuery.fx.interval The queue is not restricted to storing animation methods; other methods can also be added to the queue. We will only be looking at the queue() method from an animation perspective here. Working with the queue When several effects are chained together, the first effect is begun straight away. The remaining effects are stored as functions in an array in the element's fx queue. As the effects are stored in an array, we can call standard JavaScript array methods on it to manipulate it, and examine its properties to find out additional information about it. We can determine how many functions are in the queue by looking at the length property of the array, or we can call standard functions such as push(), pop(), or reverse() on it to perform various operations on the items (functions) in the array. It is unlikely that this would be required in most normal situations however. An important point to note about the queue is that the first effect method called on an element does not get stored in the queue, so the length of the queue at the start of the operation will always be one less than the total number of effect methods called on the element. The queue executes on a first-in-first-out basis, with the last function stored in the queue executing last. The default fx queue for an animated element will run automatically and each function contained within it will be called automatically by jQuery. The string inprogress is used as the first item in the default fx queue as a flag indicating that the queue is currently being run. A custom queue that we create ourselves will not run automatically and we must ensure that each item in the queue is executed one after the other. jQuery provides several ways of doing this including the dequeue() method, which executes the next function in the queue, and a callback function that we can pass into functions in the queue. We'll look at both of these techniques later in the article. Viewing the queue To view the queue we simply call the queue() method; no arguments are required but we can optionally supply the queue name if it differs from the default fx. When the method is called, it returns an array containing the remaining functions in the queue. The queue() method may be used in the following form: jQuery(elements).queue([queue name], [new queue], [callback]); In addition to the name of the queue, we can also supply either a new queue, or a single callback function. The new queue, if supplied, should take the form of an array of functions. The new queue will replace the existing queue entirely. Passing an empty array to the queue() method will clear the queue. A callback passed to the queue() method will be added to the end of the queue and executed last after the functions originally in the queue. A common use of the queue() method is to look at the length property of the returned array to determine how many functions are left to run; but if we need to, we can also look at each function individually by calling the toString() JavaScript function on any item in the array (except for item 0 which will simply display the string inprogress). Most functions in the returned array are function literals, however, the "next" item in the queue is not available via the queue() method. The contents of item 0 in the default fx queue will always be the string inprogress as this is the animation currently being run. Time for action - viewing the queue Let's look at a basic example of the use of the queue() method and the type of results we can expect to obtain. In the <head> of our template file add the following code: <style> #fader { width:100px; height:100px; background-color:#000; } </style> Finally, in the anonymous function at the bottom of the second <script> element, add the following code: $("#fader").fadeOut(function() { console.log($(this).queue()); }).fadeIn().fadeOut().fadeIn(); Save the page as queue.html.   What just happened?   Typically, we'd use an external stylesheet for any styling, but for a single selector and three rules, it seems pointless creating a separate file. In the script we have four effects chained together to form a simple animation in which our <div> element is simply faded out and back in twice. We provide a callback function as an argument to the first of our effect methods, within which we call the queue() method. You'll need to use a browser that has a console for this example, such as Firefox. Here's what the output looks like in Firebug: In the previous screenshot, we can see that the array making up the queue has been output to the console for us to view. There are three items left in the queue when the method is called. The first item in the array is the string inprogress. The remaining two items are the queued methods that have not yet run. If we wish to see how many functions are left in the queue (including the one that is in progress), we could change the console.log line to this: console.log($(this).queue().length); This code would show the following output in Firebug's console: This time our console shows numerically how many items are left in the queue, as shown in the previous screenshot. We can use other array methods on the queue if we wish (although this would rarely be useful), such as push() or pop() to add or remove items for example. We can also get a single item from the queue if we wish, by adding square braces and an index number after the call to queue(): console.log($(this).queue()[1]); As shown above, this time the value of the second item is output to the console. As I mentioned earlier, we can see the actual contents of the function using the toString() JavaScript function: console.log($(this).queue()[1].toString); Running this code produces the following output: (Move the mouse over the image to enlarge it.) The code shown in the previous screenshot won't make much sense to the casual observer as it's been minified, but it's the contents of jQuery's fadeout() method. Adding a function to the queue Appending a new function to the end of the queue is a trivial matter and we don't even need to use a new method. We just need to pass the new function, or a function reference, to the queue() method as an argument. When we pass a single function into the queue() method and we are working with the default fx queue, jQuery will automatically call the function for us using the dequeue() method. We haven't looked at the dequeue() method yet, but we will cover this a little later in the article.
Read more
  • 0
  • 0
  • 1607
article-image-moodle-20-assessing-your-learners-understanding-science
Packt
23 Mar 2011
12 min read
Save for later

Moodle 2.0: Assessing your Learners' Understanding of Science

Packt
23 Mar 2011
12 min read
  Science Teaching with Moodle 2.0 Create interactive lessons and activities in Moodle to enhance your students' understanding and enjoyment of science         Read more about this book       (For more resources on Moodle 2.0, see here.) One of the biggest things to come out of the UK in terms of modern education practice is Assessment for Learning (AfL). This is a phrase coined by Paul Black and Dylan Wiliam in the late 1990s. If this is the first time you have heard the phrase "assessment for learning" then refer to:Inside the Black Box: Raising standards through classroom assessment King's College, London. Black, P.J. & Wiliam, D. (1998).It's a great place to start and a reference you'll regularly go back to, again and again. Assessment for learning Let's begin by looking at what good assessment is; then we'll go through how you can apply this to your Moodle course. Assessment for learning informs you as to what your students have learned, gives an idea what topics, concepts, or areas they find hard and, most importantly, gives you and them an idea of how to improve. Assessment can unfortunately have a negative effect on people. It can make a huge difference when students are involved in their own assessments, but serves very little purpose when it is used by pupils for comparisons or to boost ego. It is important for learners to understand the reasons behind assessment, whether it is to help them understand something, a summative test designed to award a level of competency, or just a quick review so they can see how they are doing. It is vital, however, that all learners can 'do well' in assessments, which may sound contradictory. Progress is much faster for learners who are confident, secure, and happy with trying new ideas. Without that, little learning can happen. This may mean creating different levels of assessment for a particular task so that all pupils can access it. Assessment comes in three main types—teacher/tutor assessment, self assessment, and peer assessment. The latter two will be covered in later articles. The focus of this article will be teacher assessment to provide feedback to students. In the next article, we will be drilling down deeper into the analysis of assessments to inform your teaching. Feedback The most important thing a teacher can provide is to let their students know how they are doing. Moodle is great for this. You could, for instance, create a multiple-choice quiz and give your learners detailed responses for every incorrect answer, even giving them a link to another resource or website that would help them learn from their mistakes. The feedback cycle The feedback cycle is something you could use when creating tasks designed to provide feedback to your students on their learning. The following image shows you the three phases of the feedback cycle: Learning is a continual process of attempting tasks, finding out if you can do them, and then working out what you need to do to get even better. If you want to find out more about the current teaching methodologies in the UK, there are some great videos and good practice at https://www.ssatrust.org.uk/Pages/home.aspx. Using ratings in forums It is important that students get feedback on their work. Without it, they will never know how to improve. This feedback could be from the teacher, by reflection after comparing their work to some criteria, or from their peers. This last reason is why, more often than not, it is useful to include some sort of ratings in the forums you set up, along with comments for improvement. Why use ratings? It can be a good idea initially to force pupils to use the rating systems in forums. To do this, you could set some specific homework, asking them to post their replies to a discussion point. It should require them to read and reply to at least two other posts, providing ratings and written feedback. Interestingly, pupils tend to be very fair and will often do much more than the minimum. It's a good idea to be quite specific when using ratings. For instance, what does 5 out of 5 actually mean? Criterionbased judgments give the learner a much better idea of specifically what needs to be done to improve. These criteria could be agreed on beforehand and form part of your forum introduction. Again, for written comments, it is best to be specific. "Great post" doesn't really help the learner much, apart from a bit of an ego boost. Of course, there are times where you may wish to do this but there is lots of evidence that it doesn't help their understanding of scientific ideas, (see Inside the Black Box: Black, P.J. & Wiliam, D. 1998). You could ask your learners to suggest two things that were really good about the post, and one thing that could be improved. They should phrase the feedback "perhaps next time you could…". A polite suggestion, rather than a criticism that doesn't make the student giving the advice sound bigheaded. It's also good practice to get the person receiving the feedback to say "thank you", as it will encourage the person giving the feedback to do it more often. Aggregate of ratings In forums, there are five ways in which ratings are totaled (or aggregated), described as follows. These can be set by clicking on the edit icon alongside the forum link on the main course page. Average: This is the mean of all the ratings. Count: This gives you the sum of the number of posts. There are not many examples where this might be useful, other than to check that users have contributed a certain number of times. Max: This is the highest rating given for a persons post. Useful when you wish to get your users to display certain levels of competency. Min: It is the lowest rating given for a persons post. Sum: This is all the ratings combined to give a total. It is useful when you want to encourage participation and quality responses.This is different than count, as the total cannot exceed the maximum rating for the forum. In a set up forum(download here -ch:2) we will set the aggregate type and give the rating a scale. The scale chosen here gives a maximum of 5 for each post. Before setting this forum take the time to go through the scale and share a rubric with your learners, which explains what a post must include to be given a 1, or a 2, and so on. It is usually good to show them examples of different posts so they get an idea of what makes a great post that is a 5. Another way you could use ratings is to use a scale to indicate how strongly the reader agrees or disagrees with the post. You could do this by creating a custom grade scale with words to represent the level of agreement. An example of this would be a scale that pupils can award the following values: Agree totally Agree somewhat Neither agree nor disagree Disagree with some points Disagree totally Grade scales There are two standard grade scales in Moodle. One is called Separate and Connected ways of knowing. It has the following choices that you could award for a discussion post: Mostly separate knowing Separate and connected Mostly connected knowing A person who is in the 'mostly separate knowing' category has their opinions based on fact and is very objective. A person who is in the 'mostly connected knowing' category is empathetic and tries to see the other person's point of view. The other standard scale is called Satisfactory and allows users to choose from the following labels: Not satisfactory Satisfactory Outstanding You can set up custom scales, which could be anything; grade letters, levels, or even colors could be awarded to posts to represent de Bono's Thinking Hats. Here is a link if you are not familiar with the concept: http://en.wikipedia.org/wiki/Six_Thinking_Hats. To set up custom scales, click the Grades link in the settings block followed by Scales. Assignments Assignment activities are a nice introduction to getting users submitting more traditional types of work on Moodle. They are very easy to set up and provide the added benefit of organizing all of the submitted work in one place. There are a number of different assessment types that you can set up in Moodle. Some of these involve users submitting a file or files online, or even offline. There are: Online text Upload a single file Advanced uploading of files Offline Think of an assignment in the same way you would have students hand in or e-mail you a piece of written work. Online text The online text assignment allows you to set up an assignment where your users are required to type or copy and paste their work directly into the browser. The really useful thing about online text assignments is that you can choose to be able to comment on their work inline. This means that you will be able to give them feedback that they can use to improve their work and resubmit it. However, if students are typing more than a paragraph of text there is the chance that the web page might timeout, so they would lose their work. Like grading forums, you can also specify how many marks the assignment is worth, or specify a particular scale that the work will be judged against. A lot of the time a simple scale can be used to assess the piece of work, for instance unsatisfactory, satisfactory or outstanding. This would be paired with some detailed feedback for improvement. The assignment that is going to be set up here will be for the third topic "movement in and out of cells". To add an online text activity, choose it from the Add an activity drop-down menu. This activity would be a lead up to an experiment investigating how osmosis acts on pieces of potato in sugar solutions. The aim here is to get your users to justify their predictions. You can follow these same steps to set up any activity in Moodle. As with all things in Moodle it needs a name and description. Set the activity available for one week although users will not be prevented from handing it in late. Use the Satisfactory scale for grading and allow resubmitting with comments inline. It's also nice to set the e-mail alerts to teachers to yes so that you will get an e-mail when a new piece of work is submitted. For this to work properly, you must remember to add yourself to the course as a teacher and also add yourself to a group. Here are the assignment settings. The other settings can be left as standard: As a teacher, if you click the link View submitted assignments at the top-right-hand side of the activity, you'll be taken to the screen where you can grade and comment on the work. It should look a little like the following image. You can also download all assignments as a ZIP file. Upload a single file The 'upload a single file' activity, as the name suggests, is an assignment where you require the user to upload a single file. This file can be nearly any format (as long as it doesn't pose a threat to the server). Let's take an example of how you can use this activity type in a very standard way. Later, you will learn to do this more creatively using the 'advanced uploading of files' activity. Here are the settings that you could choose if you are asking your users to keep a food diary and submit it as an assignment. This is something that you would not give a grade for, just some written feedback. Again, the common module settings will be left on the default settings. Advanced uploading of files With this activity, you are able to specify a maximum number of upload files and there is a button labeled Send for marking that allows students to let you know when work is ready for marking. You can also set up draft and submission stages and it is the only assignment type where teachers can send back a file (for example, a Word document) as a response to the student. If you are a fan of getting pupils to use their cell phones in science lessons, you could get them to video their experiments or take photos to include in lab reports. Given next are the settings to use for a video assignment: Offline activity The offline activity is really useful if you want to keep records of class work or assessments on Moodle. The set up is very similar to the other activity types, but allows you to input a series of grades using any of the different scales. So rather than keeping grades from bookwork or tests in a separate spreadsheet or mark book they can be stored in the gradebook in Moodle. This means that your students can refer to them at any time and like the other types of activity the users are notified by e-mail of any grade or comments that you give them. For any assignment that you give, it is important to remember to let your students know what the marking criteria is that they are working towards. Students need to know what is good work, so you could even show exemplar work from last year as a resource that they would look at before attempting your assignment.
Read more
  • 0
  • 0
  • 1972

article-image-plug-ins-and-dynamic-actions-oracle-application-express-and-ext-js
Packt
22 Mar 2011
7 min read
Save for later

Plug-ins and Dynamic Actions with Oracle Application Express and Ext JS

Packt
22 Mar 2011
7 min read
Oracle Application Express 4.0 with Ext JS Deliver rich desktop-styled Oracle APEX applications using the powerful Ext JS JavaScript library Plug-ins and dynamic actions are the two most exciting new features for developers in APEX 4.0. Combining them with Ext JS components is a recipe for success. For the first time we now have the ability to add custom "widgets" directly into APEX that can be used declaratively in the same way as native APEX components. Plug-ins and dynamic actions are supported with back end integration, allowing developers to make use of APEX provided PL/SQL APIs to simplify component development. Plug-ins give developers a supported mechanism to enhance the existing built-in functionality by writing custom PL/SQL components for item types, regions, and processes. Dynamic actions provide developers with a way to define client-side behavior declaratively without needing to know JavaScript. Using a simple wizard, developers can select a page item and a condition, enter a value, and select an action (for example, Show, Hide, Enable, and Show Item Row). Most APEX developers come from a database development background. So, they are much more comfortable coding with PL/SQL than JavaScript. The sooner work is focused on PL/SQL development the more productive APEX developers become. The ability to create plug-ins that can be used declaratively means developers don't have to write page-specific JavaScript for items on a page, or use messy "hacks" to attach additional JavaScript functionality to standard APEX items. Ext JS provides a rich library of sophisticated JavaScript components just waiting to be integrated into APEX using plug-ins. A home for your plug-ins and dynamic actions APEX allows you to create plug-ins for item, region, dynamic action, and process types. Like templates and themes, plug-ins are designed to be shared, so they can be easily exported and imported from one workspace application to another. Plug-ins can also be subscribed, providing a way to easily share and update common attributes between plug-ins. Building a better Number Field APEX 4.0 introduced the Number Field as a new item type, allowing you to configure number-range checks by optionally specifying minimum and maximum value attributes. It also automatically checks that the entered value is a number, and performs NOT NULL validation as well. You can also specify a format mask for the number as well, presumably to enforce decimal places. This all sounds great, and it does work as described, but only after you have submitted the page for processing on the server. The following screenshot shows the APEX and Ext versions of the Number Field, both setup with a valid number range of 1 to 10,000. The APEX version allows you to enter any characters you want, including letters. The Ext version automatically filters the keys pressed to only accept numbers, conditionally the decimal separator, and the negative sign. It also highlights invalid values when you go outside the valid number range. We are going to build a better Number Field using APEX plug-ins to provide better functionality on the client side, and still maintain the same level of server-side validation. The Number Field is quite a simple example, allowing us to be introduced to how APEX plug-ins work without getting bogged down in the details. The process of building a plug-in requires the following: Creating a plug-in in your application workspace Creating a test page containing your plug-in and necessary extras to test it Running your application to test functionality Repeating the build/test cycle, progressively adding more features until satisfied with the result Creating a plug-in item For our Number Field, we will be creating an item plug-in. So, navigate to the plug-ins page in Application Builder, found under Application Builder | Application xxx | Shared Components | Plug-ins, and press Create to open the Plug-in Create/Edit page. Start filling in the following fields: Name: Ext.form.NumberField. Here, I'm using the Ext naming for the widget, but that's just for a convenience. Internal Name: Oracle's recommendation here is to use your organization's domain name as a prefix. So for example, a company domain of mycompany. com would prefix a plug-in named Slider, would result in an internal name of COM.MYCOMPANY.SLIDER. File Prefix: As we are referencing the Ext JavaScript libraries in our page template, we can skip this field completely. For specialized plug-ins that are only used on a handful of specific pages, you would attach a JavaScript file here. Source: For the PL/SQL source code required to implement our plug-in, you can either enter it as a PL/SQL anonymous block of code that contains functions for rendering, validating and AJAX callbacks, or refer to code in a PL/SQL package in the database. You get better performance using PL/SQL packages in the database, so that's the smart way to go. Simply include your package function names in the Callbacks section, as shown in the following screenshot, noting that no AJAX function name is specified as no AJAX functionality is required for this plug-in. The package doesn't need to exist at this time—the form will submit successfully anyway. Standard attributes: In addition to being able to create up to ten custom attributes, the APEX team has made the standard attributes available for plug-ins to use. This is really useful, because the standard attributes comprise elements that are useful for most components, such as width and height. They also have items such as List of Values (LOV), which have more complicated validation rules already built-in, checking SQL queries used for the LOV source are valid queries, and so on. For the Number Field, only a few attributes have been checked: IsVisible Widget: Indicating the element will be displayed Session State Changeable: So that APEX knows to store the value of the item in session state Has Read Only Attribute: So that conditional logic can be used to make the item read only Has Width Attributes: Allowing the width of the item to be set Notice that some of the attributes are disabled in the following screenshot. This is because the APEX Builder conditionally enables the checkboxes that are dependent on another attribute. So, in this screenshot the List of Values Required, Has LOV Display Null Attributes, and Has Cascading LOV Attributes checkboxes are disabled, because they are dependant on the Has List of Values checkbox. Once it is checked, the other checkboxes are enabled. Custom attributes: Defining the custom attributes for our Number Field is largely an exercise in reviewing the configuration options available in the documentation for Ext.form.NumberField, and deciding which options are most useful to be included. You need to also take into account that some configuration options are already included when you define an APEX item using your plug-in. For example, Item Label is included with an APEX item, but is rendered separately from the item, so don't need to be included. Likewise Value Required is a validation rule, and is also separate when rendering the APEX item. The following next screenshot shows some Ext.form.NumberField configuration options, overlaid with the custom attributes defined in APEX for the plug-in: I've chosen not to include the allowBlank config option as a custom attribute, simply because this can be determined by the APEX Value Required property. Other Configuration options, such as allowDecimals and allowNegative, are included as custom attributes as Yes/No types. The custom attributes created are listed in the following table: Custom events: Custom events are used to define JavaScript event that can be exposed to dynamic actions. For this simple plug-in, there is no need to define any custom events. At this point, we are done defining the Number Field in APEX; it's time to turn our attention to building the database package to execute the Callbacks to render and validate the plug-in.
Read more
  • 0
  • 0
  • 2771

article-image-getting-started-openlayers
Packt
22 Mar 2011
9 min read
Save for later

Getting Started with OpenLayers

Packt
22 Mar 2011
9 min read
OpenLayers 2.10 Beginner's Guide Create, optimize, and deploy stunning cross-browser web maps with the OpenLayers JavaScript web mapping library What is OpenLayers? OpenLayers is an open source, client side JavaScript library for making interactive web maps, viewable in nearly any web browser. Since it is a client side library, it requires no special server side so beware or settings—you can use it without even downloading anything! Originally developed by Metacarta, as a response, in part, to Google Maps, it has grown into a mature, popular framework with many passionate developers and a very helpful community. Why use OpenLayers? OpenLayers makes creating powerful web-mapping applications easy and fun. It is very powerful but also easy to use—you don't even need to be a programmer to make a great map with it. It's open source, free, and has a strong community behind it. So if you want to dig into the internal code, or even improve it, you're encouraged to do so. Cross browser compatibility is handled for you—it even works in IE6. OpenLayers is not tied to any proprietary technology or company, so you don't have to worry so much about your application breaking (unless you break it). At the time of writing, support for modern mobile and touch devices is in the works (with many proof of concept examples), and should be in the official library in the near future—if they aren't by the time you're reading this. OpenLayers allows you to build entire mapping applications from the ground up, with the ability to customize every aspect of your map—layers, controls, events, etc. You can use a multitude of different map server backends together, including a powerful vector layer. It makes creating map 'mashups' extremely easy. What, technically, is OpenLayers? We said OpenLayers is a client side JavaScript library, but what does this mean? Client side When we say client side we are referring to the user's computer, specifically their web browser. The only thing you need to have to make OpenLayers work is the OpenLayers code itself and a web browser. You can either download it and use it on your computer locally, or download nothing and simply link to the JavaScript file served on the site that hosts the OpenLayers project (http://openlayers.org). OpenLayers works on nearly all browsers and can be served by any web server or your own computer. Using a modern, standard-based browser such as Firefox, Google Chrome, Safari, or Opera is recommended. Library When we say library we mean that OpenLayers is an API (Application Programmer Interface) that provides you with tools to develop your own web maps. Instead of building a mapping application from scratch, you can use OpenLayers for the mapping part, which is maintained and developed by a bunch of brilliant people For example, if you wanted to write a blog you could either write your own blog engine, or use an existing one such as WordPress or Blogger and build on top of it. Similarly, if you wanted to create a web map, you could write your own from scratch, or use so beware that has been developed and tested by a group of developers with a strong community behind it. By choosing to use OpenLayers, you do have to learn how to use the library, but the benefits greatly outweigh the costs. You get to use a rich, highly tested and maintained code base, and all you have to do is learn how to use it. OpenLayers is written in JavaScript, but don't fret if you don't know it very well. All you really need is some knowledge of the basic syntax, and we'll try to keep things as clear as possible in the code examples. If you are unfamiliar with JavaScript, Mozilla provides phenomenal JavaScript documentation at https://developer.mozilla. org/en/javascript. Anatomy of a web-mapping application First off —what is a 'web-mapping application. To put it bluntly, it's some type of Internet application that makes use of a map. This could be a site that displays the latest geo-tagged images from Flickr , a map that shows markers of locations you've traveled to, or an application that tracks invasive plant species and displays them. If it contains a map and it does something, you could argue that it is a web map application. The term can be used in a pretty broad sense. So where exactly does OpenLayers fit in? We know OpenLayers is a client side mapping library, but what does that mean? Let's take a look at the following screenshot: This is called the Client / Server Model and it is, essentially, the core of how all web applications operate. In the case of a web map application, some sort of map client (e.g., OpenLayers) communicates with some sort of web map server (e.g., a WMS server or the Google Maps backend). Web map client OpenLayers lives on the client side. One of the primary tasks the client performs is to get map images from a map server. Essentially, the client has to ask a map server for what you want to look at. Every time you navigate or zoom around on the map, the client has to make new requests to the server—because you're asking to look at something different. OpenLayers handles this all for you, and it is happening via asynchronous JavaScript (AJAX) calls to a map server. To reiterate—the basic concept is that OpenLayers sends requests to a map server for map images every time you interact with the map, then OpenLayers pieces together all the returned map images so it looks like one big, seamless map. Web map server A map server (or map service) provides the map itself. There are a myriad of different map server backends. A small sample includes WMS, Google Maps, Yahoo! Maps, ESRI ArcGIS, WFS, and OpenStreet Maps. If you are unfamiliar with those terms, don't sweat it. The basic principle behind all those services is that they allow you to specify the area of the map you want to look at (by sending a request), and then the map servers send back a response containing the map image. With OpenLayers, you can choose to use as many different backends in any sort of combination as you'd like. OpenLayers is not a web map server; it only consumes data from them. So, you will need to be able to access some type of web map service. Don't worry though. Fortunately, there are a myriad of free and/or open source web map servers available that are remotely hosted or easy to set up yourself, such as MapServer. Throughout this article, we'll often use a freely available web mapping service from OSGeo, so don't worry about having to provide your own. With many web map servers you do not have to do anything to use them—just supplying a URL to them in OpenLayers is enough. OSGeo, OpenStreet Maps, Google, Yahoo!, and Bing Maps, for instance, provide access to their map servers (although, some commercial restrictions may apply with various services in some situations). Relation to Google / Yahoo! / and other mapping APIs The Google, Yahoo!, Bing, and ESRI Mappings API allow you to connect with their map server backend. Their APIs also usually provide a client side interface (at least in the case of Google Maps). The Google Maps API , for instance, is fairly powerful. You have the ability to add markers, plot routes, and use KML data (things you can also do in OpenLayers)—but the main drawback is that your mapping application relies totally on Google. The map client and map server are provided by a third party. This is not inherently a bad thing, and for many projects, Google Maps and the like are a good fit However, there are quite a few drawbacks: You're not in control of the backend You can't really customize the map server backend, and it can change at any time There may be some commercial restrictions, or some costs involved These other APIs also cannot provide you with anything near the amount of flexibility and customization that an open source mapping application framework (i.e., OpenLayers) offers. Layers in OpenLayers So, what's with the Layer in OpenLayers? Well, OpenLayers allows you to have multiple different 'backend' servers that your map can use. To access a web map server, you create a layer object and add it to your map with OpenLayers. For instance, if you wanted to have a Google Maps and a WMS service displayed on your map, you would use OpenLayers to create a GoogleMaps layer object and a WMS layer object, and then add them to your OpenLayers map. We'll soon see an example with a WMS layer, so don't worry if you're a little confused. What is a Layer? Like layers of an onion, each layer is above and will cover up the previous one; the order that you add in the layers is important. With OpenLayers, you can arbitrarily set the overall transparency of any layer, so you are easily able to control how much layers cover each other up, and dynamically change the layer order at any time. For instance, you could have a Google map as your base layer, a layer with satellite imagery that is semi-transparent, and a vector layer all active on your map at once. A vector layer is a powerful layer that lets us add markers and various geometric objects to our maps. Thus, in this example, your map would have three separate layers. The OpenLayers website The website for OpenLayers is located at http://openlayers.org/. To begin, we need to download a copy of OpenLayers (or, we can directly link to the library—but we'll download a local copy). You can download the compressed library as either a .tar.gz or .zip, but both contain the same files. Let's go over the links: Link to the hosted version: If you do not want to actually download OpenLayers, you can instead link to the OpenLayers library by adding this script URL to your site in a <script> tag. 2.10 (Stable) .tar.gz or .zip: This should show the latest stable release (2.10 at the time of writing). You can download it as either a tar.gz or .zip; if you are unsure of which to get, you should download the .zip version. 2.10 Release Notes: This highlights things that have changed, bugs that have been fixed, etc. Class documentation on, more documentation on: These are links to the API documentation, which we will make heavy use of throughout the article. I recommend opening it up and keeping it up while working through the examples.
Read more
  • 0
  • 0
  • 3492
article-image-article-believe-in-open-source-meet-the-team
Packt
22 Mar 2011
12 min read
Save for later

Believe in Open Source: Meet the team

Packt
22 Mar 2011
12 min read
Doug Paterson- Open Source Publisher Who are you and what do you do? My name is Douglas Paterson, and I’m the Publisher of the Open Source brand. I have overall responsibility for the books that we publish on Open Source projects – working with the Acquisition Editors to identify new projects where we can see a desire from the community for information to help them get the most from the project. What do you enjoy about your role? Providing new information for an Open Source project that we haven’t dealt with before to make life easier for users of that project. We are often dealing with projects that no other publisher has felt the need to engage with before, and there is great satisfaction from the community enjoying our book and responding. How important is the Open Source community to Packt and to your role? My role is only about Open Source, and of course it is very important. Packt’s first titles were about Open Source technologies, and we continue to contribute to the funding of Open Source projects through our Open Source Project Royalty Scheme and the Open Source Awards, a unique position among publishers. What are your hobbies outside of your role? Right now I’m currently enjoying have my hair pulled by my 4 month old daughter, that takes up most of my time these days. It even gets in the way of reading a new zombie novel.     Julian Copes- Open Source Marketing Executive Who are you and what do you do? My name is Julian Copes and I am the Marketing Executive who works on Open Source books and organizes the annual Open Source Awards. My role involves building relationships with projects and experienced figures within Open Source. A huge part of my role involves ensuring that the various Open Source communities are aware of relevant books when published. What do you enjoy about your role? The thing I really enjoy about my role is the opportunity to meet lots of different people from different walks of life over the internet or face to face through conferences. I am a real people person and my role allows me to build relationships with people on a worldwide scale. I also love being part of the Open Source community as I get to work with and meet the readers of Packt books, finding out ways to provide a greater service to the Open Source community in the future. How important is the Open Source community to Packt and to your role? The Open Source community is vital, not only the publication of Packt books but the level of quality books available in the Open Source book market. I work with various individuals within Open Source from project leaders to respected community members. All members of the Open Source community are important and we find we are provided with great assistance during our annual Open Source Awards from authorities in the industry who offer to be judges. What are your hobbies outside of your role? In my spare time I enjoy reading, listening to music, playing sports (especially soccer) and reading/writing poetry. I love travelling and spending time with my family. Thanks for your time Julian, lastly what projects, if any, are you working on at the moment? At present, I’m working on the new range of Packt mini books and completing some early preparation for the 2011 Open Source Awards.     Sarah Cullington- Open Source Acquisition Editor Who are you and what do you do? My name is Sarah and I am one of Packt’s Open Source Acquisition Editors. My role is to research Open Source technologies to see if there are any potential opportunities for new books to be created. If I find an interesting topic area, I will put together a title proposal to get a better idea of what the book will be about and who the audience will be. From there, I find authors to write the books, help them to develop an outline for the book, then work with them on perfecting their first few chapters. What do you enjoy about your role? One of my favourite things to do is to help new authors to develop a book idea and outline, and to really make it their own. It’s exciting to see a book idea turn into an actual outline, it makes the book seem much more real. How important is the Open Source community to Packt and to your role? Everyone in the Open Source community is incredibly friendly and helpful. I have approached many people over the years about writing a book for us, or to discuss books ideas that I have. Even if people don’t have time to write a book, they will always have time to discuss my ideas with me, to suggest book ideas of their own, or to introduce me to friends and colleagues who are also very friendly and great to chat to about Open Source topics. What are your hobbies outside of your role? I try to go to the gym three times a week, although it often turns out to be a lot less frequent! I also enjoy reading, listening to music (and often singing along), and spending time with my friends and family. Thanks for your time Sarah, lastly what projects, if any, are you working on at the moment? I am helping to put together the Packt mini-books and am working on updating a number of our Drupal, Moodle, and jQuery books.     Usha Iyer- Open Source Acquisition Editor Who are you and what do you do? I am Usha Iyer, an Acquisition Editor working with Packt and I work on Packt Open Source books. My job is to find book ideas with good potential and write book proposals on them. Once the publisher approves the book proposal, I find suitable authors for the book and contract them. I work on the initial chapters of the book, the structure of the book and I also aid the author to ensure the content is at the required standard before I pass the book on to other editors. What do you enjoy about your role? I like to research for new book ideas which have a good market and write title proposals on them. I love to see books getting published after a long process and definitely enjoy the success when a book sells well. How important is the Open Source community to Packt and to your role? Packt is the biggest publisher of Open Source books, so Open Source books are vital to Packt and how I perform in my role. As I work only on Open Source books, the growth of the Open Source community is very important to me. It feels good to work on books published on Open Source topics in areas where there is a real need for accesible books. What are your hobbies outside of your role? My hobbies are cooking, listening to music, and watching TV. I like to read fiction when I get time for it. Thanks for your time Usha, lastly what projects, if any, are you working on at the moment? Nothing special, I am basically spending time on researching for more good Open Source book ideas!     Robin de Jongh - Open Source Acquisition Editor Who are you and what do you do? I’m Robin, one of the Open Source Acquisition Editors at Packt. I started off as one of their authors, and found writing two books with them an excellent route into editing. I now investigate current and future trends in the software landscape so that I can match our books to future demand of our readers. Books take a long time to write and edit before they appear on the bookshelves, so I have to try and line up the titles you want, for when you want them, before you know you do! What do you enjoy about your role? I enjoy being part of a vibrant company, a supportive and talented team, and being brought cakes and biscuits by the CEO every time I press the big red cake button under my desk. Also it’s great to be in a role where thinking outside the box is encouraged and valued. How important is the Open Source community to Packt and to your role? Open Source has completely changed the software landscape for the better, allowing users to decide on which projects win, and which to quietly forget. Software is now driven by need, rather than by what makes money in the short term. And that’s very good for books too. It means that we, an Open Source focused publisher, directly address needs and wants, rather than just where the money is. Other publishers are catching on slowly to what that means – but Packt is blazing the trial. I see Open Source as no-tie-in software. It costs you nothing to install it, so there’s zero disincentive to trying it out. And because people are happy to experiment with Open Source software they learn to do things they never thought they could. Lack of user documentation is often the one factor stopping people benefitting from the software, stunting the growth of a project, and so Packt books can often be the catalyst to success. What are your hobbies outside of your role? I’m a committed Bible student. That’s probably not a popular thing to be right now, but I find that having a higher wisdom to draw on is vital to living a contented life. I also continue to write when I have the time. Thanks for your time Robin, lastly what projects, if any, are you working on at the moment? I’m working hard on building a list of talented, enthusiastic, hard working, Dutch authors to write books for me. If you fit at least three of those criteria, you should get in touch ;)     Aaron Nash- Editorial Quality Executive   Who are you and what do you do? My name is Aaron and I work as an Editorial Quality Executive at Packt, trying to maintain a high standard of quality across our range of books. This mainly consists of checking over the books and making sure that they meet our in-house style. What do you enjoy about your role? I enjoy getting to see a finished book, knowing that I’m usually the last person who has had any input on its content. Also, my role lets me exercise my unhealthy obsession with grammar in a way that isn’t just annoying. How important is the Open Source community to Packt and to your role? As part of my job to ensure good editorial quality, I’ve hired several freelance proofreaders. Quite a few of these have come from within the Open Source community – members of the community have been really helpful in this role, since they already have a familiarity with the material and technical terms used in our books. What are your hobbies outside of your role? I like to travel as much as possible, but when I’m stuck in the UK, I generally like reading (trashy crime novels in particular) and listening to music in my free time. I’m interested in current affairs, history, politics and other such exciting topics. This year I also finally discovered the Xbox 360 – it’s changed my life. Thanks for your time Aaron, lastly what projects, if any, are you working on at the moment? Currently I’m working with our copy editors on new ways to maintain the high quality of our books.     The Online PR Team Who are you and what do you do? We are Packt’s Online PR Team, and work closely with the people and communities surrounding the technologies on which Packt publishes. What do you enjoy about your role? We enjoy discussing our books with experts in different fields, and working with them to have our books reviewed. This helps to give us an understanding on the quality of our books, as well as promoting them to potential customers. How important is the Open Source community within Packt to you and your role? The Open Source community plays a very vital role within Packt since we publish a significant amount of Open Source titles. As the communities surrounding Open Source projects are so welcoming, it’s usually a pleasure to work with them, and we are always happy to support them with books or content. What are your hobbies outside of your role? Hanging out with friends, watching movies, and traveling. Lastly what projects, if any, are you/the MREs working on at the moment? We have recently worked on promoting the Microsoft Monday and IBM Tuesday campaigns, and are also helping to promote Packt’s online digital book library, PacktLib. Most of our time and focus revolves around the core of Packt’s business though, the books themselves.
Read more
  • 0
  • 0
  • 4740

article-image-photo-manipulation-gimp-26
Packt
21 Mar 2011
5 min read
Save for later

Photo Manipulation with GIMP 2.6

Packt
21 Mar 2011
5 min read
Introduction When working with photos we need to be sure that colors always look the way we want. Monitors, LCDs, and laptop screens, all render colors differently, and they don't look the same. There's no way you can control how people see their own screen, but you can calibrate your own using some kind of color profiling. The problem extends to different devices like scanners, printers, and cellphones, among others, because each device has its own color characteristics. Also, each device can handle different ranges of color. To avoid these problems, color profiles were implemented. It's a table that matches a specific color of a device to a device-independent color. Color profiles are created by each manufacturer, but the ICC (International Color Consortium) created its own standard. Calibration, image modes, and colour profiles This is one of the first things to do before working with photos. The Color Management menu (Edit | Preferences | Color Management) enables you to load any preset for your monitor. The presets can be created using any hardware calibration and measurement tool. For Linux, you can use LPROF and ARGYLL. For more information on color management in Linux, check the Linux color management page on Wikipedia. Apart from the color profile in use, you should set up your monitor and video card to render colors as close as possible to the standard. For Linux you can use XCALIB or DISPWIN. You can also simulate how an image will look when printed by selecting Print Simulation from the Mode of Operation in the Color Management menu. Scaling an image Image scaling is one of the easiest tasks, and also one of the most useful. In just a few seconds you can reduce an image's size, making e-mail transfers quicker. How to do it... To scale an image follow these steps: Open a file, go to Image | Scale Image. Change the size to whatever you want: As you change one value, you can see the other changing too. That's to keep the original file aspect ratio. If you click on any of the chain icons you can change any value independently. How it works... Image scaling works by changing the number of pixels of an image. The way pixels are created/deleted can be changed by choosing a different interpolation method in the Quality section of the Scale Image window. The best (but slowest) method is the Cubic interpolation, which calculates the color of each pixel by estimating an average of the eight closest ones. On the opposite corner, if you choose None as the interpolation method, each pixel gets its own color from its closest neighbor. This is the fastest method, but it also generates unwanted aliasing that can give you headaches if you are working with transparencies and highcontrasts. The resolution fields are useful when printing the image, they say how many pixels are per inch. If your image is too big and the resolution too low, the printed image can look pixelated. You can change the print size of an image without changing its resolution or size by going to Image | Print Size. Cropping an image There's another quick way to rescale your image and select just a section of it. Use the Crop Tool. How to do it... The following steps will show you how to crop an existing image: Open an image, and select the Crop Tool: Quickly click and drag around the area you want. Then, just press Return (Enter in Windows), and anything around the selection area will be cropped. Flipping or rotating an image Sometimes you scan and old photo or take a picture with the camera tilted. Following is how to quickly rotate or flip them. How to do it... To rotate or flip an image easily, carry out the following steps: Open an image, for example the following: Select the Flip Tool from the Toolbox: Use the left-mouse button along with the Ctrl key to change between horizontal and vertical flipping. Now, to rotate the image, select the Rotate Tool from the Toolbox: Click and drag your image to rotate it. Use the Ctrl key to constrain rotation to 15 degrees steps. Press the Return key when you've finished: How it works... Flip and rotate are basic tools. You can use the mouse to perform the operations after selecting any of them, but using their respective tool options gives you a lot more control. In both cases, you can control what to rotate (a layer, a selection, or a path). Also, in the Rotate tool, you can change the middle point around which the image rotates. This allows you to rotate the image with more freedom. To change it, select the Rotate Tool, and click and drag the small circle that appears in the center of the image: You can also set its coordinates from the Rotate window: You can also flip and rotate an image by using the menu items in Image | transform.
Read more
  • 0
  • 0
  • 2432
Modal Close icon
Modal Close icon