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
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Development

1802 Articles
article-image-ext-js-4-working-grid-component
Packt
11 Jan 2012
10 min read
Save for later

Ext JS 4: Working with the Grid Component

Packt
11 Jan 2012
10 min read
(For more resources on JavaScript, see here.) Grid panel The grid panel is one of the most-used components when developing an application Ext JS 4 provides some great improvements related to this component. The Ext JS 4 Grid panel renders a different HTML than Ext JS 3 Grid did. Sencha calls this new feature Intelligent Rendering. Ext JS 3 used to create the whole structure, supporting all the features. But, what if someone just wanted to display a simple grid? All the other features not being rendered would just be wasted, because no one was using that structure. Ext JS 4 now renders only the features the grid uses, minimizing and boosting the performance. Before we examine the grid's new features and enhancements, let's take a look how to implement a simple grid in Ext JS 4: Ext.create('Ext.grid.Panel', { store: Ext.create('Ext.data.ArrayStore', { fields: [ {name: 'book'}, {name: 'author'} ], data: [['Ext JS 4: First Look','Loiane Groner']] }), columns: [ { text : 'Book', flex : 1, sortable : false, dataIndex: 'book' },{ text : 'Author', width : 100, sortable : true, dataIndex: 'author' }], height: 80, width: 300, title: 'Simple Grid', renderTo: Ext.getBody() }); As you can see in the preceding code, the two main parts of the grid are the store and the columns declarations. Note, as well, names of both store and model fields always have to match with the column's dataIndex (if you want to display the column in the grid). So far, nothing has changed. The way we used to declare a simple grid in Ext JS 3 is the same way we do for Ext JS 4. However, there are some changes related to plugins and the new features property. We are going to take a closer look at that in this section. Let's dive into the changes! Columns Ext JS 4 organizes all the column classes into a single package—the Ext.grid.column package. We will explain how to use each column type with an example. But first, we need to declare a Model and a Store to represent and load the data: Ext.define('Book', { extend: 'Ext.data.Model', fields: [ {name: 'book'}, {name: 'topic', type: 'string'}, {name: 'version', type: 'string'}, {name: 'released', type: 'boolean'}, {name: 'releasedDate', type: 'date'}, {name: 'value', type: 'number'} ] }); var store = Ext.create('Ext.data.ArrayStore', { model: 'Book', data: [ ['Ext JS 4: First Look','Ext JS','4',false,null,0], ['Learning Ext JS 3.2','Ext JS','3.2',tr ue,'2010/10/01',40.49], ['Ext JS 3.0 Cookbook','Ext JS','3',true,'2009/10/01',44.99], ['Learning Ext JS','Ext JS','2.x',true,'2008/11/01',35.99], ] }); Now, we need to declare a grid: Ext.create('Ext.grid.Panel', { store: store, width: 550, title: 'Ext JS Books', renderTo: 'grid-example', selModel: Ext.create('Ext.selection.CheckboxModel'), //1 columns: [ Ext.create('Ext.grid.RowNumberer'), //2 { text: 'Book',//3 flex: 1, dataIndex: 'book' },{ text: 'Category', //4 xtype:'templatecolumn', width: 100, tpl: '{topic} {version}' },{ text: 'Already Released?', //5 xtype: 'booleancolumn', width: 100, dataIndex: 'released', trueText: 'Yes', falseText: 'No' },{ text: 'Released Date', //6 xtype:'datecolumn', width: 100, dataIndex: 'releasedDate', format:'m-Y' },{ text: 'Price', //7 xtype:'numbercolumn', width: 80, dataIndex: 'value', renderer: Ext.util.Format.usMoney },{ xtype:'actioncolumn', //8 width:50, items: [{ icon: 'images/edit.png', tooltip: 'Edit', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Edit',rec.get('book')); } },{ icon: 'images/delete.gif', tooltip: 'Delete', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Delete',rec.get('book')); } }] }] }); The preceding code outputs the following grid: The first column is declared as selModel, which, in this example, is going to render a checkbox, so we can select some rows from the grid. To add this column into a grid, simply declare the selModel (also known as sm in Ext JS 3) as CheckBox selection model, as highlighted in the code (comment 1 in the code). The second column that we declared is the RowNumberer column. This column adds a row number automatically into the grid. In the third column (with text:'Book'), we did not specify a column type; this means the column will display the data itself as a string. In the fourth column, we declared a column with xtype as templatecolumn. This column will display the data from the store, specified by an XTemplate, as declared in the tpl property. In this example, we are saying we want to display the topic (name of the technology) and its version. The fifth column is declared as booleancolumn. This column displays a true or false value. But, if we do not want to display true or false in the grid, we can specify the values that we want to get displayed. In this example, we displayed the value as Yes (for true values) and No (for false values), as we declared in the trueText and falseText. The sixth column we declared as datecolumn, which is used to display dates. We can also declare a date format we want to be displayed. In this example, we want to display only the month and the year. The format follows the same rules for PHP date formats. The seventh column we declared as numbercolumn. This column is used to display numbers, such as a quantitative number, money, and so on. If we want to display the number in a particular format, we can use one of the Ext JS renderers to create a customized one. And the last column we declared is the actioncolumn. In this column, we can display icons that are going to execute an action, such as delete or edit. We declare the icons we want to display in the items property. topic: {name}{rows.length} Book topic: {name}{rows.length} Books Feature support In Ext JS 3, when we wanted to add a new functionality to a grid, we used to create a plugin or extend the GridPanel class. There was no default way to do it. Ext JS 4 introduces the Ext.grid.feature.Feature class that contains common methods and properties to create a plugin. Inside the Ext.grid.feature packages, we will find seven classes: AbstractSummary, Chunking, Feature, Grouping, GroupingSummary, RowBody, and Summary. A feature is very simple to use—we need to add the feature inside the feature declaration in the grid: features: [{ groupHeaderTpl: 'Publisher: {name}', ftype: 'groupingsummary' }] Let's take a look at how to use some of these native grid features. Ext.grid.feature.Grouping Grouping rows in Ext JS 4 has changed. Now, Grouping is a feature and can be applied to a grid through the features property. The following code displays a grid grouped by book topic: Ext.define('Book', { extend: 'Ext.data.Model', fields: ['name', 'topic'] }); var Books = Ext.create('Ext.data.Store', { model: 'Book', groupField: 'topic', data: [{ name: 'Learning Ext JS', topic: 'Ext JS' },{ name: 'Learning Ext JS 3.2', topic: 'Ext JS' },{ name: 'Ext JS 3.0 Cookbook', topic: 'Ext JS' },{ name: 'Expert PHP 5 Tools', topic: 'PHP' },{ name: 'NetBeans IDE 7 Cookbook', topic: 'Java' },{ name: 'iReport 3.7', topic: 'Java' },{ name: 'Python Multimedia', topic: 'Python' },{ name: 'NHibernate 3.0 Cookbook', topic: '.NET' },{ name: 'ASP.NET MVC 2 Cookbook', topic: '.NET' }] }); Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [Ext.create('Ext.grid.feature.Grouping',{ groupHeaderTpl: 'topic: {name} ({rows.length} Book{[values.rows.length > 1 ? "s" : ""]})' })], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); In the groupHeaderTpl attribute, we declared a template to be displayed in the grouping row. We are going to display one of the following customized strings, depending on the number of books belonging to the topic: The string comprises of the topic name ({name}) and the count of the book for the topic ({rows.length}). In Ext JS 3, we still had to declare a grouping field in the store; but, instead of a Grouping feature, we used to declare GroupingView, as follows: view: new Ext.grid.GroupingView({ forceFit:true, groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Books" : "Book"]})' }) If we execute the grouping grid, we will get the following output:   Ext.grid.feature.GroupingSummary The GroupingSummary feature also groups rows with a field in common, but it also adds a summary row at the bottom of each group. Let's change the preceding example to use the GroupingSummary feature: Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [{ groupHeaderTpl: 'Topic: {name}', ftype: 'groupingsummary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); We highlighted two pieces in the preceding code. The first line is the feature declaration: in the previous example (Grouping) we created the feature using the Ext.create declaration. But if we do not want to explicitly create the feature every time we declare, we can use the ftype property, which is groupingsummary in this example. The groupingsummary that we added to the grid's name column is in the second line of highlighted code. We declared a summaryType property and set its value as count. Declaring the summaryType as count means we want to display the number of books in that particular topic/category; it is going to count how many records we have for a particular category in the grid. It is very similar to the count of the PL/SQL language. Other summary types we can declare are: sum, min, max, average (these are self-explanatory). In this example, we want to customize the text that will be displayed in the summary, so we are going to use the summaryRenderer function. We need to pass a value argument to it, and the value is the count of the name column. Then, we are going to return a customized string that is going to display the count (token {0}) and the string book or books, depending on the count (if it is more than 1 we add s at the end of the string book). Ext.String.format is a function that allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each token must be unique and must increment in the format {0}, {1}, and so on. The preceding code will output the following grid: Ext.grid.feature.Summary The GroupingSummary feature adds a row at the bottom of each grouping. The Summary feature adds a row at the bottom of the grid to display summary information. The property configuration is very similar to that for GroupingSummary, because both classes are subclasses of AbstractSummary (a class that provides common properties and methods for summary features). Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'summary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] }); The only difference from the GroupingSummary feature is the feature declaration itself. The summayType and summaryRenderer properties work in a similar way. The preceding code will output the following grid: Ext.grid.feature.RowBody The rowbody feature adds a new tr->td->div in the bottom of the row that we can use to display additional information. Here is how to use it: Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'rowbody', getAdditionalData: function(data, idx, record, orig) { return { rowBody: Ext.String.format( '->topic: {0}', data.topic) }; } }, { ftype: 'rowwrap' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' }] });  In the preceding code, we are not only displaying the name of the book; we are using the rowbody to display the topic of the book as well. The first step is to declare the rowbody feature. One very important thing to be noted is that rowbody will be initially hidden, unless you override the getAdditionalData method. If we execute the preceding code, we will get the following output:
Read more
  • 0
  • 0
  • 6783

article-image-null-16
Packt
30 Jan 2013
4 min read
Save for later

Getting Started with HTML5 Modernizr

Packt
30 Jan 2013
4 min read
Detect and design with features, not User Agents (browsers) What if you could build your website based on features instead of for the individual browser idiosyncrasies by manufacturer and version, making your website not just backward compatible but also forward compatible? You could quite potentially build a fully backward and forward compatible experience using a single code base across the entire UA spectrum. What I mean by this is instead of baking in an MSIE 7.0 version, an MSIE 8.0 version , a Firefox version, and so on of your website, and then using JavaScript to listen for, or sniff out, the browser version in play, it would be much simpler to instead build a single version of your website that supports all of the older generation, latest generation, and in many cases even future generation technologies, such as a video API , box-shadow, first-of-type , and more. Think of your website as a full-fledged cable television network broadcasting over 130 channels, and your users as customers that sign up for only the most basic package available, of only 15 channels. Any time that they upgrade their cable (browser) package to one offering additional channels (features), they can begin enjoying them immediately because you have already been broadcasting to each one of those channels the entire time. What happens now is that a proverbial line is drawn in the sand, and the site is built on the assumption that a particular set of features will exist and are thus supported. If not, fallbacks are in place to allow a smooth degradation of the experience as usual, but more importantly the site is built to adopt features that the browser will eventually have. Modernizr can detect CSS features, such as @font-face , box-shadow , and CSS gradients. It can also detect HTML5 elements, such as canvas, localstorage, and application cache. In all it can detect over 40 features for you, the developer. Another term commonly used to describe this technique is progressive enhancement. When the time finally comes that the user decides to upgrade their browser, the new features that the more recent browser version brings with it, for example text-shadow, will automatically be detected and picked up by your website, to be leveraged by your site with no extra work or code from you when they do. Without any additional work on your part, any text that is assigned text-shadow attributes will turn on at the flick of a switch so that user's experience will smoothly, and progressively be enhanced. What is Modernizr? More importantly, why should you use it? At its foundation, Modernizr is a feature-detection library powered by none other than JavaScript. Here is an example of conditionally adding CSS classes based on the browser, also known as the User Agent. When the browser parses this HTML document and finds a match, that class will be conditionally added to the page. code 1 Now that the browser version has been found, the developer can use CSS to alter the page based on the version of the browser that is used to parse the page. In the following example, IE 7, IE 8, and IE 9 all use a different method for a drop shadow attribute on an anchor element: code 2 The problem with the conditional method of applying styles is that not only does it require more code, but it also leaves a burden on the developer to know what browser version is capable of a given feature, in this case box-shadow . Here is the same example using Modernizr. Note how Modernizr has done the heavy lifting for you, irrespective of whether or not the box-shadow feature is supported by the browser: code 3
Read more
  • 0
  • 0
  • 6768

article-image-modifying-existing-theme-drupal-6-part-1
Packt
20 Oct 2009
10 min read
Save for later

Modifying an Existing Theme in Drupal 6: Part 1

Packt
20 Oct 2009
10 min read
Setting up the workspace There are several software tools that can make your work modifying themes more efficient. Though no specific tools are required to work with Drupal themes, there are a couple of applications that you might want to consider adding to your tool kit. I work with Firefox as my primary browser, principally due to the fact that I can add into Firefox various extensions that make my life easier. The Web Developer extension, for example, is hugely helpful when dealing with CSS and related issues. I recommend the combination of Firefox and the Web Developer extension to anyone working with Drupal themes. Another extension popular with many developers is Firebug, which is very similar to the Web Developer extension, and indeed more powerful in several regards. Pick up Web Developer, Firebug, and other popular Firefox add-ons at https://addons.mozilla.org/en-US/firefox/ When it comes to working with PHP files and the various theme files, you will need an editor. The most popular application is probably Dreamweaver, from Adobe, although any editor that has syntax highlighting would work well too. I use Dreamweaver as it helps me manage multiple projects and provides a number of features that make working with code easier (particularly for designers). If you choose to use Dreamweaver, you will want to tailor the program a little bit to make it easier to work with Drupal theme files. Specifically, you should configure the application preferences to open and edit the various types of files common to PHPTemplate themes. To set this up, open Dreamweaver, then: Go to the Preferences dialogue. Open file types/editors. Add the following list of file types to Dreamweaver's open in code view field: .engine.info.module.install.theme Save the changes and exit. With these changes, your Dreamweaver application should be able to open and edit all the various PHPTemplate theme files. Previewing your work Note that, as a practical matter, previewing Drupal themes requires the use of a server. Themes are really difficult to preview (with any accuracy) without a server environment. A quick solution to this problem is the XAMPP package. XAMPP provides a one step installer containing everything you need to set up a server environment on your local machine (Apache, MySQL, PHP, phpMyAdmin, and more). Visit http://www.ApacheFriends.org to download XAMPP and you can have your own Dev Server quickly and easily. Another tool that should be on the top of your list is the Theme developer extension for the popular Drupal Devel module. Theme developer can save you untold hours of digging around trying to find the right function or template. When the module is active, all you need to do is click on an element and the Theme developer pop-up window will show you what is generating the element, along with other useful information. In the example later in this article, we will also use another feature of the Devel module, that is, the ability to automatically generate sample content for your site. You can download Theme developer as part of the Devel project at Drupal.org: http://drupal.org/project/devel Note that Theme developer only works on Drupal 6 and due to the way it functions, is only suitable for use in a development environment—you don't want this installed on a client's public site! Visit http://drupal.org/node/209561 for more information on the Theme developer aspects of the Devel module. The article includes links to a screencast showing the module in action—a good quick start and a solid help in grasping what this useful tool can do. Planning the modifications We're going to base our work on the popular Zen theme. We'll take Zen, create a new subtheme, and then modify the subtheme until we reach our final goal. Let's call our new theme "Tao". The Zen theme was chosen for this exercise because it has a great deal of flexibility. It is a good solid place to start if you wish to build a CSS-based theme. The present version of Zen even comes with a generic subtheme (named "STARTERKIT") designed specifically for themers who wish to take a basic theme and customize it. We'll use the Starterkit subtheme as the way forward in the steps that follow. The Zen theme is one of the most active theme development projects. Updated versions of the theme are released regularly. We used version 6.x-1.0-beta2 for the examples in this article. Though that version was current at the time this text was prepared, it is unlikely to be current at the time you read this. To avoid difficulties, we have placed a copy of the files used in this article in the software archive that is provided on the Packt website. Download the files used in this article at http://www.packtpub.com/files/code/5661_Code.zip. You can download the current version of Zen at http://drupal.org/project/zen. Any time you set off down the path of transforming an existing theme into something new, you need to spend some time planning. The principle here is the same as in many other areas of life: A little time spent planning at the front end of a project can pay off big in savings later. A proper dissertation on site planning and usability is beyond the scope of this article; so for our purposes let us focus on defining some loose goals and then work towards satisfying a specific wish list for the final site functionality. Our goal is to create a two-column blog-type theme with solid usability and good branding. Our hypothetical client for this project needs space for advertising and a top banner. The theme must also integrate a forum and a user comments functionality. Specific changes we want to implement include: Main navigation menu in the right column Secondary navigation mirrored at the top and bottom of each page A top banner space below top nav but above the branding area Color scheme and fonts to match brand identity Enable and integrate the Drupal blog, forum, and comments modules In order to make the example easier to follow and to avoid the need to install a variety of third-party extensions, the modifications we will make in this article will be done using only the default components—excepting only the theme itself, Zen. Arguably, were you building a site like this for deployment in the real world (rather than simply for skills development) you might wish to consider implementing one or more specialized third-party extensions to handle certain tasks. Creating a new subtheme Install the Zen theme if you have not done so before now; once that is done we're ready to create a new subtheme. First, make a copy of the directory named STARTERKIT and place the copied files into the directory sites/all/themes. Rename the directory "tao". Note that in Drupal 5.x, subthemes were kept in the same directory as the parent theme, but for Drupal 6.x this is no longer the case. Subthemes should now be placed in their own directory inside the sites/all/themes/directory. Note that the authors of Zen have chosen to vary from the default stylesheet naming. Most themes use a file named style.css for their primary CSS. In Zen, however, the file is named zen.css. We need to grab that file and incorporate it into Tao. Copy the Zen CSS (zen/zen/zen.css) file. Rename it tao.css and place it in the Tao directory (tao/tao.css). When you look in the zen/zen directory, in addition to the key zen.css file, you will note the presence of a number of other CSS files. We need not concern ourselves with the other CSS files. The styles contained in those stylesheets will remain available to us (we inherit them as Zen is our base theme) and if we need to alter them, we can override the selectors as needed via our new tao.css file. In addition to renaming the theme directory, we also need to rename any other theme-name-specific files or functions. Do the following: Rename the STARTERKIT.info file to tao.info. Edit the tao.info file to replace all occurrences of STARTERKIT with tao. Open the tao.info file and find this copy: The name and description of the theme used on the admin/build/themes page. name = Zen Themer's StarterKit description = Read the <a href="http://drupal.org/node/226507">online docs</a> on how to create a sub-theme. Replace that text with this copy: The name and description of the theme used on the admin/build/themes page. name = Tao description = A 2-column fixed-width sub-theme based on Zen. Make sure the name= and description = content is not commented out, else it will not register. Edit the template.php file to replace all occurrences of STARTERKIT with tao. Edit the theme-settings.php file to replace all occurrences of STARTERKIT with tao. Copy the file zen/layout-fixed.css and place it in the tao directory, creating tao/layout-fixed.css. Include the new layout-fixed.css by modifying the tao.info file. Change style sheets[all][] = layout.css to style sheets[all][] = layout-fixed.css. The .info file functions similar to a .ini file: It provides configuration information, in this case, for your theme. A good discussion of the options available within the .info file can be found on the Drupal.org site at: http://drupal.org/node/171205 Making the transition from Zen to Tao The process of transforming an existing theme into something new consists of a set of tasks that can categorized into three groups: Configuring the Theme Adapting the CSS Adapting the Templates & Themable Functions Configuring the theme As stated previously, the goal of this redesign is to create a blog theme with solid usability and a clean look and feel. The resulting site will need to support forums and comments and will need advertising space. Let's start by enabling the functionality we need and then we can drop in some sample contents. Technically speaking, adding sample content is not 100% necessary, but practically speaking, it is extremely useful; let's see the impact of our work with the CSS, the templates, and the themable functions. Before we begin, enable your new theme, if you have not done so already. Log in as the administrator, then go to the themes manager (Administer | Site building | Themes), and enable the theme Tao. Set it to be the default theme and save the changes. Now we're set to begin customizing this theme, first through the Drupal system's default configuration options, and then through our custom styling. Enabling Modules To meet the client's functional requirements, we need to activate several features of Drupal which, although contained in the default distro, are not by default activated. Accordingly, we need to identify the necessary modules and enable them. Let's do that now. Access the module manager screen (Administer | Site building | Modules), and enable the following modules: Blog (enables blog-type presentation of content) Contact (enables the site contact forms) Forum (enables the threaded discussion forum) Search (enables users to search the site) Save your changes and let's move on to the next step in the configuration process.
Read more
  • 0
  • 0
  • 6765

article-image-moodle-authentication-methods
Packt
11 Mar 2011
6 min read
Save for later

Moodle: Authentication Methods

Packt
11 Mar 2011
6 min read
Moodle Security Learn how to install and configure Moodle in the most secure way possible Basics of authentication Authentication is the process of confirming that something or someone is really who they claim to be. The ways in which someone may be authenticated fall into three categories, based on what are known as the factors of authentication: Knowledge (something you know): password, PIN code, etc. Ownership (something you have): security token, phone, etc. Inherence (something you are): fingerprint, signature, various biometric identifiers Following the path of most computer systems, Moodle offers basic authentication based on a knowledge factor. This means that in order to operate in Moodle any person must have a user account. A user account consists of a username, password, and other personal information. Both username and password are used to authenticate a person who wishes to access the platform. Based on the outcome of an authentication, a user will be given or declined access to the platform. The authentication is performed (usually) by comparing provided data from the person trying to access the platform with the data located in the Authoritative Data Source (of user identity). Moodle supports 13 different types of authentication and this actually means that it has support for consulting 13 different types of Authoritative Data Sources. An Authoritative Data Source is a recognized or official data production source with a designated mission statement or source/product to publish reliable and accurate data for subsequent use by users or by other computer programs. Logon procedure Logon in Moodle is implemented using a HTML form that submits supplied data over HTTP or HTTPS to the server where it is being processed. Hypertext Transfer Protocol (HTTP) is a networking protocol used for transferring and rendering content on the World Wide Web. HTTP Secure (HTTPS) is a combination of a HTTP protocol and SSL/TLS (Security Socket Layer/ Transport Layer Security) protocol that offers encrypted and thus secures communication and identification between two computers on the Internet. HTTPS connections are often used for payments transactions and other sensitive information's transfer. The user enters his assigned credentials into the supplied fields on the login form and presses Login. That sends data to Moodle for processing. Common authentication attacks Any type of security attack is directed toward potential weak spots in the system that is under attack. The most common weaknesses related to the authentication and ways of protecting from them are as follows: Weak passwords A password that is easily guessed and does not provide an effective defense against unauthorized access to a resource is considered weak. Such passwords are usually: Short Set to dictionary word or name Set to be the same as username Set to some predefined value When we have a platform with weak passwords it can be attacked using brute force login technique (also known as dictionary attack). Dictionary attack is a technique for defeating authentication mechanism by trying to determine its pass-phrase by searching likely possibilities. In practice this means that a bot (automated script) constantly tries to log on by sending various usernames and passwords from a predefined list of words (usually a dictionary list of words—hence the name dictionary attack). Enforcing a good password policy In order to prevent this attack, make sure you have enabled the password policy. Visit Administration | Security | Site policies and locate the Password Policy checkbox. You should arrive at the following screenshot: Password policy is enabled by default starting from Moodle 1.9.7. This applies to both new installs and upgrades. Protecting user login By default, Moodle is configured to use unencrypted HTTP as the main communication protocol between client and server. This is fine for general usage of the platform but it also exposes credential information to the potential eavesdropper who can intercept and read it. This is a common case known as man-in-the-middle attack. The perpetrator makes a separate connection with the client (user's computer) and server (Moodle), forcing all communication to go over his connection. That permits him to look at the entire communication and even inject his own version of messages and responses. Closing the security breach We need to make sure that credential transmission is performed using secure HTTP (HTTPS) because that prevents (or makes it really hard) for anybody to hook into a protected conversation. Here are the steps: Firstly, you should install and configure a valid SSL (Secure Sockets Layer) certificate on your web-server. It is important to do this properly before doing anything else in Moodle; otherwise you might block yourself from accessing the platform. The procedure for installing an SSL certificate is beyond the scope of this book since it involves too many different factors that depend on your server configuration, OS type, and the way you manage it. Please refer to the manual for your particular web server and/or particular procedure of your hosting provider. Valid SSL certificates can be obtained only from certified root authorities—companies with a license for issuing certificates. VeriSign, Thawte, and Comodo are one of the several certificate providers. You need to specify which web server you are using since some of them prefer particular formats. Secondly, you should activate HTTPS log-in in your Moodle. You can do that by going to Administration | Security | HTTP security page and checking Use HTTPS for logins. If everything is configured properly you should see a login page that shows a valid certificate box (see following screenshot) in your browser. This means that a certificate is issued by a valid root authority and that communication between your browser and Moodle is secure which is what we wanted to accomplish in the first place. Every time a user tries to login in Moodle they will be redirected to the secure version of the login page which effectively prevents the interception of user credentials. Password change By default, all newly created users in Moodle (excluding admin) are assigned the Authenticated user role. The authenticated user role by default has permission to change their own password. This feature can be utilized by accessing user profile page. Recover a forgotten password Forgetting a username and/or password is a common situation in which many users find themselves. Moodle offers a procedure for getting a username and resetting the password. The user will be presented with a form where he can enter his username or his e-mail. If the username or email exists in the database, a mail with a reset link will be sent to that user. By clicking on that link, the user is offered a chance to enter a new password. If not configured properly, this feature can be used for determining valid user emails or user-names. See the following screenshot: An attacker would be able to tailor a script that could probe for usernames and, based on the response, can determine valid users.  
Read more
  • 0
  • 0
  • 6760

article-image-professional-environment-react-native-part-1
Pierre Monge
09 Jan 2017
5 min read
Save for later

A Professional Environment for React Native, Part 1

Pierre Monge
09 Jan 2017
5 min read
React Native, a new framework, allows you to build mobile apps using JavaScript. It uses the same design as React.js, letting you compose a rich mobile UI from declarative components. Although many developers are talking about this technology, React Native is not yet approved by most professionals for several reasons: React Native isn’t fully stable yet. At the time of writing this, we are at version 0.40 It can be scary to use a web technology in a mobile application It’s hard to find good React Native developers because knowing the React.js stack is not enough to maintain a mobile React Native app from A to Z! To confront all these prejudices, this series will act as a guide, detailing how we see things in my development team. We will cover the entire React Native environment as well as discuss how to maintain a React Native application. This series may be of interest to companies who want to implement a React Native solution and also of interest to anyone who is looking for the perfect tools to maintain a mobile application in React Native. Let’s start here in part 1 by exploring the React Native environment. The environment The React Native environment is pretty consistent. To manage all of the parts of such an application, you will need a native stack, a JavaScript stack, and specific components from React Native. Let's examine all the aspects of the React Native environment: The Native part consists of two important pieces of software: Android Studio (Android) and Xcode (iOS). Both the pieces of software are provided with their emulators, so there is no need for a physical device! The negative point of Android Studio, however, is that you need to download the SDK, and you will have to find the good versions and download them all. In addition, these two programs take up a lot of room on your hard disk! The JavaScript part naturally consists of Node.js, but we must add Watchman to that to check the changes in a file in real time. The React Native CLI will automate the linking of all software. You only have to run react-native init helloworld to create a project and react-native run-ios --scheme 'Dev' to launch the project on an iOS simulator in debug mode. The supplied react-native controls will load almost everything! You have, no doubt, come to our first conclusion. React Native has a lot of prerequisites, and although it makes sense to have as much dependency as possible, you will have to master them all, which can take some time. And also a lot of space on your hard drive! Try this as your starting point if you want more information on getting started with React Native. Atom, linter, and flow A developer never starts coding without his text editor and his little tricks, just as a woodcutter never goes out into the forest without his ax! More than 80% of people around me use Atom as a text editor. And they are not wrong! React Native is 100% OpenSource, and Atom is also open source. And it is full of plug-ins and themes of all kinds. I personally use a lot of plug-ins, such as color-picker, file-icons, indent-guide-improved, minimap, etc., but there are some plug-ins that should be essential for every JavaScript coder, especially for your React Native application. linter-eslint To work alone or in a group, you must have a common syntax for all your files. To do this, we use linter-eslint with the fbjs configurations. This plugin provides the following: Good indentation Good syntax on how to define variables, objects, classes, etc. Indications on non-existent, unused variables and functions And many other great benefits. Flow One question you may be thinking is what is the biggest problem with using JavaScript? One issue with using JavaScript has always been that it's a language that has no type. In fact, there are types, such as String, Number, Boolean, Function, etc., but that's just not enough. There is no static type. To deal with this, we use Flow, which allows you to perform type check before run-time. This is, of course, useful for predicting bugs! There is even a plug-in version for Atom: linter-flow. Conclusion At this point, you should have everything you need to create your first React Native mobile applications. Here are some great examples of apps that are out there already. Check out part 2 in this series where I cover the tools that can help you maintain your React Native apps. About the author Pierre Monge (liroo.pierre@gmail.com) is a 21 year old student. He is a developer in C, JavaScript, and all things related to web development, and he has recently been creating mobile applications. He is currently working as an intern at a company named Azendoo, where he is developing a 100% React Native application.
Read more
  • 0
  • 0
  • 6723

article-image-performing-table-and-database-operations-phpmyadmin-33x-effective-mysql-management
Packt
12 Oct 2010
4 min read
Save for later

Performing Table and Database Operations in phpMyAdmin 3.3.x for Effective MySQL Management

Packt
12 Oct 2010
4 min read
  Mastering phpMyAdmin 3.3.x for Effective MySQL Management A complete guide to get started with phpMyAdmin 3.3 and master its features The best introduction to phpMyAdmin available Written by the project leader of phpMyAdmin, and improved over several editions A step-by-step tutorial for manipulating data with phpMyAdmin Learn to do things with your MySQL database and phpMyAdmin that you didn't know were possible!        Introduction Various links that enable table operations have been put together on the Operations subpage of the Table view. Here is an overview of this subpage: Maintaining a table During its lifetime, a table repeatedly gets modified and is therefore continually growing and shrinking. In addition, outages may occur on the server, leaving some tables in a damaged state. Using the Operations subpage, we can perform various operations, which are listed next. However, not every operation is available for every storage engine: Check table: Scans all rows to verify that deleted links are correct. A checksum is also calculated to verify the integrity of the keys. If everything is alright, we will obtain a message stating OK or Table is already up to date; if any other message shows up, it's time to repair this table (see the third bullet). Analyze table: Analyzes and stores the key distribution; this will be used on subsequent JOIN operations to determine the order in which the tables should be joined. This operation should be performed periodically (in case data has changed in the table), in order to improve JOIN efficiency. Repair table: Repairs any corrupted data for tables in the MyISAM and ARCHIVE engines. Note that a table might be so corrupted that we cannot even go into Table view for it! In such a case, refer to the Multi-table operations section for the procedure to repair it. Optimize table: This is useful when the table contains overheads. After massive deletions of rows or length changes for VARCHAR fields, lost bytes remain in the table. phpMyAdmin warns us in various places (for example, in the Structure view) if it feels the table should be optimized. This operation reclaims unused space in the table. In the case of MySQL 5.x, the relevant tables that can be optimized use the MyISAM, InnoDB, and ARCHIVE engines. Flush table: This must be done when there have been many connection errors and the MySQL server blocks further connections. Flushing will clear some internal caches and allow normal operations to resume. Defragment table: Random insertions or deletions in an InnoDB table fragment its index. The table should be periodically defragmented for faster data retrieval. This operation causes MySQL to rebuild the table, and only applies to InnoDB. The operations are based on the available underlying MySQL queries—phpMyAdmin only calls those queries. Changing table attributes Table attributes are the various properties of a table. This section discusses the settings for some of them. Table storage engine The first attribute that we can change is called Storage Engine. This controls the whole behavior of the table—its location (on-disk or in-memory), the index structure, and whether it supports transactions and foreign keys. The drop-down list varies depending on the storage engines supported by our MySQL server. Changing a table's storage engine may be a long operation if the number of rows is large. Table comments This allows us to enter comments for the table: These comments will be shown at appropriate places—for example, in the navigation panel, next to the table name in the Table view, and in the export file. Here is what the navigation panel looks like when the $cfg['ShowTooltip'] parameter is set to its default value of TRUE: The default value (FALSE) of $cfg['ShowTooltipAliasDB'] and $cfg['ShowTooltipAliasTB'] produces the behavior we saw earlier—the true database and table names are displayed in the navigation panel and in the Database view for the Structure subpage. Comments appear when the cursor is moved over a table name. If one of these parameters is set to TRUE, the corresponding item (database names for DB and table names for TB) will be shown as a tooltip instead of the names. This time, the mouseover box shows the true name for the item. This is convenient when the real table names are not meaningful. There is another possibility for $cfg['ShowTooltipAliasTB']—the 'nested' value. Here is what happens if we use this feature: The true table name is displayed in the navigation panel The table comment (for example project__) is interpreted as the project name and is displayed as it is
Read more
  • 0
  • 0
  • 6690
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 $19.99/month. Cancel anytime
article-image-advanced-theme-liferay-user-interface-development
Packt
01 Dec 2010
16 min read
Save for later

Advanced Theme in Liferay User Interface Development

Packt
01 Dec 2010
16 min read
Liferay User Interface Development Develop a powerful and rich user interface with Liferay Portal 6.0 Design usable and great-looking user interfaces for Liferay portals Get familiar with major theme development tools to help you create a striking new look for your Liferay portal Learn the techniques and tools to help you improve the look and feel of any Liferay portal A practical guide with lots of sample code included from real Liferay Portal Projects free for use for developing your own projects Changing theme.parent property in theme Liferay provides four different theme implementations out-of-box in the ${PORTAL_ROOT_HOME}/html/themes/ folder as shown in the following screenshot: When you create a new theme in the themes/ directory of the Plugins SDK, the Ant script will copy some files to the new theme from one of these three folders, _styled/, _unstyled/, and classic/, which can be specified in the ${PLUGINS_SDK_HOME}/themes/build-common-theme.xml file. For example, you can go to the ${PLUGINS_SDK_HOME}/themes/ directory and run create.bat palmtree "Palm-Tree Publications theme" on Windows or ./create.sh palmtree "Palm-Tree Publications theme" on Linux, respectively. Or you can use Liferay IDE to create same New Liferay Theme Plugin Project. This will create a theme folder named palmtree-theme in the Liferay Plugins SDK environment. When you run ant to build and deploy the theme and then apply the newly created theme to your page, you will find out that the look and feel of the page is messed up, as shown in the following screenshot: If you are familiar with theme development in Liferay Portal 5.2, you may wonder what has happened to the theme created in Liferay Portal 6 Plugins SDK because you would expect a fully working theme with two simple commands, create and ant. This is because the following build.xml file in your theme specifies _styled as the value for the theme.parent property: <?xml version="1.0"?> <project name="palmtree-theme" basedir="." default="deploy"> <import file="../build-common-theme.xml" /> <property name="theme.parent" value="_styled" /> </project> This means that when your newly created theme is built, it will copy all the files from the _styled/ folder in the ${PORTAL_ROOT_HOME}/html/themes/ directory to the docroot/ folder of your theme. The default _styled/ folder does not have enough files to create a completely working theme and that is why you see a messed-up page when the theme is applied to a page. The reason why this default _styled/ folder does not include enough files is that some Liferay users prefer to have minimal set of files to start with. You can modify the build.xml file for your theme in the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/ folder by changing value of the theme.parent property from _styled to classic, if you prefer to use the Classic theme as the basis for your theme modification. <property name="theme.parent" value="classic" /> Now you will see that your page looks exactly the same as that with the Classic theme after you build and apply your theme to the page (refer to the following screenshot): Adding color schemes to a theme When you create a theme in the Plugins SDK environment, the newly created theme by default supports one implementation and does not automatically have color schemes as variations of the theme. This fits well if you would like to have a consistent look and feel, especially in terms of the color display, across all the pages that the theme is applied to. In your portal application, you might have different sites with slightly different look and feel for different groups of users such as physicians and patients. You might also need to display different pages such as public pages with one set of colors and the private pages with a different set of colors. However, you don't want to create several different themes for reasons such as easy maintenance. In this case, you might consider creating different color schemes in your theme. Color schemes are specified using a Cascading Style Sheets (CSS) class name, with which you are able to not only change the colors, but also choose different background images, border colors, and so on. In the previous section, we created a PalmTree Publication theme, which takes the Classic theme as its parent theme. Now we can follow the mentioned steps to add color schemes to this theme: Copy the ${PORTAL_ROOT_HOME}/webapps/palmtree-theme/WEB-INF/liferay-look-and-feel.xml file to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/WEB-INF/ folder. Open the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/WEB-INF/liferay-look-and-feel.xml file in your text editor. Change <theme id="palmtree" name="PalmTree Publication Theme" /> as shown in the highlighted lines here, and save the change: <look-and-feel> <compatibility> <version>6.0.5+</version> </compatibility> <theme id="palmtree" name="Palm Tree Publications Theme"> <color-scheme id="01" name="Blue"> <css-class>blue</css-class> <color-scheme-images-path>${images-path}/color_schemes/ blue</color-scheme-images-path> </color-scheme> <color-scheme id="02" name="Green"> <css-class>green</css-class> </color-scheme> <color-scheme id="03" name="Orange"> <css-class>orange</css-class> </color-scheme> </theme> </look-and-feel> Go to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/palmtree-theme/_diffs/ folder and create a css/ subfolder. Copy both custom.css and custom_common.css from the ${PORTAL_ROOT_HOME}/html/themes/classic/_diffs/css/ folder to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/css/ folder. This is to let the default styling handle the first color scheme blue. Create a color_schemes/ folder under the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/palmtree-theme/_diffs/css/ folder. Place one .css file for each of your additional color schemes. In this case, we are going to create two additional color schemes: green and orange. To make the explanation simpler, copy both the green.css and orange.css files from the ${PORTAL_ROOT_HOME}/html/themes/classic/_diffs/css/color_schemes/ folder to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/css/color_schemes/ folder. Copy all images from the ${PORTAL_ROOT_HOME}/html/themes/classic/_diffs/images/ folder to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/images/ folder. Add the following lines in your ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/css/custom.css file: @import url(color_schemes/green.css); @import url(color_schemes/orange.css); If you open either the green.css or the orange.css file, you will be able to identify the styling for the CSS by using a color prefix for each CSS definition. For example, in the orange.css file you would find that each item is defined like this: orange .dockbar { background-color: #AFA798; background-image: url(../../images/color_schemes/orange/dockbar /dockbar_bg.png); } .orange .dockbar .menu-button-active { background-color: #DBAC5C; background-image: url(../../images/color_schemes/orange/dockbar /button_active_bg.png); } In the green.css file, the style is defined like this: green .dockbar { background-color: #A2AF98; background-image: url(../../images/color_schemes/green/dockbar/ dockbar_bg.png); } .green .dockbar .menu-button-active { background-color: #95DB5C; background-image: url(../../images/color_schemes/green/dockbar/ button_active_bg.png); } Also, notice that the related images used for the different color schemes are included in the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/images/color_schemes/ folder. Re-build and deploy the PalmTree Publication theme. Log in as administrator and go to the Control Panel to apply this theme to the PalmTree Publications Inc. organization. You will be able to see three color schemes available under this theme. Select any of them to apply it to the Public Pages. Take a screenshot of the page when each of the color schemes is applied and save it as thumbnail.png in the corresponding blue, green, and orange subfolders in the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/images/color_scheme/ folder. Three screenshots are used to distinguish between the three color schemes in the Control Panel as seen in the following screenshot: The following screenshots shows how each of the three color schemes looks when applied to a portal page: As shown in above screenshot, color scheme blue has been applied on the Home page, by default. The following screenshot shows applying color scheme green on the current page. Of course, you would be able to apply color schemes blue or green in the entire site, if required. Similar to color schemes blue and green, you can apply color scheme orange as well on the current page or the entire site, as shown in following screenshot: So it works! The page background is with a hue of gray color. Now, what if we want to change the page background color to red for the green color schema? Update the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/css/color_schemes/green.css file as follows. The commented outline is the original content. The next line after the comment is the new content. The #FF0000 code is for the red color. body.green, .green .portlet { /*background-color: #F1F3EF;*/ background-color: #FF0000; } Re-deploy the PalmTree theme and refresh the portal page that uses the green color scheme. Now, you should be able to see the portal page with a red background color. As you can see, you can use theme color schemes to create some variants of the same theme without creating multiple themes. This is useful when you have different but related user roles such as physicians, nurses, and patients and you need to build a different site for each of them. You can use the color schemes to display each of these sites in a slightly different look and feel. Configurable theme settings There are many use cases where you would like to change some default settings in the theme so that you can modify the values after the theme is built and deployed. Fortunately, each theme can define a set of settings to make this configurable. The settings are defined as key-value pairs in the liferay-look-and-feel.xml file of the theme with the following syntax: <settings> <setting key="my-setting1" value="my-value1" /> <setting key="my-setting2" value="my-value2" /> </settings> These settings can then be accessed in the theme templates using the following code: $theme.getSetting("my-setting1") $theme.getSetting("my-setting2") For example, I need to create two themes—PalmTree Publications theme and AppleTree Publications theme. They are exactly the same except for some differences in the footer content that includes copyright, terms of use, privacy policy, and so on. Instead of creating two themes packaged as separate .war files, we create one set of two themes that share the majority of the code including CSS, JavaScript, images, and most templates; but with one configurable setting and two different implementations of the footer Velocity files. Here is how this can be done: Open ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/WEB-INF/liferay-look-and-feel.xml in the above sample PalmTree theme. Copy the PalmTree theme section and paste it in the same file but after this section. Rename the values of id and name from palmtree and PalmTree Publications theme to appletree and AppleTree Publications theme in the second section. Add the following setting to the palmtree section before the color-scheme definition: <settings> <setting key="theme-id" value="palmtree" /> </settings> Add the following setting to the appletree section before the color-scheme definition: <settings> <setting key="theme-id" value="appletree" /> </settings> Find the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/WEB-INF/liferay-look-and-feel.xml file as follows: <look-and-feel> // ignore details <theme id="palmtree" name="PalmTree Publications Theme"> <settings> <setting key="theme-id" value="palmtree" /> </settings> <color-scheme id="01" name="Blue"> // ignore details </color-scheme> </theme> <theme id="appletree" name="AppleTree Publications Theme"> <settings> <setting key="theme-id" value="appletree" /> </settings> <color-scheme id="01" name="Blue"> // ignore details </color-scheme> </theme> </look-and-feel> Copy the portal_normal.vm file of the Classic theme from the ${PORTAL_ROOT_HOME}/html/themes/classic/_diffs/templates/ folder to the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/templates/ folder. Open the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/templates/portal_normal.vm file Replace the default footer section with the following code: #set ($theme_id = $theme.getSetting("theme-id")) #if ($theme_id == "palmtree") #parse ("$full_templates_path/footer_palmtree.vm") #else #parse ("$full_templates_path/footer_appletree.vm") #end Create your own version of the two footer Velocity templates in the ${PLUGINS_SDK_HOME}/themes/palmtree-theme/docroot/_diffs/templates/ folder. Add related CSS definitions for your footer in your custom.css file. Build and deploy the theme .war file. Now you should be able to see both the PalmTree and AppleTree themes when you go to the Control Panel to apply either theme to your page. Based on the theme to be used, you should also notice that your footer is different. Of course, we can take other approaches to implement a different footer in the theme. For example, you can dynamically get the organization or community name and render the footer differently. However, the approach we explained previously can be expanded to control the UI of the other theme components such as the header, navigation, and portlets. Portal predefined settings in theme In the previous section, we discussed that theme engineers can add configurable custom settings in the liferay-look-and-feel.xml file of a theme. Liferay portal can also include some predefined out-of-the-box settings such as portlet-setup-show-borders-default and bullet-style-options in a theme to control certain default behavior of the theme. Let us use portlet-setup-show-borders-default as an example to explain how Liferay portal controls the display of the portlet border at different levels. If this predefined setting is set to false in your theme, Liferay portal will turn off the borders for all portlets on all pages where this theme is applied to. <settings> <setting key="portlet-setup-show-borders-default" value="false" /> </settings> By default, the value is set to true, which means that all portlets will display the portlet border by default. If the predefined portlet-setup-show-borders-default setting is set to true, it can be overwritten for individual portlets using the liferay-portlet.xml file of a portlet as follows: <liferay-portlet-app> // ignore details <portlet> <portlet-name>sample</portlet-name> <icon>/icon.png</icon> <use-default-template>false</use-default-template> <instanceable>true</instanceable> <header-portlet-css>/css/main.css</header-portlet-css> <footer-portlet-javascript>/js/main.js</footer-portlet-javascript> <css-class-wrapper>sample-portlet</css-class-wrapper> </portlet> // ignore details </liferay-portlet-app> Set the use-default-template value to true if the portlet uses the default template to decorate and wrap content. Setting it to false will allow the developer to maintain the entire output content of the portlet. The default value is true. The most common use of this is when you want the portlet to look different from the other portlets or if you want the portlet not to have borders around the output content. The use-default-template setting of each portlet, after being set to either true or false, in the liferay-portlet.xml file, can be further overwritten by the portlet's popup CSS setting. Users with the appropriate permissions can change it by going to the Look and Feel | Portlet Configuration | Show Borders checkbox of the portlet, as shown in the next screenshot: Embedding non-instanceable portlets in theme One common requirement in theme development is to add some portlets in different components of a theme. For example, you might want to add the Sign In portlet in the header of your theme, the Web Content Search portlet in the navigation area, and the Site Map portlet in the footer area. All the Liferay out-of-the-box portlets can be referred in the ${PORTAL_ROOT_HOME}/WEB-INF/liferay-portlet.xml file. How can this be achieved? Well, it can be quite easy or pretty tricky to embed an out-of-the-box portlet in a theme. Embedding Dockbar and Breadcrumb portlets in a theme The Dockbar portlet is embedded at the very top in the default Classic theme in the portal_normal.vm file as shown next: #if($is_signed_in) #dockbar() #end In the same way, the Breadcrumb portlet can be embedded in the content area of the Classic theme in the portal_normal.vm file: #breadcrumbs() Embedding Language and Web Content Search portlets in a theme Some other Liferay out-of-the-box portlets such as the Language and Web Content Search portlets can be embedded in a theme or a layout template easily. For example, the Web Content Search portlet can be added to the far right side of the horizontal navigation area of your theme as follows in the navigation.vm file of your theme. <div id="navbar"> <div id="navigation" class="sort-pages modify-pages"> <div id="custom"> $theme.journalContentSearch() </div> // ignore details </div> </div> In the same way, the Language portlet can be embedded in the portal_normal.vm Velocity template file of your theme: $theme.language() Again, you need to add the necessary CSS definitions in your custom.css file to control the look and feel and the location of your embedded portlet(s). Embedding Sign In portlet in the header area of a theme Sometimes the theme design requires that the Liferay Sign In portlet be in the header area. By default, the Sign In portlet has a portlet border but we need to disable it. The previously mentioned approaches for embedding a portlet in a theme through Velocity attributes in a template do not work in this case because we need to customize the default UI of the embedded portlet. Instead, we can add the following code to the header section in the portal_normal.vm file in our sample PalmTree theme: #if(!$is_signed_in) #set ($locPortletId = "58") $velocityPortletPreferences.setValue("portlet-setup-show-borders", "false") #set($locRenderedPortletContent = $theme.runtime($locPortletId, "", $velocityPortletPreferences.toString())) $locRenderedPortletContent $velocityPortletPreferences.reset() #end After the theme is re-built and re-deployed, we can see that the Sign In portlet is rendered in the header area underneath the logo without the portlet border. The next step for us is to modify the custom.css file and the related files by adding CSS definition to control the location and look and feel of this Sign In portlet. The following screenshot shows the Sign In portlet in the header area and the Web Content Search portlet in the navigation area in a working theme in the production environment:
Read more
  • 0
  • 0
  • 6685

article-image-php-5-social-networking-implementing-public-messages
Packt
26 Oct 2010
7 min read
Save for later

PHP 5 Social Networking: Implementing Public Messages

Packt
26 Oct 2010
7 min read
PHP 5 Social Networking Create a powerful and dynamic Social Networking website in PHP by building a flexible framework   Build a flexible Social Networking framework using PHP which can be extended to fit the needs of any Social Networking site Develop a suitable structure for our framework, with MVC to structure the architecture and a Registry to store core Objects Allow users to connect and communicate with each other using communication with friends list, flexible user profiles, messages, discussions, and much more Plan marketing and scaling strategies, to entice more users and ensure the site can cope with the demand Packed with real-world code and clear explanation, this book uses an ongoing case study for creating a Social Networking framework Throughout the course of this article we will be using a social networking site for keepers of pet dinosaurs (of course nobody owns a real pet dinosaur, but for the sake of this article, let's pretend!), which we will call DinoSpace. Public messages The status stream fully supports public messages and streaming them to the Dino Space members. What we don't yet have, however, is support for users to post messages on the profiles of other users, so, let's add that in now. Controller A user should only be able to post a message on another user's profile if they are connected. The post message form should only be displayed if the users are connected. Similarly, a public message post should only be processed if the two users are connected. The controller also needs to display messages that have been posted on a user's profile too. Displaying profile messages If we look at our Profilestatusescontroller (controllers/profile/ profilestatusescontroller.php), in the listRecentStatuses method, we have our query for listing recent profile statuses: $sql = "SELECT t.type_reference, t.type_name, s.*, p.name as poster_name FROM statuses s, status_types t, profile p WHERE t.ID=s.type AND p.user_id=s.poster AND p.user_id={$user} ORDER BY s.ID DESC LIMIT 20"; At the moment, this query pulls in any posts on a user's profile by the user whose profile it is. If that user has made a post on someone else's profile, the message instead shows on the user's own profile, which we don't want. We need to change this to pull in the profiles table twice, once for the user who made the post, and again for the user whose profile is being viewed. We will also want to only pull in posts made on the user's profile, and not posts made by the user on another user's profile (though this is something we can expand on in the future, perhaps to indicate that a user has made a post on the profile of another user). The following query should meet our requirements nicely: $sql = "SELECT t.type_reference, t.type_name, s.*, pa.name as poster_name FROM statuses s, status_types t, profile p, profile pa WHERE t.ID=s.type AND p.user_id=s.profile AND pa.user_id=s.poster AND p.user_id={$user} ORDER BY s.ID DESC LIMIT 20"; Now, if we view a user's profile, we see their own status updates, and messages posted on their profile by other users, as shown in the following screenshot: Displaying the post message box The listRecentStatuses method we were just editing is the method we need to edit to display the post message box. This box should only be displayed if the user is logged in, and is connected to the user. If the user is viewing their own profile, then they should see a box to update their own status: // post status / public message box if( $this->registry->getObject('authenticate')->isLoggedIn() == true ) { $loggedInUser = $this->registry->getObject('authenticate')- >getUser()->getUserID(); If the logged in user is viewing their own profile, then we add the update template to the view, so they can update their status: if( $loggedInUser == $user ) { $this->registry->getObject('template')->addTemplateBit('status_ update', 'profile/statuses/update.tpl.php' ); } else { If the user isn't viewing their own profile, but is logged in, we get any connections the user has: require_once( FRAMEWORK_PATH . 'models/relationships.php' ); $relationships = new Relationships( $this->registry ); $connections = $relationships->getNetwork( $user, false ); if( in_array( $loggedInUser, $connections ) ) { If the user is connected to the user whose profile they are viewing, then we allow them to post a message on the users profile with the post template: $this->registry->getObject('template')->addTemplateBit( 'status_update', 'profile/statuses/post.tpl.php' ); } else { If the user isn't connected to the user, or isn't logged in, then we simply remove the template tag from the view so they don't see any update or post box on the page: $this->registry->getObject('template')->getPage()- >addTag( 'status_update', '' ); } } } else { $this->registry->getObject('template')->getPage()- >addTag( 'status_update', '' ); } Now, we need to process status updates and profile posts, and create the templates that make up the final aspect of our view. Process a new message The same logic that we used to determine whether the user should see a post form is what we need to use to determine if we should process a status update, or public message submission. Status model To save the status update or public profile post in the database, we will need a status model; as with our previous models, this simply needs to represent the fields from the database, with setter methods for these fields, and a save method to insert a new record into the database. In the future, we may wish to extend this to pull in statuses from the database, and save changes to them, as well as deleting statuses, perhaps if the owner of the message or the owner of the profile the message was posted on wishes to edit or delete it. The following is suitable code for our status model (models/status.php): <?php /** * Status model */ class Status { /** * The registry object */ private $registry; /** * Statuses ID */ private $id; /** * Poster of the status update / profile message */ private $poster; /** * The profile the status update / profile message was posted on */ sprivate $profile; /** * Type of status */ private $type; /** * The update / profile message itself */ private $update; /** * Reference for the type of status */ private $typeReference = 'update'; /** * Constructor * @param Registry $registry the registry object * @param int $id ID of the status update / profile message * @return void */ public function __construct( Registry $registry, $id=0 ) { $this->registry = $registry; $this->id = 0; } /** * Set the poster of the status / profile message * @param int $poster the id of the poster * @return void */ public function setPoster( $poster ) { $this->poster = $poster; } /** * Set the profile that the message / status is posted on * @param int $profile the profile ID * @return void */ public function setProfile( $profile ) { $this->profile = $profile; } /** * Set the status / profile message itself * @param String $status * @return void */ public function setStatus( $status ) { $this->status = $status; } /** * Set the type of status / profile message * @param int $type * @return void */ public function setType( $type ) { $this->type = $type; } /** * Set the type reference, so we can get the type ID from the database * @param String $typeReference the reference of the type * @return void */ public function setTypeReference( $typeReference ) { $this->type = $typeReference; } /** * Generate the type of status based of the type reference * @return void */ public function generateType() { $sql = "SELECT * FROM status_types WHERE type_reference='{$this->typeReference}'"; $this->registry->getObject('db')->executeQuery( $sql ); $data = $this->registry->getObject('db')->getRows(); $this->type = $data['ID']; } /** * Save the status / profile message * @return void */ public function save() { if( $this->id == 0 ) { $insert = array(); $insert['update'] = $this->status; $insert['type'] = $this->type; $insert['poster'] = $this->poster; $insert['profile'] = $this->profile; $this->registry->getObject('db')- >insertRecords( 'statuses', $insert ); $this->id = $this->registry->getObject('db')->lastInsertID(); } } } ?> Now that we have some functionality to easily insert the status into the database, we need to update our profile controller to process the new status update.
Read more
  • 0
  • 0
  • 6649

article-image-how-to-build-remote-controlled-tv-node-webkit
Roberto González
08 Jul 2015
14 min read
Save for later

How to build a Remote-controlled TV with Node-Webkit

Roberto González
08 Jul 2015
14 min read
Node-webkit is one of the most promising technologies to come out in the last few years. It lets you ship a native desktop app for Windows, Mac, and Linux just using HTML, CSS, and some JavaScript. These are the exact same languages you use to build any web app. You basically get your very own Frameless Webkit to build your app, which is then supercharged with NodeJS, giving you access to some powerful libraries that are not available in a typical browser. As a demo, we are going to build a remote-controlled Youtube app. This involves creating a native app that displays YouTube videos on your computer, as well as a mobile client that will let you search for and select the videos you want to watch straight from your couch. You can download the finished project from https://github.com/Aerolab/youtube-tv. You need to follow the first part of this guide (Getting started) to set up the environment and then run run.sh (on Mac) or run.bat (on Windows) to start the app. Getting started First of all, you need to install Node.JS (a JavaScript platform), which you can download from http://nodejs.org/download/. The installer comes bundled with NPM (Node.JS Package Manager), which lets you install everything you need for this project. Since we are going to be building two apps (a desktop app and a mobile app), it’s better if we get the boring HTML+CSS part out of the way, so we can concentrate on the JavaScript part of the equation. Download the project files from https://github.com/Aerolab/youtube-tv/blob/master/assets/basics.zip and put them in a new folder. You can name the project’s folder youtube-tv  or whatever you want. The folder should look like this: - index.html // This is the starting point for our desktop app - css // Our desktop app styles - js // This is where the magic happens - remote // This is where the magic happens (Part 2) - libraries // FFMPEG libraries, which give you H.264 video support in Node-Webkit - player // Our youtube player - Gruntfile.js // Build scripts - run.bat // run.bat runs the app on Windows - run.sh // sh run.sh runs the app on Mac Now open the Terminal (on Mac or Linux) or a new command prompt (on Windows) right in that folder. Now we’ll install a couple of dependencies we need for this project, so type these commands to install node-gyp and grunt-cli. Each one will take a few seconds to download and install: On Mac or Linux: sudo npm install node-gyp -g sudo npm install grunt-cli -g  On Windows: npm install node-gyp -g npm install grunt-cli -g Leave the Terminal open. We’ll be using it again in a bit. All Node.JS apps start with a package.json file (our manifest), which holds most of the settings for your project, including which dependencies you are using. Go ahead and create your own package.json file (right inside the project folder) with the following contents. Feel free to change anything you like, such as the project name, the icon, or anything else. Check out the documentation at https://github.com/rogerwang/node-webkit/wiki/Manifest-format: { "//": "The // keys in package.json are comments.", "//": "Your project’s name. Go ahead and change it!", "name": "Remote", "//": "A simple description of what the app does.", "description": "An example of node-webkit", "//": "This is the first html the app will load. Just leave this this way", "main": "app://host/index.html", "//": "The version number. 0.0.1 is a good start :D", "version": "0.0.1", "//": "This is used by Node-Webkit to set up your app.", "window": { "//": "The Window Title for the app", "title": "Remote", "//": "The Icon for the app", "icon": "css/images/icon.png", "//": "Do you want the File/Edit/Whatever toolbar?", "toolbar": false, "//": "Do you want a standard window around your app (a title bar and some borders)?", "frame": true, "//": "Can you resize the window?", "resizable": true}, "webkit": { "plugin": false, "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36" }, "//": "These are the libraries we’ll be using:", "//": "Express is a web server, which will handle the files for the remote", "//": "Socket.io lets you handle events in real time, which we'll use with the remote as well.", "dependencies": { "express": "^4.9.5", "socket.io": "^1.1.0" }, "//": "And these are just task handlers to make things easier", "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-copy": "^0.6.0", "grunt-node-webkit-builder": "^0.1.21" } } You’ll also find Gruntfile.js, which takes care of downloading all of the node-webkit assets and building the app once we are ready to ship. Feel free to take a look into it, but it’s mostly boilerplate code. Once you’ve set everything up, go back to the Terminal and install everything you need by typing: npm install grunt nodewebkitbuild You may run into some issues when doing this on Mac or Linux. In that case, try using sudo npm install and sudo grunt nodewebkitbuild. npm install installs all of the dependencies you mentioned in package.json, both the regular dependencies and the development ones, like grunt and grunt-nodewebkitbuild, which downloads the Windows and Mac version of node-webkit, setting them up so they can play videos, and building the app. Wait a bit for everything to install properly and we’re ready to get started. Note that if you are using Windows, you might get a scary error related to Visual C++ when running npm install. Just ignore it. Building the desktop app All web apps (or websites for that matter) start with an index.html file. We are going to be creating just that to get our app to run: <!DOCTYPE html><html> <head> <metacharset="utf-8"/> <title>Youtube TV</title> <linkhref='http://fonts.googleapis.com/css?family=Roboto:500,400'rel='stylesheet'type='text/css'/> <linkhref="css/normalize.css"rel="stylesheet"type="text/css"/> <linkhref="css/styles.css"rel="stylesheet"type="text/css"/> </head> <body> <divid="serverInfo"> <h1>Youtube TV</h1> </div> <divid="videoPlayer"> </div> <script src="js/jquery-1.11.1.min.js"></script> <script src="js/youtube.js"></script> <script src="js/app.js"></script> </body> </html> As you may have noticed, we are using three scripts for our app: jQuery (pretty well known at this point), a Youtube video player, and finally app.js, which contains our app's logic. Let’s dive into that! First of all, we need to create the basic elements for our remote control. The easiest way of doing this is to create a basic web server and serve a small web app that can search Youtube, select a video, and have some play/pause controls so we don’t have any good reasons to get up from the couch. Open js/app.js and type the following: // Show the Developer Tools. And yes, Node-Webkit has developer tools built in! Uncomment it to open it automatically//require('nw.gui').Window.get().showDevTools(); // Express is a web server, will will allow us to create a small web app with which to control the playervar express = require('express'); var app = express(); var server = require('http').Server(app); var io = require('socket.io')(server); // We'll be opening up our web server on Port 8080 (which doesn't require root privileges)// You can access this server at http://127.0.0.1:8080var serverPort =8080; server.listen(serverPort); // All the static files (css, js, html) for the remote will be served using Express.// These assets are in the /remote folderapp.use('/', express.static('remote')); With those 7 lines of code (not counting comments) we just got a neat web server working on port 8080. If you were paying attention to the code, you may have noticed that we required something called socket.io. This lets us use websockets with minimal effort, which means we can communicate with, from, and to our remote instantly. You can learn more about socket.io at http://socket.io/. Let’s set that up next in app.js: // Socket.io handles the communication between the remote and our app in real time, // so we can instantly send commands from a computer to our remote and backio.on('connection', function (socket) { // When a remote connects to the app, let it know immediately the current status of the video (play/pause)socket.emit('statusChange', Youtube.status); // This is what happens when we receive the watchVideo command (picking a video from the list)socket.on('watchVideo', function (video) { // video contains a bit of info about our video (id, title, thumbnail)// Order our Youtube Player to watch that video Youtube.watchVideo(video); }); // These are playback controls. They receive the “play” and “pause” events from the remotesocket.on('play', function () { Youtube.playVideo(); }); socket.on('pause', function () { Youtube.pauseVideo(); }); }); // Notify all the remotes when the playback status changes (play/pause)// This is done with io.emit, which sends the same message to all the remotesYoutube.onStatusChange =function(status) { io.emit('statusChange', status); }; That’s the desktop part done! In a few dozen lines of code we got a web server running at http://127.0.0.1:8080 that can receive commands from a remote to watch a specific video, as well as handling some basic playback controls (play and pause). We are also notifying the remotes of the status of the player as soon as they connect so they can update their UI with the correct buttons (if it’s playing, show the pause button and vice versa). Now we just need to build the remote. Building the remote control The server is just half of the equation. We also need to add the corresponding logic on the remote control, so it’s able to communicate with our app. In remote/index.html, add the following HTML: <!DOCTYPE html><html> <head> <metacharset=“utf-8”/> <title>TV Remote</title> <metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1"/> <linkrel="stylesheet"href="/css/normalize.css"/> <linkrel="stylesheet"href="/css/styles.css"/> </head> <body> <divclass="controls"> <divclass="search"> <inputid="searchQuery"type="search"value=""placeholder="Search on Youtube..."/> </div> <divclass="playback"> <buttonclass="play">&gt;</button> <buttonclass="pause">||</button> </div> </div> <divid="results"class="video-list"> </div> <divclass="__templates"style="display:none;"> <articleclass="video"> <figure><imgsrc=""alt=""/></figure> <divclass="info"> <h2></h2> </div> </article> </div> <script src="/socket.io/socket.io.js"></script> <script src="/js/jquery-1.11.1.min.js"></script> <script src="/js/search.js"></script> <script src="/js/remote.js"></script> </body> </html> Again, we have a few libraries: Socket.io is served automatically by our desktop app at /socket.io/socket.io.js, and it manages the communication with the server. jQuery is somehow always there, search.js manages the integration with the Youtube API (you can take a look if you want), and remote.js handles the logic for the remote. The remote itself is pretty simple. It can look for videos on Youtube, and when we click on a video it connects with the app, telling it to play the video with socket.emit. Let’s dive into remote/js/remote.js to make this thing work: // First of all, connect to the server (our desktop app)var socket = io.connect(); // Search youtube when the user stops typing. This gives us an automatic search.var searchTimeout =null; $('#searchQuery').on('keyup', function(event){ clearTimeout(searchTimeout); searchTimeout = setTimeout(function(){ searchYoutube($('#searchQuery').val()); }, 500); }); // When we click on a video, watch it on the App$('#results').on('click', '.video', function(event){ // Send an event to notify the server we want to watch this videosocket.emit('watchVideo', $(this).data()); }); // When the server tells us that the player changed status (play/pause), alter the playback controlssocket.on('statusChange', function(status){ if( status ==='play' ) { $('.playback .pause').show(); $('.playback .play').hide(); } elseif( status ==='pause'|| status ==='stop' ) { $('.playback .pause').hide(); $('.playback .play').show(); } }); // Notify the app when we hit the play button$('.playback .play').on('click', function(event){ socket.emit('play'); }); // Notify the app when we hit the pause button$('.playback .pause').on('click', function(event){ socket.emit('pause'); }); This is very similar to our server, except we are using socket.emit a lot more often to send commands back to our desktop app, telling it which videos to play and handle our basic play/pause controls. The only thing left to do is make the app run. Ready? Go to the terminal again and type: If you are on a Mac: sh run.sh If you are on Windows: run.bat If everything worked properly, you should be both seeing the app and if you open a web browser to http://127.0.0.1:8080 the remote client will open up. Search for a video, pick anything you like, and it’ll play in the app. This also works if you point any other device on the same network to your computer’s IP, which brings me to the next (and last) point. Finishing touches There is one small improvement we can make: print out the computer’s IP to make it easier to connect to the app from any other device on the same Wi-Fi network (like a smartphone). On js/app.js add the following code to find out the IP and update our UI so it’s the first thing we see when we open the app: // Find the local IPfunction getLocalIP(callback) { require('dns').lookup( require('os').hostname(), function (err, add, fam) { typeof callback =='function'? callback(add) :null; }); } // To make things easier, find out the machine's ip and communicate itgetLocalIP(function(ip){ $('#serverInfo h1').html('Go to<br/><strong>http://'+ip+':'+serverPort+'</strong><br/>to open the remote'); }); The next time you run the app, the first thing you’ll see is the IP for your computer, so you just need to type that URL in your smartphone to open the remote and control the player from any computer, tablet, or smartphone (as long as they are in the same Wi-Fi network). That's it! You can start expanding on this to improve the app: Why not open the app on a fullscreen by default? Why not get rid of the horrible default frame and create your own? You can actually designate any div as a window handle with CSS (using -webkit-app-region: drag), so you can drag the window by that div and create your own custom title bar. Summary While the app has a lot of interlocking parts, it's a good first project to find out what you can achieve with node-webkit in just a few minutes. I hope you enjoyed this post! About the author Roberto González is the co-founder of Aerolab, “an awesome place where we really push the barriers to create amazing, well-coded designs for the best digital products”. He can be reached at @robertcode.
Read more
  • 0
  • 0
  • 6647

article-image-magentos-architecture-part-1
Packt
01 Feb 2010
5 min read
Save for later

Magento's Architecture: Part 1

Packt
01 Feb 2010
5 min read
Magento's base structure The fundamental knowledge of Magento's architecture begins with its file structure. It's important to know what goes where by default, so that we may position our new files accordingly, especially in terms of ensuring that our development doesn't overwrite core files. Base directory The default installation contains the following files and directories in the base directory: .htaccess .htaccess.sample 404 (directory) app (directory) cron.php downloader (directory) favicon.ico index.php index.php.sample js (directory) lib (directory) LICENSE_AFL.txt LICENSE.txt media (directory) pear pkginfo (directory) report (directory) skin (directory) var (directory) Each of these files and directories has a different purpose. We'll go through them to ensure that we understand the function of each. This will help us later, if ever we need to find something specific, or when developing. It will also be helpful when we'll be looking to place the files coming out of our new module into the appropriate directory. The function of each of the files in the base directory The following is a run through of all the files in the base directory, to show us what they do: .htaccess—This file controls mod_rewrite for fancy URLs and sets configuration server variables (such as memory limit) and PHP maximum execution time, so that Magento can run better. .htaccess.sample—Works as a backup for .htaccess, so that we know the default .htaccess file (if ever we edit it and need to backtrack). cron.php—The file that should be executed as a cron job every few minutes to ensure that Magento's wide caching doesn't affect our server's performance. favicon.ico—Magento's default favicon; it's the small icon that appears in the toolbar of our browser. index.php—The main loader file for Magento and the file that initializes everything. index.php.sample—The base template for new index.php files, useful when we have edited the index.php file and need to backtrack. LICENSE_AFL.txt—It contains the Academic Free License that Magento is distributed under. LICENSE.txt—It contains the Open Software License that Magento is distributed under. pear—This controls all automatic updating via the downloader and SSH. This file is initialized and handles the updating of each individual module that makes up Magento. php.ini—A sample php.ini file for raw PHP server variables recommended when setting up Magento on our server. This should not be used as a complete replacement, but only as a guide to replace certain lines of the php.ini server file. It is useful when overriding these variables when .htaccess isn't enabled on our server. The function of each of the folders in the base directory The following is a run through of all the folders in the base directory to show us their contents: 404—The default 404 template and skin storage folder for Magento. app—All code (modules), design (themes), configuration, and translation files are stored in this directory. This is the folder that we'll be working in extensively, when developing a Magento powered website. Also contained in this folder are the template files for the default administration theme and installation. downloader—The web downloader for upgrading and installing Magento without the use of SSH. js—The core folder where all JavaScript code included with the installation of Magento is kept. We will find all pre-compiled libraries of JavaScript here. lib—All PHP libraries used to put together Magento. This is the core code of Magento that ties everything together. The Zend Framework is also stored within this directory. media—All media is stored here. Primarily for images out of the box, this is where all generated thumbnails and uploaded product images will be stored. It is also the container for importing images, when using the mass import/export tools. pkginfo—Short form of package information, this directory contains text files that largely operate as debug files to inform us about changes when modules are upgraded in any way. report—The skin folder for the reports that Magento outputs when any error occurs. skin—All assets for themes are stored within this directory. We typically find images, JavaScript files, CSS files, and Flash files relating to themes, in this directory. However, it can be used to store any assets associated with a theme. It also contains the skin files for the installation of skins and administration templates. var—Typically where we will find all cache and generated files for Magento. We can find the cache, sessions (if storing as files), data exports, database backups, and cached error reports in this folder. The template system architecture The template architecture is broken into three areas—two for development of the theme and one for the containment of the assets: /app/design/frontend/default/<template_name>/ layout/—For all the XML files declaring which module tied functions should be called to which template files template/—For all the templates processing the output that is passed from functions called from layout/ and structured into the final output to the user. /skin/frontend/default/<template_name>/—For the containment of all assets relating to our template, images, CSS, Flash, and JavaScript. Structural blocks and content blocks Each theme contains structural and content blocks. Structural blocks are the ones that lay out the theme into sections. Let's take a look at a three-column layout. The following are the structural blocks in a three-column layout: header left content right footer Here's a visual representation of those structural blocks laid over the Magento demo store: In each of the structural blocks, we then have content blocks that give each structural block its content for output to the browser. Let's take the right column; our content blocks set for this column on a standard theme could be: mini cart recently viewed products newsletter subscription block poll
Read more
  • 0
  • 0
  • 6646
article-image-develop-php-web-applications-netbeans-virtualbox-and-turnkey-lamp-appliance
Packt
01 Oct 2009
4 min read
Save for later

Develop PHP Web Applications with NetBeans, VirtualBox and Turnkey LAMP Appliance

Packt
01 Oct 2009
4 min read
A couple of days ago, a client asked me for an easy way to develop PHP applications. Naturally, I told him the best way would be to pay me for doing it! Just kidding… "Use the NetBeans IDE", I said to him, almost automatically. "But… isn’t NetBeans something related to Java?" he answered back, with a startled grin on his face. "My dear friend, you can use NetBeans to develop software on Java, PHP, C++, and almost any other programming language I’ve heard of! You could even use it to work on a WordPress live Web site!" I said to him triumphantly. And that’s when a small light bulb lit up inside my mind... I introduced him to VirtualBox and the world of virtual machines, the Turnkey Linux LAMP appliance, and how to make all these software applications collaborate between each other. And that’s how this article was born. So now, my dear readers, let’s get on with the action! Oh, and feel free to skip any section you don’t need, ok? Download and Install VirtualBox Go to the VirtualBox Web site and download the most recent version: http://download.virtualbox.org/virtualbox/3.0.4/VirtualBox-3.0.4-50677-Win.exe After downloading VirtualBox, install it with all the default options (remember to register with Sun!). Download the Turnkey LAMP appliance Go to the Turnkey Linux Web site and download the LAMP appliance: http://www.turnkeylinux.org/download?file=turnkey-lamp-2009.02-hardy-x86.iso . Download the NetBeans PHP IDE Go to the Sun Web site and download the NetBeans PHP IDE here. After downloading NetBeans, install it with the default options. Create a virtual machine Open VirtualBox and click on the New button to create a virtual machine (VM). In the following screenshot I used the VirtualPHPDev name for my VM, but you can use whatever you want; just don’t use strange characters or signs: Choose Linux and Ubuntu as the Operating System and Version, respectively. Click on Next to continue. Leave the default values for RAM and hard disk. When finished, click on the VirtualBox Settings button to open your virtual machine’s settings dialog, select the CD/DVD-ROM category, enable the Mount CD/DVD drive option, select the ISO Image File button and then click on the Invoke Virtual Media Manager button . Click on the Add button in the Virtual Media Manager to open up the Select a CD/DVD-ROM disk image file, go to the directory where you downloaded the Turnkey LAMP appliance and double-click on it to add it to the Virtual Media Manager: Click on Select to close the Virtual Media Manager, and then click on OK to exit the Settings dialog. Now you can click on the Start button to start your LAMP virtual machine: Select the Install to hard disk option in the Turnkey Linux menu screen and press Enter to start installing the LAMP appliance on your virtual machine. Eventually the following screen will show up: Select the Guided option and press Enter to continue. The installer will ask if you want to save changes to disk. Select Yes and press Enter. The installer will start the disk formatting process and then you’ll get to the root password screen. Type the password twice for the root user, and then do the same for the MySQL user. The installer will continue and, after a while, the following installation completion screen will show up: Select No, press Enter and then close the virtual machine typing shutdown -r now at the system prompt. You’ll return to the VirtualBox main screen. With your LAMP virtual machine selected, click on the Settings button to open the settings dialog box. Select the CD/DVD-ROM category and disable the Mount CD/DVD drive option. Then select the Network category, change the Attached to: option to Bridged Adapter and click on OK to continue: You can start your LAMP virtual machine now. When ready, the following screen will appear: The Bridged Adapter mode lets your virtual machine act as if it were another PC on the LAN, and consequently, it will have a different IP address. Write down the IP address shown in the Turnkey Linux Configuration Console screen, because you’ll need it to configure the NetBeans IDE later. You can minimize the LAMP virtual machine window now.
Read more
  • 0
  • 0
  • 6629

article-image-common-api-liferay-portal-systems-development
Packt
01 Feb 2012
11 min read
Save for later

Common API in Liferay Portal Systems Development

Packt
01 Feb 2012
11 min read
(For more resources on Liferay, see here.) User management The portal has defined user management with a set of entities, such as, User, Contact, Address, EmailAddress, Phone, Website, and Ticket, and so on at /portal/service.xml. In the following section, we're going to address the User entity, its association, and relationship. Models and services The following figure depicts these entities and their relationships. The entity User has a one-to-one association with the entity Contact, which may have many contacts as children. And the entity Contact has a one-to-one association with the entity Account, which may have many accounts as children. The entity Contact can have a many-to-many association with the entities Address, EmailAddress, Phone, Website, and Ticket. Logically, the entities Address, EmailAddress, Phone, Website, and Ticket may have a many-to-many association with the other entities, such as Group, Organization, and UserGroup as shown in the following image: Services The following table shows user-related service interfaces, extensions, utilities, wrappers, and their main methods: Interface Extension Utility/Wrapper Main methods UserService, UserLocalService PersistedModelLocalService User(Local)ServiceUtil, User(Local)ServiceWrapper add*, authenticate*, check*, decrypt*, delete*, get*, has*, search, unset*, update*, and so on. ContactService, ContactLocalService persistedmodellocalservice> Contact(Local)ServiceUtil, Contact(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. AccountService, AccountLocalService Account(Local)ServiceUtil, Account(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. AddressService, AddressLocalService Address(Local)ServiceUtil, Address(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. EmailAddressService, EmailAddressLocalService PersistedModelLocalService Address(Local)ServiceUtil, Address(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. PhoneService, PhoneLocalService PersistedModelLocalService Phone(Local)ServiceUtil, Phone(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. WebsiteService, WebsiteLocalService PersistedModelLocalService Website(Local)ServiceUtil, Website(Local)ServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on. TicketLocalService PersistedModelLocalService TicketLocalServiceUtil, TicketLocalServiceWrapper add*, create*, delete*, get*, update*, dynamicQuery, and so on.   Relationships The portal also defined many-to-many relationships between User and Group, User and Organization, User and Team, User and UserGroup, as shown in the following code: <column name="groups" type="Collection" entity="Group" mapping-table="Users_Groups" /> <column name="userGroups" type="Collection" entity="UserGroup" mapping-table="Users_UserGroups" /> In particular, you will be able to find a similar definition at /portal/service.xml. Sample portal service portlet The portal provides a sample portal service plugin called sample-portal-service-portlet (refer to the plugin details at /portlets/sample-portal-service-portlet). The following is the code snippet: List organizations = OrganizationServiceUtil.getUserOrganizations( themeDisplay.getUserId()); // add your logic The previous code shows how to consume Liferay services through regular Java calls. These services include com.liferay.portal.service.OrganizationServiceUtil and the model involves com.liferay.portal.model.Organization. Similarly, you can use other services, for example, com.liferay.portal.service.UserServiceUtil and com.liferay.portal.service.GroupServiceUtil; and models, for example, com.liferay.portal.model.User, com.liferay.portal.model.Group. Of course, you can find other services and models—you will find services located at the com. liferay.portal.service package in the /portal-service/src folder. In the same way, you will find models located at the com.liferay.portal.model package in the /portal-service/src folder. What's the difference between *LocalServiceUtil and *ServiceUtil? The sign * represents models, for example, Organization, User, Group, and so on. Generally speaking, *Service is the remote service interface that defines the service methods available to remote code. *ServiceUtil has an additional permission check, since this method might be called as a remote service. *ServiceUtil is a facade class that combines the service locator with the actual call to the service *Service. While *LocalService is the internal service interface,*LocalServiceUtil is a facade class that combines the service locator with the actual call to the service *LocalService. *Service has a PermissionChecker in each method, and *LocalService usually doesn't have the same. Authorization Authorization is a process of finding out if the user, once identified, is permitted to have access to a resource. The portal implemented authorization by assigning permissions via roles and checking permissions, and this is called Role-Based Access Control (RBAC). The following figure depicts an overview of authorization. A user can be a member of Group, UserGroup, Organization, or Team. And a user or a group of users, such as Group, UserGroup, or Organization can be a member of Role. And the entity Role can have many ResourcePermission entities associated with it, while the entity ResourcePermission may contain many ResourceAction entities, as shown in the following diagram: The following table shows the entities Role, ResourcePermission, and ResourceAction: Interface Extension Wrapper/SOAP Main methods Role RoleModel, PersistedModel RoleWrapper, RoleSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. ResourceAction ResourceActionModel, PersistedModel ResourceActionWrapper, ResourceActionSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. ResourcePermission ResourcePermissionModel, PersistedModel ResourcePermissionWrapper, ResourcePermissionSoap clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on. In addition, the portal specifies role constants in the class RoleConstants. The entity ResourceAction gets specified with the columns name, actionId, and bitwiseValue as follows: <column name="name" type="String" /> <column name="actionId" type="String" /> <column name="bitwiseValue" type="long" /> The entity ResourcePermission gets specified with the columns name, scope, primKey, roleId, and actionIds as follows: <column name="name" type="String" /> <column name="scope" type="int" /> <column name="primKey" type="String" /> <column name="roleId" type="long" /> <column name="ownerId" type="long" /> <column name="actionIds" type="long" /> In addition, the portal specified resource permission constants in the class ResourcePermissionConstants Password policy The portal implements enterprise password policies and user account lockout using the entities PasswordPolicy and PasswordPolicyRel, as shown in the following table: Interface Extension Wrapper/Soap Description PasswordPolicy PasswordPolicyModel, PersistedModel PasswordPolicyWrapper, PasswordPolicySoap Columns: name, description, minAge, minAlphanumeric, minLength, minLowerCase, minNumbers, minSymbols, minUpperCase, lockout, maxFailure, lockoutDuration, and so on. PasswordPolicyRel PasswordPolicyRelModel, PersistedModel PasswordPolicyRelWrapper, PasswordPolicyRelSoap Columns: passwordPolicyId, classNameId, and classPK. Ability to associate the entity PasswordPolicy with other entities.   Passwords toolkit The portal has defined the following properties related to the passwords toolkit in portal.properties: passwords.toolkit= com.liferay.portal.security.pwd.PasswordPolicyToolkit passwords.passwordpolicytoolkit.generator=dynamic passwords.passwordpolicytoolkit.static=iheartliferay The property passwords.toolkit defines a class name that extends com.liferay.portal.security.pwd.BasicToolkit, which is called to generate and validate passwords. If you choose to use com.liferay.portal.security.pwd.PasswordPolicyToolkit as your password toolkit, you can choose either static or dynamic password generation. Static is set through the property passwords.passwordpolicytoolkit.static and dynamic uses the class com.liferay.util.PwdGenerator to generate the password. If you are using LDAP password syntax checking, you will also have to use the static generator, so that you can guarantee that passwords obey their rules. The passwords' toolkits get addressed in detail in the following table: Class Interface Utility Property Main methods DigesterImpl Digester DigesterUtil passwords.digest.encoding digest, digestBase64, digestHex, digestRaw, and so on. Base64 None None None decode, encode, fromURLSafe, objectToString, stringToObject, toURLSafe, and so on. PwdEncryptor None None passwords.encryption.algorithm encrypt, default types: MD2, MD5, NONE, SHA, SHA-256, SHA-384, SSHA, UFC-CRYPT, and so on .   Authentication Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be. The portal defines the class called PwdAuthenticator for authentication, as shown in the following code: public static boolean authenticate( String login, String clearTextPassword, String currentEncryptedPassword) { String encryptedPassword = PwdEncryptor.encrypt( clearTextPassword, currentEncryptedPassword); if (currentEncryptedPassword.equals(encryptedPassword)) { return true; } } As you can see, it encrypts the clear text password first into the variable encryptedPassword. It then tests whether the variable currentEncryptedPassword has the same value as that of the variable encryptedPassword or not. The classes UserLocalServiceImpl (the method authenticate) and EditUserAction (the method updateUser) call the class PwdAuthenticator for authentication. A Message Authentication Code (MAC) is a short piece of information used to authenticate a message. The portal supports MAC through the following properties: auth.mac.allow=false auth.mac.algorithm=MD5 auth.mac.shared.key= To use authentication with MAC, simply post to a URL as follows: It passes the MAC in the password field. Make sure that the MAC gets URL encoded, since it might contain characters not allowed in a URL. Authentication with MAC also requires that you set the following property in system-ext.properties: com.liferay.util.servlet.SessionParameters=false As shown in the previous code, it encrypts session parameters, so that browsers can't remember them. Authentication pipeline The portal provides the authentication pipeline framework for authentication, as shown in the following code: auth.pipeline.pre=com.liferay.portal.security.auth.LDAPAuth auth.pipeline.post= auth.pipeline.enable.liferay.check=true As you can see, the property auth.pipeline.enable.liferay.check is set to true to enable password checking by the internal portal authentication. If it is set to false, essentially, password checking is delegated to the authenticators configured in the auth.pipeline.pre and auth.pipeline.post settings. The interface com.liferay.portal.security.auth.Authenticator defines the constant values that should be used as return code from the classes implementing the interface. If authentication is successful, it returns SUCCESS; if the user exists but the passwords doesn't match, then it returns FAILURE. If the user doesn't exist in the system, it returns DNE. Constants get defined in the interface Authenticator. As shown in the following table, the available authenticator is com.liferay.portal.security.auth.LDAPAuth: Class Extension Involved properties Main Methods PasswordPolicyToolkit BasicToolkit passwords.passwordpolicytoolkit.charset.lowercase, passwords.passwordpolicytoolkit.charset.numbers, passwords.passwordpolicytoolkit.charset.symbols, passwords.passwordpolicytoolkit.charset.uppercase, passwords.passwordpolicytoolkit.generator, passwords.passwordpolicytoolkit.static generate, validate RegExpToolkit BasicToolkit passwords.regexptoolkit.pattern, passwords.regexptoolkit.charset, passwords.regexptoolkit.length generate, validate PwdToolkitUtil None passwords.toolkit Generate, validate PwdGenerator None None getPassword. getPinNumber   Authentication token The portal provides the interface com.liferay.portal.security.auth.AuthToken for the authentication token as follows: auth.token.check.enabled=true auth.token.impl= com.liferay.portal.security.auth.SessionAuthToken As shown in the previous code, the property auth.token.check.enabled is set to true to enable authentication token security checks. The checks can be disabled for specific actions via the property auth.token.ignore.actions or for specific portlets via the init parameter check-auth-token in portlet.xml. The property auth.token.impl is set to the authentication token class. This class must implement the interface AuthToken. The class SessionAuthToken is used to prevent CSRF (Cross-Site Request Forgery) attacks. The following table shows the interface AuthToken and its implementation: Class Interface Properties Main Methods LDAPAuth Authenticator ldap.auth.method, ldap.referral, ldap.auth.password.encryption.algorithm, ldap.base.dn, ldap.error.user.lockout, ldap.error.password.expired, ldap.import.user.password.enabled, ldap.base.provider.url, auth.pipeline.enable.liferay.check, ldap.auth.required authenticateByEmailAddress, authenticateByScreenName, authenticateByUserId   JAAS Java Authentication and Authorization Service (JAAS) is a Java security framework for user-centric security to augment the Java code-based security. The portal has specified a set of properties for JAAS as follows: portal.jaas.enable=false portal.jaas.auth.type=userId portal.impersonation.enable=true The property portal.jaas.enable is set to false to disable JAAS security checks. Disabling JAAS would speed up login. Note that JAAS must be disabled, if administrators are able to impersonate other users. JAAS can authenticate users based on their e-mail address, screen name, user ID, or login, as determined by the property company.security.auth.type. By default, the class com.liferay.portal.security.jaas.PortalLoginModule loads the correct JAAS login module, based on what application server or servlet container the portal is deployed on. You can set a JAAS implementation class to override this behavior. The following table shows this class and its associations: Class Interface Properties Main methods AuthTokenImpl AuthToken auth.token.impl check, getToken AuthTokenWrapper AuthToken None check, getToken AuthTokenUtil None None check, getToken SessionAuthToken AuthToken auth.token.shared.secret check, getToken   As you have noticed, the classes com.liferay.portal.kernel.security.jaas, PortalLoginModule, and com.liferay.portal.security.jaas.PortalLoginModule, implement the interface LoginModule, configured by the property portal.jaas.impl. As shown in the following table, the portal has provided different login module implementation for different application servers or servlet containers: Class Interface/Extension Package Main methods ProtectedPrincipal Principal com.liferay.portal.kernel.servlet getName, equals, hasCode, toString PortalPrincipal ProtectedPrincipal com.liferay.portal.kernel.security.jaas PortalPrincipal PortalRole PortalPrincipal com.liferay.portal.kernel.security.jaas PortalRole PortalGroup PortalPrincipal, java.security.acl.Group com.liferay.portal.kernel.security.jaas addMember, isMember, members, removeMember PortalLoginModule javax.security.auth.spi.LoginModule com.liferay.portal.kernel.security.jaas, com.liferay.portal.security.jaas abort, commit, initialize, login, logout  
Read more
  • 0
  • 0
  • 6602

article-image-state-play-buddypress-themes
Packt
22 Oct 2013
13 min read
Save for later

State of Play of BuddyPress Themes

Packt
22 Oct 2013
13 min read
(For more resources related to this topic, see here.) What is BuddyPress? BuddyPress had its first release in April 2009 and is a plugin that you use with WordPress to bring community features to your site. BuddyPress is capable of so much, from connecting and bringing together an existing community through to building new communities. A few things you can create are: A community for your town or village An intranet for a company A safe community for students of a school to interact with each other A community around a product or event A support network for people with the same illness BuddyPress has a lot of different features; you can choose which you want to use. These include groups, streams, messaging, and member profiles. BuddyPress and WordPress are open source projects released under the GPL license. You can find out more about GPL here: http://codex.wordpress.org/License. A team of developers work on the project and anyone can get involved and contribute. As you use BuddyPress, you may want to get more involved in the project itself or find out more. There are a number of ways you can do this: The main site http://buddypress.org/ and the development blog at http://bpdevel.wordpress.com. For support and information there is http://buddypress.org/support/ and http://codex.buddypress.org. If you use IRC, you can use the dedicated channels on irc.freenode.net #buddypress or #buddypress-dev. The developer meeting is every Wednesday at 19:00 UTC in #buddypress-dev. IRC (Internet Relay Chat) is a form of real-time Internet text messaging (chat). You can find out more here: http://codex.wordpress.org/IRC. What is a theme? Your site theme can be thought of as the site design, but it's more than colors and fonts. Themes work by defining templates, which are then used for each section of your site (for instance, a front page or a single blog post). In the case of a BuddyPress theme, it brings BuddyPress templates and functionality on top of the normal WordPress theme. At the heart of any BuddyPress theme are the same files a WordPress theme needs; here are some useful WordPress theme resources: Wordpress.org theme handbook: http://make.wordpress.org/docs/theme-developer-handbook/ WordPress CSS coding standards: http://make.wordpress.org/core/handbook/coding-standards/css/ Theme check plugin (make sure you're using the WordPress standards): http://wordpress.org/extend/plugins/theme-check/ There is a great section in the WordPress codex on design and layout: http://codex.wordpress.org/Blog_Design_and_Layout How BuddyPress themes used to work BuddyPress in the past needed a theme to work. This theme had several variations; the latest of these was BP-Default, which is shown in the following screenshot: This is the default theme before BuddyPress 1.7 This theme was a workhorse solution giving everything a style, making sure you could be up and running with BuddyPress on your site. For a long time, the best way was to use this theme and create a child theme to then do what you wanted for your site. A child theme inherits the functionality of the parent theme. You can add, edit, and modify in the child theme without affecting the parent. This is a great way to build on the foundation of an existing theme and still be able to do updates and not affect the parent. For more information about a child theme see: http://codex.wordpress.org/Child_Themes. The trouble with default The BuddyPress default theme allowed people without much knowledge to set up BuddyPress, but it wasn't ideal. Fairly quickly, everything started to look the same and the learning curve to create your own theme was steep. People made child themes that often just looked more like clones. The fundamental issue above all was that it was a plugin that needed a theme and this wasn't the right way to do things. A plugin should work as best it can in any theme. There had been work done on bbPress to make the change in the theme compatibility and the time was right for BuddyPress to follow suit. bbPress is a plugin that allows you to easily create forums in your WordPress site and also integrate into BuddyPress. You can learn more about bbPress here: http://bbpress.org. Theme compatibility Theme compatibility in simple terms means that BuddyPress works with any theme. Everything that is required to make it work is included in the plugin. You can now go and get any theme from wordpress.org or other sites and be up and running in no time. Should you want to use your own custom template, it's really easy thanks to theme compatibility. So long as you give it the right name and place it in the right location in your theme, BuddyPress when loading will use your file instead of its own. Theme compatibility is always active as this allows BuddyPress to add new features in future versions. You can see this in the following screenshot: Here you see BuddyPress 1.7 in the Twenty Twelve theme Do you still need a BuddyPress theme? Probably by now you're asking yourself if you even need a theme for BuddyPress. With theme compatibility while, you don't have to, there are many reasons why you'd want to. A custom theme allows you to tailor the experience for your community. Different communities have different needs, one size doesn't fit all. Theme compatibility is great, but there is still a need for themes that focus on community and the other features of BuddyPress. A default experience will always be default and not tailored to your site or for BuddyPress. There are many things when creating a community theme that a normal WordPress theme won't have taken into account. This is what we mean when we nowadays refer to BuddyPress themes. There is still a need for these and a need to understand how to create them. Communities A community is a place for people to belong. Creating a community isn't something you should do lightly. The best advice when creating a community is to start small and build up functionality over time. Social networking on the other hand is purely about connections. Social networking is only part of a community. Most communities have far more than just social networking. When you are creating a community you want to focus on enabling your members to make strong connections. Niche communities BuddyPress is perfect for creating niche communities. These are pockets of people united by a cause, by a hobby, or by something else. However, don't think niche means small. Niche communities can be of any size. Having a home online for a community, a place where people of the same mindset, same experiences can unite, that's powerful. Niche communities can be forces for change, a place of comfort, give people a chance to be heard, or sometimes a place just to be. Techniques A community should encourage engagement and provide paths for users to easily accomplish tasks. You may provide areas, such as for user promotion, for user generated content, set achievements for completing tasks or allow users to collect points and have leaderboards. The idea of points and achievements comes from something called Gamification and is a powerful technique. Gamification techniques leverage people's natural desires for competition, achievement, status, self-expression, altruism and closure —Wikipedia (http://en.wikipedia.org/wiki/Gamification) Community is something you experience offline and online. When you are creating a community it's great to look at both. Think how groups of people interact, how they get tasks done together, and what hurdles they experience. Knowing a little bit about psychology will help you create a design that works for the community. Responsive design Responsive web design (RWD) is a web design approach aimed at crafting sites to provide an optimal viewing experience—easy reading and navigation with a minimum of resizing, panning, and scrolling—across a wide range of devices (from desktop computer monitors to mobile phones) —Wikipedia When you create your theme, you need to be careful to design it not only for one device. The world is multi-device and your theme should adapt to the device it's being used on without causing any issues. There are several options open to you when looking to create a theme that works across all devices. What about adaptive design? Responsive designs worked initially a lot by using media queries in CSS to create designs that adapted to CSS media queries. From this emerged the term adaptive design. There are many definitions of what responsive and adaptive mean. Adaptive loosely means progressive enhancement and responsive web design is part of this. You could say that responsive web design is the technique and adaptive design is the movement. A media query consists of a media type and zero or more expressions that check for the conditions of particular media features: http://www.w3.org/TR/css3-mediaqueries/. Mobile first Mobile first makes sure that the site works first for the smallest screen size. As you move up, styles are added using media queries to use the extra screen real estate. This was a phrase coined by Luke Wroblewski. This is a lighter approach and often preferred as it loads just what the device needs. Do you need an app? In the WordPress world, mobile themes tend to come in the form of plugins or apps. Historically, most WordPress themes had a mobile theme and this theme showed only to those accessing a mobile device. You were presented with a default theme that looked the same regardless of the site and there was often no way to see a non-mobile experience (a point of frustration on larger mobile devices). When thinking about mobile apps or plugins, a good rule of thumb is to ask if it's bringing something extra to your site. This could be focusing on one aspect, or making something mobile so devices have access to integrate. If they are simply changing the look of your site you can deal with that in your theme. You shouldn't need an app or plugin to get your site working on a mobile device. In the wild – BuddyPress custom themes There is a whole world out there of great BuddyPress examples, so let's take a little bit of time to get inspired and see what others have done. The following list shows some of the custom themes: Cuny Academic Commons: http://commons.gc.cuny.edu/. This is run by the City University of New York and is for supporting faculty initiatives along with building community. Enterprise Nation: http://enterprisenation.com. This site is a business club encouraging connections and sharing of information. Goed en wel.nl: http://goedenwel.nl. This is a community for 50-65 year olds and built around five areas of interest. Shift.ms: http://shift.ms. This is a community run by and for young people with multiple sclerosis. Teen Summer Challenge: http://teensummerchallenge.org. This site is part of an annual reading program for teens run by Pierce County Library. Trainerspace: http://www.trainerspace.com. This site is a place to go to find a trainer and those trainers can also have their own website. If you want to discover more great BuddyPress sites, BP Inspire is a great showcase site at http://www.bpinspire.com/. What are the options while creating a theme? There are several options available to you when creating a BuddyPress theme: Use an existing WordPress theme with theme compatibility Use an existing BuddyPress theme Create custom CSS with another theme Create custom templates – use in child theme or existing theme Create everything from custom Later, we will take a look at each of these and how each works. WordPress themes You can get free WordPress themes from the WordPress theme repository http://wordpress.org/extend/themes/ and also buy from many great theme shops. You can also use a theme framework. A framework goes beyond a theme and has a lot of extra tools to help you build your theme rolled in. You can learn more about theme frameworks here: http://codex.wordpress.org/Theme_Frameworks. BuddyPress themes You can get both free and paid BuddyPress themes if you want something a little bit more than theme compatibility. A BuddyPress theme, as we discussed earlier, brings something extra and it may bring that to all the features or just some. It is a theme designed to take your site beyond what theme compatibility brings. Free themes If you are looking for free themes your first place should be the theme repository on WordPress.org http://wordpress.org/extend/themes/. The theme repository page will look like the following screenshot: This is the WordPress.org theme repository where you can find BuddyPress themes You can find BuddyPress themes by searching for the word buddypress. Here you can see a range of themes. A few free themes you may want to consider are: Custom Community by svenl77: http://wordpress.org/extend/themes/custom-community. Fanwood by tungdo http://wordpress.org/extend/themes/fanwood. Frisco by David Carson: http://wordpress.org/extend/themes/frisco-for-buddypress. Status by buddypressthemers: http://wordpress.org/extend/themes/status. 3oneseven: http://3oneseven.com/buddypress-themes/. Infinity Theme Engine: http://infinity.presscrew.com. Commons in a box: http://commonsinabox.org. All the power of the CUNY site (mentioned earlier) with a theme engine. Themes to buy Buying a theme is a good way to get a lot of features from custom themes without the cost or learning involved in custom development. The downside of course is that you will not have a custom look, but if your budget and time is limited this may be a good option. When you buy a theme, be careful and as like with anything online, make sure you buy from a reputable source. There are a number of theme shops selling BuddyPress themes including (not extensive list): BuddyBoss: http://www.buddyboss.com Mojo Themes: http://www.mojo-themes.com Press Crew: http://shop.presscrew.com Theme Loom: http://themeloom.com/themes/pure-theme/ Theme Forest: http://themeforest.net/category/wordpress/buddypress Themekraft: http://themekraft.com WPMU DEV: http://premium.wpmudev.org Summary As you can see from this article, the way things are done now since the release of BuddyPress 1.7 are a little bit different to before, thanks to theme compatibility. This is great and means there is no better time than now to start developing BuddyPress themes. In this article we skimmed over a lot of important issues that anyone making a theme has to consider. These are important, just like knowing how to build. You should have in mind the users you are creating for and what their experience will be. We all view sites on different devices, we all need to have a similar experience and not one where we're penalized. Resources for Article: Further resources on this subject: Customizing WordPress Settings for SEO [Article] The Basics of WordPress and jQuery Plugin [Article] Anatomy of a WordPress Plugin [Article]
Read more
  • 0
  • 0
  • 6593
article-image-different-types-q-replication
Packt
16 Nov 2010
5 min read
Save for later

The different types of Q Replication

Packt
16 Nov 2010
5 min read
There are four basic types of Q replication: Unidirectional Bidirectional Peer-to-peer Event Publishing Replicating to a stored procedure or a Consistent Change Data (CCD) table are a subset of unidirectional replication. Let's look at each of these in more detail. Unidirectional replication In unidirectional replication, we can replicate all of the rows and columns of a source table or we can just replicate a subset of the rows and columns. We cannot really perform any transformation on this data. If we want to perform some sort of transformation, then we would need to replicate to a stored procedure. Replicating to a stored procedure Stored procedure replication is a subset of unidirectional replication in which the target is not a table as such, but a stored procedure, as shown in the following diagram: A stored procedure can transform the data and output the results to a target table. This target table is not known to Q Apply. These stored procedures can be written in SQL, C, or Java. Prior to DB2 9.7 the source table and the stored procedure must have the same name, and the target table name can be any name we like. Bidirectional replication In bidirectional replication, we replicate copies of tables between two servers, each of which has a copy of the table. Note that we can only set up bidirectional replication between two servers. Unlike unidirectional replication, where we can replicate a subset of rows and columns, this is not possible in bidirectional replication. The tables on both servers can have different names, but must have the same number of rows and columns. The columns must have identical column names of compatible data types. It is not possible to do any data transformation using this type of replication. Because we are updating records on both servers, it is possible that the same record will be updated at the same time on both servers. Although Q replication provides a conflict detection mechanism, we strongly advise that the driving application should be written or modified in such a way that such conflicts be avoided. The conflict detection provided by Q replication should be treated as a safety net and not the primary conflict resolution mechanism. This mechanism allows us to choose which data values are used to detect conflicts (key column values only, changed column values, or all column values) and which server should win if such a conflict is detected. The row in the losing system is rolled back and the record is written to the IBMQSNAP_EXCEPTIONS table for review. One of the related subjects to conflict detection is the concept of which server takes precedence in a conflict, or to put it more bluntly, which server is the master and which is the slave! If there is a conflict, then whichever server takes precedence will not apply changes from the other server. This ensures that the servers remain in sync. There is a more egalitarian option, which is that no server takes precedence. In this situation, rows are applied irrespective of whether or not there is a conflict, which ultimately leads to a divergence of the contents of the databases, which is not good! There are two types of bidirectional replication—the first type is where we have an active/passive setup and the second type is where we have an active/active setup. The type of replication you choose will have implications on which server is defined as the master and which as the slave and what to do if a Q subscription is inadvertently inactivated. In an active/passive setup, the passive server should be made the master. In an active/active setup, the choice of which system is the master is a decision you have to make. Peer-to-peer replication Peer-to-peer replication allows us to replicate data between two or more servers. This is different from bidirectional replication, which is only between two servers. Each server has a copy of the table (which can have a different schema and name), but must have the same number of rows and columns and these columns must have identical column names and compatible data types. It is not possible to do any data transformation using this type of replication. In peer-to-peer replication, there is no such thing as a master or slave server—each server will have the most recent copy of the table—eventually! What this means is that there will be a slight delay between the first server having a copy of the table and the last server having that copy. This is an asynchronous process, so at any one time the tables might be different, but once applications stop updating them, then the tables will converge to the most recently updated value. This type of processing means that there isn't any "manual" conflict detection as such (it is handled automatically by Q Apply), because the latest update will always win. If two applications update the same record at exactly the same time, then Q replication uses the server number allocated when the peer-to-peer environment was set up to determine the winner. This type of processing means that two columns are added to each of the tables in the Q replication environment, where the first column is a timestamp of when the row was last updated (GMT) and the second column is the machine number. These updates are performed through triggers on the tables.
Read more
  • 0
  • 0
  • 6568

article-image-gamification-moodle-lms
Packt
19 Oct 2015
11 min read
Save for later

Gamification with Moodle LMS

Packt
19 Oct 2015
11 min read
 In this article by Natalie Denmeade, author of the book, Gamification with Moodle describes how teachers can use Gamification design in their course development within the Moodle Learning Management System (LMS) to increase the motivation and engagement of learners. (For more resources related to this topic, see here.) Gamification is a design process that re-frames goals to be more appealing and achievable by using game design principles. The goal of this process is it to keep learners engaged and motivated in a way that is not always present in traditional courses. When implemented in elegant solutions, learners may be unaware of the subtle game elements being used. A gamification strategy can be considered successful if learners are more engaged, feel challenged and confident to keep progressing, which has implications for the way teachers consider their course evaluation processes. It is important to note that Gamification in education is more about how the person feels at certain points in their learning journey than about the end product which may or may not look like a game. Gamification and Moodle After following the tutorials in this book, teachers will gain the basic skills to get started applying Gamification design techniques in their Moodle courses. They can take learners on a journey of risk, choice, surprise, delight, and transformation. Taking an activity and reframing it to be more appealing and achievable sounds like the job description of any teacher or coach! Therefore, many teachers are already doing this! Understanding games and play better can help teachers be more effective in using a wider range of game elements to aid retention and completions in their courses. In this book you will find hints and tips on how to apply proven strategies to online course development, including the research into a growth mindset from Carol Dweck in her book Mindset. You will see how the use of game elements in Foursquare (badges), Twitter (likes), and Linkedin (progress bar), can also be applied to Moodle course design. In addition, you will use the core features available in Moodle which were designed to encourage learner participation as they collaborate, tag, share, vote, network, and generate learning content for each other. Finally, explore new features and plug-ins which offer dozens of ways that teachers can use game elements in Moodle such as, badges, labels, rubrics, group assignments, custom grading scales, forums, and conditional activities. A benefit of using Moodle as a Gamification LMS is it was developed on social constructivist principles. As these are learner-centric principles this means it is easy to use common Moodle features to apply gamification through the implementation of game components, mechanics and dynamics. These have been described by Kevin Werbach (in the Coursera MOOC on Gamification) as: Game Dynamics are the grammar: (the hidden elements) Constraints, emotions, narrative, progression, relationships Game Mechanics are the verbs: The action is driven forward by challenges, chance, competition/cooperation, feedback, resource acquisition, rewards, transactions, turns, win states Game Components are the nouns: Achievements, avatars, badges, boss fights, collections, combat, content, unlocking, gifting, leaderboards, levels, points, quests, teams, virtual goods Most of these game elements are not new ideas to teachers. It could be argued that school is already gamified through the use of grades and feedback. In fact it would be impossible to find a classroom that is not using some game elements. This book will help you identify which elements will be most effective in your current context. Teachers are encouraged to start with a few and gradually expanding their repertoire. As with professional game design, just using game elements will not ensure learners are motivated and engaged. The measure of success of a Gamification strategy is that learners continue to build resilience and autonomy in their own learning. When implemented well, the potential benefits of using a Gamification design process in Moodle are to: Provide manageable set of subtasks and tasks by hiding and revealing content Make assessment criteria visible, predictable, and in plain English using marking guidelines and rubrics Increase ownership of learning paths through choice and activity restrictions Build individual and group identity through work place simulations and role play Offer freedom to fail and try again without negative repercussions Increase enjoyment of both teacher and learners When teachers follow the step by step guide provided in this book they will create a basic Moodle course that acts as a flexible framework ready for learning content. This approach is ideal for busy teachers who want to respond to the changing needs and situations in the classroom. The dynamic approach keeps Teachers in control of adding and changing content without involving a technology support team. Onboarding tips By using focussed examples, the book describes how to use Moodle to implement an activity loop that identifies a desired behaviour and wraps motivations and feedback around that action. For example, a desired action may be for each learner to update their Moodle profile information with their interests and an avatar. Various motivational strategies could be put in place to prompt (or force) the learners to complete this task, including: Ask learners to share their avatars, with a link to their profile in a forum with ratings. Everyone else is doing it and they will feel left out if they don't get a like or a comment (creating a social norm). They might get rated as having the best avatar. Update the forum type so that learners can't see other avatars until they make a post. Add a theme (for example, Lego inspired avatars) so that creating an avatar is a chance to be creative and play. Choosing how they represent themselves in an online space is an opportunity for autonomy. Set the conditional release so learners cannot see the next activity until this activity is marked as complete (for example, post at least 3 comments on other avatars). The value in this process is that learners have started building connections between new classmates. This activity loop is designed to appeal to diverse motivations and achieve multiple goals: Encourages learners to create an online persona and choose their level of anonymity Invite learners to look at each other’s profiles and speed up the process of getting to know each other Introduce learners to the idea of forum posting and rating in a low-risk (non-assessable) way Take the workload off the Teacher to assess each activity directly Enforce compliance through software options which saves admin time and creates an expectation of work standards for learners Feedback options Games celebrate small and large successes and so should Moodle courses. There are a number of ways to do this in Moodle, including simply automating feedback with a Label, which is revealed once a milestone is reached. These milestones could be an activity completion, topic completion, or a level has been reached in the course total. Feedback can be provided through symbols of the achievement. Learners of all ages are highly motivated by this. Nearly all human cultures use symbols, icons, medals and badges to indicate status and achievements such as a black belt in Karate, Victoria Cross and Order of Australia Medals, OBE, sporting trophies, Gold Logies, feathers and tattoos. Symbols of achievement can be achieved through the use of open badges. Moodle offers a simple way to issue badges in line with Open Badges Industry (OBI) standards. The learner can take full ownership of this badge when they export it to their online backpack. Higher education institutes are finding evidence that open badges are a highly effective way to increase motivation for mature learners. Kaplan University found the implementation of badges resulted in increased student engagement by 17 percent. As well as improving learner reactions to complete harder tasks, grades increased up to 9 percent. Class attendance and discussion board posts increased over the non-badged counterparts. Using open badges as a motivation strategy enables feedback to be regularly provided along the way from peers, automated reporting and the teacher. For advanced Moodlers, the book describes how rubrics can be used for "levelling up" and how the Moodle gradebook can be configured as an exponential point scoring system to indicate progress. Social game elements Implementing social game elements is a powerful way to increase motivation and participation. A Gamification experiment with thousands of MOOC participants measured participation of learners in three groups of "plain, game and social". Students in the game condition had a 22.5 percent higher test score in the final test compared to students in the plain condition. Students in the social condition showed an even stronger increase of almost 40 percent compared to students in the plain condition. (See A Playful Game Changer: Fostering Student Retention in Online Education with Social Gamification Krause et al, 2014). Moodle has a number of components that can be used to encourage collaborative learning. Just as the online gaming world has created spaces where players communicate outside of the game in forums, wikis and You Tube channels as well as having people make cheat guides about the games and are happy to share their knowledge with beginners. In Moodle we can imitate these collaborative spaces gamers use to teach each other and make the most of the natural leaders and influencers in the class. Moodle activities can be used to encourage communication between learners and allow delegation and skill-sharing. For example, the teacher may quickly explain and train the most experienced in the group how to perform a certain task and then showcase their work to others as an example. The learner could create blog posts which become an online version of an exercise book. The learner chooses the sharing level so classmates only, or the whole world, can view what is shared and leave comments. The process of delegating instruction through the connection of leader/learners to lagger/learners, in a particular area, allows finish lines to be at different points. Rather spending the last few weeks marking every learner’s individual work, the Teacher can now focus their attention on the few people who have lagged behind and need support to meet the deadlines. It's worth taking the time to learn how to configure a Moodle course. This provides the ability to set up a system that is scalable and adaptable to each learner. The options in Moodle can be used to allow learners to create their own paths within the boundaries set by a teacher. Therefore, rather than creating personalised learning paths for every student, set up a suite of tools for learners to create their own learning paths. Learning how to configure Moodle activities will reduce administration tasks through automatic reports, assessments and conditional release of activities. The Moodle activities will automatically create data on learner participation and competence to assist in identifying struggling learners. The inbuilt reports available in Moodle LMS help Teachers to get to know their learners faster. In addition, the reports also create evidence for formative assessment which saves hours of marking time. Through the release from repetitive tasks, teachers can spend more time on the creative and rewarding aspects of teaching. Rather than wait for a game design company to create an awesome educational game for a subject area, get started by using the same techniques in your classroom. This creative process is rewarding for both teachers and learners because it can be constantly adapted for their unique needs. Summary Moodle provides a flexible Gamification platform because teachers are directly in control of modifying and adding a sequence of activities, without having to go through an administrator. Although it may not look as good as a video game (made with an extensive budget) learners will appreciate the effort and personalisation. The Gamification framework does require some preparation. However, once implemented it picks up a momentum of its own and the teacher has a reduced workload in the long run. Purchase the book and enjoy a journey into Gamification in education with Moodle! Resources for Article: Further resources on this subject: Virtually Everything for Everyone [article] Moodle for Online Communities [article] State of Play of BuddyPress Themes [article]
Read more
  • 0
  • 0
  • 6559
Modal Close icon
Modal Close icon