Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-why-do-we-need-specialist-security-distros
Packt
24 Oct 2009
4 min read
Save for later

Why Do We Need Specialist Security Distros?

Packt
24 Oct 2009
4 min read
I talk with Ryan Berens, from Guardian Digital makers of EnGarde Linux, to understand their role in the Linux distribution space. EnGarde is distributed in two flavors -- one of which can be had for gratis. EnGarde is what you'd call a minimalist distribution that you'd install on your server to run critical services. It's also popular for its one-stop WebTool remote administration tool. Mayank Sharma: Why do we need a specialist security distro? Why is this better than the 'adding security apps to an existing distro on the server' approach? Guardian Digital: These platforms exist to fulfill a significant need in the market. Many users want a hardened platform because locking down a system can be both difficult and time-consuming. The challenge of creating a secure foundation requires a holistic view over all of system resources, not only at default settings, but as configurations need to change. Hardened platforms, designed and built with security from the ground up, create a much more streamlined, integrated system that ensures a system can stay secure. Bloated distro's can be very insecure by default and overcoming that initial state won't be as effective as building security in from the ground up to ensure that tools all work together to minimize access to and control over resources. Simply adding a couple applications doesn't mean they necessarily 'play' well with other apps or the OS in order to perform as securely as needed. MS: What is involved in packaging a secure distro? Is there more to it than just packaging firewall and network monitoring apps? GD: So much more. As I said in the previous answer, a strong focus is on integration and default security. There are processes that could be left open to abuse, that would otherwise get overlooked. One simple example is that EnGarde sets the ls command to have the least privilege, and doesn't allow write access to /bin/ls. Ubuntu, for example, allows write access to the command ls by default. If a user isn't aware of this, it could be a hole in their system that can be compromised. The point is that adding apps that provide some kind of security process doesn't by any means address the internal security of the platform and how it interacts with other processes and applications. Sure they help, but using them, and using them securely are two different things. How does the system treat passwords? What tools does it use for ordinary, "non-security" apps? How does it integrate them? Does it use best-practices for secure remote access? So on and so on... MS: What are the main differences between the free Community and the commercial Enterprise releases? GD: Our free community platform is really more of a "bleeding edge" platform. It is a great way for users to set up a secure server and incorporate new and secure functionality, but it isn't always in the kind of stable development that is demanded for a corporate environment. Also, EnGarde Professional comes with our portfolio of secure, business-critical applications - SMS (Secure Mail Suite) for routing and securing email from Spam/Virus's for tens of thousands of users - SurfSecure, our web enforcement filter for corporate networks, and so on. These applications aren't available for the community (and most of the time, they wouldn't need to be, not at that level of scalability). And lastly is the service and support for all users. All implementations of EnGarde Professional are fully supported by our dedicated staff of security specialists, with service options for Installation, Remote Monitoring, custom development and much more. MS: Who would be the Community Edition's primary users? Can I use it as a secure desktop OS? GD: The primary users for our Community Edition are really administrators interested in providing a secure server foundation. EnGarde Community (as well as EnGarde Professional) is solely engineered for server operations. This is not a desktop OS for running spreadsheets or playing music - this is about secure, usable functionality for your servers. Even though the corporate version is recommended, there have been numerous examples where EnGarde Community was implemented in a small office environment. MS: What Package management does EnGarde have? Do you maintain your own repository of software? GD: We utilize RPM and yes we do maintain our own repository. The platform is engineered from the ground up, and this means that we choose secure packages, and then integrate and develop them expressly with security in mind. MS: Thank you for your time Ryan and wish you luck for the future.   Some more articles by Mayank Sharma: Zen Gift of Education Making a Complete yet Small Linux Distribution
Read more
  • 0
  • 0
  • 1560

article-image-development-login-management-module-and-comment-management-module
Packt
24 Oct 2009
12 min read
Save for later

Development of Login Management Module and Comment Management Module

Packt
24 Oct 2009
12 min read
Lets get started right away. Developing the Login Management Module Even though Login and session handling are separate functionalities from User management, they depend on the same table—user. Also, the functionalities are more alike than different. Hence, instead of creating a new Controller, we will be using the UserController itself as the Controller for the Login module. Keeping this point in mind, let us look at the steps involved in developing the Login Management, which are: Creating the Login page Implementing the Authentication Method Setting up the Session Applying Authorization Leaving aside the first step, all other steps mainly focus on the Controller. Here we go. Creating the Login Page We need a login page with text boxes for user name and password in which users can put their credentials and submit to the login authenticator (fancy name for the action method that will contain the logic to authenticate the user). That's what we are going to create now. The convention for any website is to show the login page when the user enters the URL without any specific page in mind. RoR also follows this convention. For example, if you enter the URL as http://localhost:3000/user, it displays the list of users. The reason is that the index action method of the UserController class calls the list method whenever the aforementioned URL is used. From this, we can understand two things—first, the default action method is index, and second, the first page to be shown is changeable if we change the index method. What we need is to show the login page whenever a user enters the URLhttp://localhost:3000/user. So let's change the index method. Open theuser_controller.rb file from the app/views/user folder and remove all the statements from the body of the index method so that it looks like as follows: def indexend Next, let us create an index.rhtml file, which will be shown when the index method is called. This file will be the login page. In the app/views/user folder, create an index.rhtml file. It will be as follows <%= form_tag :action=> 'authenticate'%><table ><tr align="center" class="tablebody"><td>User name:</td><td><%= text_field("user", "user_name",:size=>"15" ) %></td></tr><tr align="center" class="tablebody"><td>Password:</td><td><%= password_field("user","password",:size=>"17" ) %></td></tr><tr align="center" class="tablebody"><td></td><td><input type="submit" value=" LOGIN " /></td></tr></table> It uses two new form helpers—text_field and password_field. The text_field creates a text field with the name passed as the parameter, and the password_field creates a password field again with the name passed as the parameter. We have passed the authenticate method as the action parameter so that the form is submitted to the authenticate method. That completes the login page creation. Next, we will work on the authenticate method. Implementing the Authenticate method Implementing the Authenticate method Authenticating a user essentially means checking whether the user name and password given by the user corresponds to the one in database or not. In our case, the user gives us the user name and password through the login page. What we will be doing is checking whether the user is in database and does the password that we got corresponds to the password stored in the database for the user? Here, we will be working on two levels: Model Controller We can put the data access part in the action method that being the Controller itself. But it will create problems in the future if we want to add something extra to the user name/password checking code. That's why we are going to put (or delegate) the data access part into Model. Model We will be modifying the User class by adding a method that will check whether the user name and password provided by the user is correct or not. The name of the method is login. It is as follows: def self.login(name,password)find(:first,:conditions => ["user_name = ? and password =?",name, password])end It is defined as a singleton method of the User class by using the self keyword. The singleton methods are special class-level methods. The conditions parameter of the find method takes an array of condition and the corresponding values. The find method generates an SQL statement from the passed parameters. Here, the find method finds the first record that matches the provided user_name and password. Now, let us create the method that the Controller will call to check the validity of the user. Let us name it check_login. The definition is as follows: def check_loginUser.login(self.user_name, self.password)end This function calls the login method. Now if you observe closely, check_login calls the login function. One more point to remember—if a method 'test' returns a value and you call 'test' from another method 'test1,' then you don't need to say 'return test' from within 'test1'.The value returned from 'test' will be returned by 'test1' implicitly. That completes the changes to be done at the Model level. Now let us see the changes at the Controller-level. Controller In the Controller for User—UserController—add a new method named authenticate. The method will first create a User object based on the user name and password. Then it will invoke check_login on the newly created User object. If check_login is successful, that is, it does not return nil, then the user is redirected to the list view of Tales. Otherwise, the user is redirected to the login page itself. Here is what the method will look like: def authenticate@user = User.new(params[:user])valid_user = @user.check_loginif logged_in_userflash[:note]="Welcome "+logged_in_user.nameredirect_to(:controller=>'tale',:action => "list")elseflash[:notice] = "Invalid User/Password"redirect_to :action=> "index"endend The redirect_to method accepts two parameters—the name of the Controller and the method within the Controller. If the user is valid, then the list method of TaleController is called, or in other words, the user is redirected to the list of tales. Next, let us make it more robust by checking for the get method. If a user directly types a URL to an action, then the get method is received by the method. If any user does that, we want him/her to be redirected to the login page. To do this, we wrap up the user validation logic in an if/else block. The code will be the following: def authenticate if request.get?render :action=> 'index'else@user = User.new(params[:user])valid_user = @user.check_loginif valid_userflash[:note]="Welcome "+valid_user.user_nameredirect_to(:controller=>'tale',:action => 'list')else flash[:notice] = "Invalid User/Password"redirect_to :action=> 'index'endendend The get? method returns true if the URL has the GET method else it returns false. That completes the login authentication part. Next, let us set up the session. In Ruby, any method that returns a Boolean value—true or false—is suffixed with a question mark (?). The get method of the request object returns a boolean value. So it is suffixed with a question mark (?). Setting up the Session Once a user is authenticated, the next step is to set up the session to track the user. Session, by definition, is the conversation between the user and the server from the moment the user logs in to the moment the user logs out. A conversation is a pair of requests by the user and the response from the server. In RoR, the session can be tracked either by using cookies or the session object. The session is an object provided by RoR. The session object can hold objects where as cookies cannot. Therefore, we will be using the session object. The session object is a hash like structure, which can hold the key and the corresponding value. Setting up a session is as easy as providing a key to the session object and assigning it a value. The following code illustrates this aspect: def authenticateif request.get?render :action=> 'index'else@user = User.new(params[:user])valid_user = @user.check_loginif valid_usersession[:user_id]=valid_user.idflash[:note]="Welcome "+valid_user.user_nameredirect_to(:controller=>'tale',:action => 'list')elseflash[:notice] = "Invalid User/Password"redirect_to :action=> 'index'endendend That completes setting up the session part. That brings us to the last step—applying authorization. Applying Authorization Until now, we have authenticated the user and set up a session for him/her. However, we still haven't ensured that only the authenticated users can access the different functionalities of TaleWiki. This is where authorization comes into the picture. Authorization has two levels—coarse grained and fine grained. Coarse grained authorization looks at the whole picture whereas the fine grained authorization looks at the individual 'pixels' of the picture. Ensuring that only the authenticated users can get into TaleWiki is a part of coarse grained authorization while checking the privileges for each functionality comes under the fine grained authorization. In this article, we will be working with the coarse grained authorization. The best place to apply the coarse grained authorization is the Controller as it is the central point of data exchange. Just like other aspects, RoR provides a functionality to easily apply any kind of logic on the Controller as a whole in the form of filters. To jog your memory, a filter contains a set of statements that need to be executed before, after (or before and after) the methods within the Controllers are executed. Our problem is to check whether the user is authenticated or not, before any method in a Controller is executed. The solution to our problem is using a 'before filter'. But we have to apply authorization to all the Controllers. Hence, the filter should be callable from any of the Controller. If you look at the definition of a Controller, you can find such a place. Each Controller is inherited from the ApplicationController. Anything placed in ApplicationController will be callable from other Controllers. In other words, any method placed in ApplicationController becomes global to all the Controllers within your application. So, we will place the method containing the filter logic in ApplicationController. To check whether a user is authentic or not, the simplest way is to check whether a session exists for that person or not. If it exists, then we can continue with the normal execution. Let us name it check_authentic_user. The implementation will be as follows: def check_authentic_userunless session[:user_id]flash[:notice] = "Please log in"redirect_to(:controller => "user", :action =>"index")endend It checks for the user_id key in a session. If it is not present, the user is redirected to the login page. Place the code in the application.rb file as a method of ApplicationController. Next, let us use it as a filter. First, we will tell UserController to apply the filter for all the action methods except index and authenticate methods. Add the following statement to the UserController. It should be the first statement after the starting of the Controller class. class UserController < ApplicationControllerbefore_filter :check_authentic_user, :except =>[ :index, :authenticate ]::end Similarly, we will place the filter in other Controllers as well. However, in their case, there are no exceptions. So TaleController will have: class TaleController < ApplicationControllerbefore_filter :check_authentic_user::end GenreController and RoleController will be the same as TaleController. Thus, we have completed the 'applying authorization' part for the time being. Now, let's tie up one loose end—the problem of adding a new tale. Tying Up the Loose Ends When we developed the User management, the Tale management was affected as the tales table has a many-to-one relationship with the users table. Now we can solve the problem created by the foreign key reference. First, open the user.rb file and add the following statement indicating that it is at the 'one' end of the relationship: has_many :tale After addition of the statement, the class will look like the following: class User < ActiveRecord::Basevalidates_presence_of :user_name, :password, :first_name,:last_name, :age, :email, :country validates_uniqueness_of :user_namevalidates_numericality_of :age validates_format_of :email, :with => /A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})Z/ibelongs_to :rolehas_many :taledef check_loginUser.login(self.name, self.password)enddef self.login(name,password)find(:first,:conditions => ["user_name = ? and password=?",name, password])endend Next, add the following statement to the tale.rb file: belongs_to :user The file will look like as follows: class Tale < ActiveRecord::Basevalidates_presence_of :title, :body_text, :sourcebelongs_to:genrebelongs_to :userend Next, open the tale_controller.rb file. In the create method, we need to add the user's id to the tale's user id reference so that the referential integrity can be satisfied. For that, we will get the current user's id from the session and set it as the value of the user_id attribute of the tale object. The create method will look like as follows, after doing the changes: def create @tale = Tale.new(params[:tale])@tale.genre_id=params[:genre]@tale.user_id=session[:user_id]@tale.status="new" if @tale.saveflash[:notice] = 'Tale was successfully created.'redirect_to :action => 'list'elserender :action => 'new'endend That's it. The 'loose ends' related to the User management are tied up. Now let us move onto the Comment Management module.
Read more
  • 0
  • 0
  • 1544

article-image-understand-and-use-microsoft-silverlight-javascript
Packt
24 Oct 2009
10 min read
Save for later

Understand and Use Microsoft Silverlight with JavaScript

Packt
24 Oct 2009
10 min read
We have come a long way from the day the WEB was created in 1992 by T.B.LEE in Switzerland. From hyper linking which was the only thing at that time, to streaming videos, instant gratification with AJAX, and a host of other do-dads that has breathed new life to JavaScript and internet usability. Silverlight among several others, is a push in this direction to satisfy the ever increasing needs of the internet users. Even so, the web application displays fall short of the rich experience one can achieve with desktop applications, and this is where the tools are being created and honed for creating RIA, short for Rich Internet Applications. In order to create such applications, a great deal of development has taken place in the Microsoft ecosystem . These are all described in the .NET and Windows Presentation Foundation which supports developers to create easily deployable Rich Internet Applications. We have to wait and see how it percolates to the Semantic Web in the future. Silverlight is a cross-platform, cross-browser plug-in that renders XAML, the declarative tag-based files while exposing the JavaScript programming interface. It makes both developers and designers to collaborate and contribute to rich and interactive designs that are well integrated with Microsoft's Expression series of programs. Initial Steps to Take In this article we will be using Silverlight 1.0 with JavaScript. Initially you need to make your browser understand the XAML, and for this you need to install Silverlight available here. There is no need for a server to work with these Silverlight application files as they will be either HTML pages, XAML pages, or JavaScript pages. Of course these files may be hosted on the server as well. The next figure shows some details you need to know before installing the plug-in. Silverlight Project Details After having enabled the browser to recognize XAML - the Extensible Application Mark up Language, you need to consider the different components that will make Silverlight happen. In the present tutorial we will look at using Silverlight 1.0. Silverlight 2.0 is still in Beta stage. If you have Silverlight already installed you may be able to verify the version in the Control Panel / Add Remove Programs and display information as shown in the next figure. To make Silverlight happen you need the following files: An HTML page that you can browse to where the Silverlight plug-in is spawned A XAML page which is all the talk is about which provides the 'Richness' Supporting script files that will create the plug-in and embeds it in the HTML page The next figure shows how these interact with one another somewhat schematically. Basically you can start with your HTML page. You need to reference two .JS files as shown in the above figure. The script file Silverlight.js exposes the properties, methods, etc. of Silverlight. This file will be available in the SDK download. You can copy this file and move it around to any location. The second script createSilvelight.js creates a plug-in which you will embed in the HTML page using yet another short script. You will see how this is created later in the tutorial. The created plug-in then brings-in the XAML page which you will create as well. The first step is to create a blank HTML page, herein called, TestSilverLight.htm as shown in the following listing: Listing 1:TestSilverLight.htm Scaffold file <html><head><script type="text/javascript" src="Silverlight.js"></script><script type="text/javascript" src="createSilverlight.js"></script><title> </title> </head> <body> Next, you go ahead and create the createSilvelight.js file. The following listing shows how this is coded. This is slightly modified although taken from a web resource. Listing 2: createSilverlight.js function createSilverlight() { Silverlight.createObject( "TestSilver.xaml", // Source property value. parentElement, // DOM reference to hosting DIV tag. "SilverlightPlugInHost1", // Unique plug-in ID value. { // Plug-in properties. width:'1024', // Width of rectangular in pixels. height:'530', // Height of rectangular in pixels. inplaceInstallPrompt:false, // install prompt if invalid version is detected. background:'white', // Background color of plug-in. isWindowless:'false', // Determines whether to display in windowless mode. framerate:'24', // MaxFrameRate property value. version:'1.0' // Silverlight version. }, { onError:null, // OnError property value onLoad:null // OnLoad property value }, null, // initParams null); // Context value } This function, createSilverlight(), when called from within a place holder location will create a Silverlight object at that location with some defined properties. You may go and look up the various customizable items in this code on the web. The object that is going to be created will be the TestSilver.xaml at the "id" of the location which will be found using the ECMA script we will see later. The "id" is also named here, found by the "parentElement". To proceed further we need to create (a) the TestSilver.xaml file and (b) create a place holder in the HTML page. At first the changes made to Listing 1 are shown in bold. This is the place holder <div> </div> tags inside the 'body' tags as shown in the next listing with the "id" used in the createSilverlight.js file. You may also use <span> </span> tags, provided you associate a "id" with it. Listing 3: Place holder created in the HTML Page <head><script type="text/javascript" src="Silverlight.js"></script><script type="text/javascript" src="createSilverlight.js"></script><title> </title> </head> <body><div id="SilverlightPlugInHost1"> </div></body> </html> Creating the XAML File If you have neither used XAML, nor created a XAML page you should access the internet where you will find tons of this stuff. A good location is MSDN's Silvelight home page. You may also want to read up this article which will give some idea about XAML. Although this article is focusing on 'Windows' and not 'Web', the idea of what XAML is the same. The next listing describes the declarative syntax that will show a 'canvas', a defined space on your web page in which an image has been brought in. The 'Canvas' is the container and the image is the contained object. A XAML file should be well formed similar to an XML file. Listing 4: A Simple XAML file <Canvas Width="200" Height="200" Background="powderblue"><Image Canvas.Left="50" Canvas.Top="50" Width="200"Source="Fish.JPG"/></Canvas> Save the above file (text) with the extension XAML. If your Silverlight 1.0 is working correctly you should see this displayed on the browser when you browse to it. You also note the [.] notation to access the properties of the Canvas. For example, Canvas.Left is 50 pixels relative to the Canvas. The namespace is very important, more about it later. Without going into too much details, the pale blue area is the canvas whose width and height are 200 pixels each. The fish image is off set by the amounts shown relative to the canvas. Canvas is the portion of the browser window which functions as a place holder. While you use "Canvas" in web, you will have "Window" for desktop applications. The namespace of the canvas should be as shown otherwise you may get errors of various types depending on the typos. Inside the canvas you may place any type of object, buttons, textboxes, shapes, and even other canvases. If and when you design using the Visual Studio designer with intellisense guiding you along you will see a bewildering array of controls, styles, etc. The details of the various XAML tags are outside the scope of this tutorial. Although Notepad is used in this tutorial, you really should use a designer as you cannot possibly remember correctly the various Properties, Methods and Events supported. In some web references you may notice one more additional namespace . Remove this namespace reference as "Canvas" does not exist in this namespace. If you use it, you will get an XamlParseException. Also if you are of the cut and paste type make sure you save the XAML file as of type "All files" with XAML extension. With the above brief background review the TestSilver.xaml file whose listing is shown in the next paragraph. Listing 5: TestSilver.xaml file referenced in Plug-in script <Canvas Width="200" Height="150" Background="powderblue"> <Canvas Width="150" Height="250" Background="PaleGoldenRod"> <Ellipse Width="100" Height="100" Stroke="Black" StrokeThickness="2" Fill="Green" /> </Canvas><Image Canvas.Left="50" Canvas.Top="50" Width="200" Source="http://localhost/IMG_0086.JPG"/></Canvas> In the above code you see a second canvas embedded inside the first with its own independent window. The order they would appear will depend on where they are in the code unless the default order is changed. You also see that the image is now referenced to a graphic file on the local server. Later on you will see the Silverlight.htm hosted on the server. If you are using more recent versions of ASP.NET used on your site, or version of IE you may get to see the complete file and some times you may get to see only part of the XMAL content and additional error message such as this one. For example, while the image in the project folder is displayed, the image on the local server may be skipped. If the setting and versions are optimum, you will get to see this displayed on your browser when you browse to the above file. Script in HTML to Embed Silverlight Plug-in This really is the last piece left to be taken care of to complete this project. The code shown in the next listing shows how this is done. The code segment shown in bold is the script that is added to the place holder we created earlier. Listing 6: Script added to bring Plug-in <html><head><script type="text/javascript" src="Silverlight.js"></script><script type="text/javascript" src="createSilverlight.js"></script><title> </title> </head> <body><div id="SilverlightPlugInHost1"> <script type="text/javascript"> var parentElement = document.getElementById("SilverlightPluginHost1"); createSilverlight();</script></div></body> </html> Hosted Files on the IIS The various files used are then saved to a folder and can be set up as the target of a virtual directory on your IIS as shown. Now you can browse the Silverlight123.htm file on your browser to see the following displayed on your IE. Summary The present tutorial shows how to create a Silverlight project describing the various files used and how they interact with each other. The importance of using the correct namespace and some tips on creating the XAML files as well as hosting them on IIS are also described. A Windows XP with SP2 was used and the Silverlight.htm file tested on IIS 5.1; IE Ver 7.0.5370IC and web site enabled for ASP.NET Version 2.0.50727 with the registered MimeType application/xaml+xml.
Read more
  • 0
  • 0
  • 5305

article-image-manipulating-jquery-tables
Packt
24 Oct 2009
20 min read
Save for later

Manipulating jQuery tables

Packt
24 Oct 2009
20 min read
In this article by Karl Swedberg and Jonathan Chaffer, we will use an online bookstore as our model website, but the techniques we cook up can be applied to a wide variety of other sites as well, from weblogs to portfolios, from market-facing business sites to corporate intranets. In this article, we will use jQuery to apply techniques for increasing the readability, usability, and visual appeal of tables, though we are not dealing with tables used for layout and design. In fact, as the web standards movement has become more pervasive in the last few years, table-based layout has increasingly been abandoned in favor of CSS‑based designs. Although tables were often employed as a somewhat necessary stopgap measure in the 1990s to create multi-column and other complex layouts, they were never intended to be used in that way, whereas CSS is a technology expressly created for presentation. But this is not the place for an extended discussion on the proper role of tables. Suffice it to say that in this article we will explore ways to display and interact with tables used as semantically marked up containers of tabular data. For a closer look at applying semantic, accessible HTML to tables, a good place to start is Roger Johansson's blog entry, Bring on the Tables at www.456bereastreet.com/archive/200410/bring_on_the_tables/. Some of the techniques we apply to tables in this article can be found in plug‑ins such as Christian Bach's Table Sorter. For more information, visit the jQuery Plug‑in Repository at http://jQuery.com/plugins. Sorting One of the most common tasks performed with tabular data is sorting. In a large table, being able to rearrange the information that we're looking for is invaluable. Unfortunately, this helpful operation is one of the trickiest to put into action. We can achieve the goal of sorting in two ways, namely Server-Side Sorting and JavaScript Sorting. Server-Side Sorting A common solution for data sorting is to perform it on the server side. Data in tables often comes from a database, which means that the code that pulls it out of the database can request it in a given sort order (using, for example, the SQL language's ORDER BY clause). If we have server-side code at our disposal, it is straightforward to begin with a reasonable default sort order. Sorting is most useful when the user can determine the sort order. A common idiom is to make the headers of sortable columns into links. These links can go to the current page, but with a query string appended indicating the column to sort by: <table id="my-data">   <tr>     <th class="name"><a href="index.php?sort=name">Name</a></th>     <th class="date"><a href="index.php?sort=date">Date</a></th>   </tr>   ... </table> The server can react to the query string parameter by returning the database contents in a different order. Preventing Page Refreshes This setup is simple, but requires a page refresh for each sort operation. As we have seen, jQuery allows us to eliminate such page refreshes by using AJAX methods. If we have the column headers set up as links as before, we can add jQuery code to change those links into AJAX requests: $(document).ready(function() {   $('#my-data .name a').click(function() {     $('#my-data').load('index.php?sort=name&type=ajax');     return false;   });   $('#my-data .date a').click(function() {     $('#my-data').load('index.php?sort=date&type=ajax');     return false;   }); }); Now when the anchors are clicked, jQuery sends an AJAX request to the server for the same page. We add an additional parameter to the query string so that the server can determine that an AJAX request is being made. The server code can be written to send back only the table itself, and not the surrounding page, when this parameter is present. This way we can take the response and insert it in place of the table. This is an example of progressiveenhancement. The page works perfectly well without any JavaScript at all, as the links for server-side sorting are still present. When JavaScript is present, however, the AJAX hijacks the page request and allows the sort to occur without a full page load. JavaScript Sorting There are times, though, when we either don't want to wait for server responses when sorting, or don't have a server-side scripting language available to us. A viable alternative in this case is to perform the sorting entirely on the browser using JavaScript client-side scripting. For example, suppose we have a table listing books, along with their authors, release dates, and prices: <table class="sortable">   <thead>     <tr>       <th></th>       <th>Title</th>       <th>Author(s)</th>       <th>Publish&nbsp;Date</th>       <th>Price</th>     </tr>   </thead>   <tbody>     <tr>       <td>         <img src="../covers/small/1847192386.png" width="49"              height="61" alt="Building Websites with                                                 Joomla! 1.5 Beta 1" />       </td>       <td>Building Websites with Joomla! 1.5 Beta 1</td>       <td>Hagen Graf</td>       <td>Feb 2007</td>       <td>$40.49</td>     </tr>     <tr>       <td><img src="../covers/small/1904811620.png" width="49"                height="61" alt="Learning Mambo: A Step-by-Step                Tutorial to Building Your Website" /></td>       <td>Learning Mambo: A Step-by-Step Tutorial to Building Your           Website</td>       <td>Douglas Paterson</td>       <td>Dec 2006</td>       <td>$40.49</td>     </tr>     ...   </tbody> </table> We'd like to turn the table headers into buttons that sort by their respective columns. Let us look into ways of doing this.   Row Grouping Tags Note our use of the <thead> and <tbody> tags to segment the data into row groupings. Many HTML authors omit these implied tags, but they can prove useful in supplying us with more convenient CSS selectors to use. For example, suppose we wish to apply typical even/odd row striping to this table, but only to the body of the table: $(document).ready(function() {   $('table.sortable tbody tr:odd').addClass('odd');   $('table.sortable tbody tr:even').addClass('even'); }); This will add alternating colors to the table, but leave the header untouched: Basic Alphabetical Sorting Now let's perform a sort on the Titlecolumn of the table. We'll need a class on the table header cell so that we can select it properly: <thead>   <tr>     <th></th>    <th class="sort-alpha">Title</th>     <th>Author(s)</th>     <th>Publish&nbsp;Date</th>     <th>Price</th>   </tr> </thead> To perform the actual sort, we can use JavaScript's built in .sort()method. It does an in‑place sort on an array, and can take a function as an argument. This function compares two items in the array and should return a positive or negative number depending on the result. Our initial sort routine looks like this: $(document).ready(function() {   $('table.sortable').each(function() {     var $table = $(this);     $('th', $table).each(function(column) {       if ($(this).is('.sort-alpha')) {         $(this).addClass('clickable').hover(function() {           $(this).addClass('hover');         }, function() {           $(this).removeClass('hover');         }).click(function() {           var rows = $table.find('tbody > tr').get();           rows.sort(function(a, b) {             var keyA = $(a).children('td').eq(column).text()                                                       .toUpperCase();             var keyB = $(b).children('td').eq(column).text()                                                       .toUpperCase();             if (keyA < keyB) return -1;             if (keyA > keyB) return 1;             return 0;           });           $.each(rows, function(index, row) {             $table.children('tbody').append(row);           });         });       }     });   }); }); The first thing to note is our use of the .each() method to make iteration explicit. Even though we could bind a click handler to all headers with the sort-alpha class just by calling $('table.sortable th.sort-alpha').click(), this wouldn't allow us to easily capture a crucial bit of information—the column index of the clicked header. Because .each() passes the iteration index into its callback function, we can use it to find the relevant cell in each row of the data later. Once we have found the header cell, we retrieve an array of all of the data rows. This is a great example of how .get()is useful in transforming a jQuery object into an array of DOM nodes; even though jQuery objects act like arrays in many respects, they don't have any of the native array methods available, such as .sort(). With .sort() at our disposal, the rest is fairly straightforward. The rows are sorted by comparing the textual contexts of the relevant table cell. We know which cell to look at because we captured the column index in the enclosing .each() call. We convert the text to uppercase because string comparisons in JavaScript are case-sensitive and we wish our sort to be case-insensitive. Finally, with the array sorted, we loop through the rows and reinsert them into the table. Since .append() does not clone nodes, this moves them rather than copying them. Our table is now sorted. This is an example of progressive enhancement's counterpart, gracefuldegradation. Unlike with the AJAX solution discussed earlier, we cannot make the sort work without JavaScript, as we are assuming the server has no scripting language available to it in this case. The JavaScript is required for the sort to work, so by adding the "clickable" class only through code, we make sure not to indicate with the interface that sorting is even possible unless the script can run. The page degrades into one that is still functional, albeit without sorting available. We have moved the actual rows around, hence our alternating row colors are now out of whack: We need to reapply the row colors after the sort is performed. We can do this by pulling the coloring code out into a function that we call when needed: $(document).ready(function() {   var alternateRowColors = function($table) {     $('tbody tr:odd', $table).removeClass('even').addClass('odd');     $('tbody tr:even', $table).removeClass('odd').addClass('even');   };     $('table.sortable').each(function() {     var $table = $(this);     alternateRowColors($table);     $('th', $table).each(function(column) {       if ($(this).is('.sort-alpha')) {         $(this).addClass('clickable').hover(function() {           $(this).addClass('hover');         }, function() {           $(this).removeClass('hover');         }).click(function() {           var rows = $table.find('tbody > tr').get();           rows.sort(function(a, b) {             var keyA = $(a).children('td').eq(column).text()                                                       .toUpperCase();             var keyB = $(b).children('td').eq(column).text()                                                       .toUpperCase();             if (keyA < keyB) return -1;             if (keyA > keyB) return 1;             return 0;           });           $.each(rows, function(index, row) {             $table.children('tbody').append(row);           });           alternateRowColors($table);         });       }     });   }); }); This corrects the row coloring after the fact, fixing our issue:   The Power of Plug-ins The alternateRowColors()function that we wrote is a perfect candidate to become a jQuery plug-in. In fact, any operation that we wish to apply to a set of DOM elements can easily be expressed as a plug-in. In this case, we only need to modify our existing function a little bit: jQuery.fn.alternateRowColors = function() {   $('tbody tr:odd', this).removeClass('even').addClass('odd');   $('tbody tr:even', this).removeClass('odd').addClass('even');   return this; }; We have made three important changes to the function. It is defined as a new property of jQuery.fn rather than as a standalone function. This registers the function as a plug-in method. We use the keyword this as a replacement for our $table parameter. Within a plug-in method, thisrefers to the jQuery object that is being acted upon. Finally, we return this at the end of the function. The return value makes our new method chainable. More information on writing jQuery plug-ins can be found in Chapter 10 of our book Learning jQuery. There we will discuss making a plug-in ready for public consumption, as opposed to the small example here that is only to be used by our own code. With our new plug-in defined, we can call $table.alternateRowColors(), which is a more natural jQuery syntax, intead of alternateRowColors($table). Performance Concerns Our code works, but is quite slow. The culprit is the comparator function, which is performing a fair amount of work. This comparator will be called many times during the course of a sort, which means that every extra moment it spends on processing will be magnified. The actual sort algorithm used by JavaScript is not defined by the standard. It may be a simple sort like a bubble sort (worst case of Θ(n2) in computational complexity terms) or a more sophisticated approach like quick sort (which is Θ(n log n) on average). In either case doubling the number of items increases the number of times the comparator function is called by more than double. The remedy for our slow comparator is to pre-compute the keys for the comparison. We begin with the slow sort function: rows.sort(function(a, b) {   keyA = $(a).children('td').eq(column).text().toUpperCase();   keyB = $(b).children('td').eq(column).text().toUpperCase();   if (keyA < keyB) return -1;   if (keyA > keyB) return 1;   return 0; }); $.each(rows, function(index, row) {   $table.children('tbody').append(row); }); We can pull out the key computation and do that in a separate loop: $.each(rows, function(index, row) {   row.sortKey = $(row).children('td').eq(column).text().toUpperCase(); }); rows.sort(function(a, b) {   if (a.sortKey < b.sortKey) return -1;   if (a.sortKey > b.sortKey) return 1;   return 0; }); $.each(rows, function(index, row) {   $table.children('tbody').append(row);   row.sortKey = null; }); In the new loop, we are doing all of the expensive work and storing the result in a new property. This kind of property, attached to a DOM element but not a normal DOM attribute, is called an expando.This is a convenient place to store the key since we need one per table row element. Now we can examine this attribute within the comparator function, and our sort is markedly faster.  We set the expando property to null after we're done with it to clean up after ourselves. This is not necessary in this case, but is a good habit to establish because expando properties left lying around can be the cause of memory leaks. For more information, see Appendix C.   Finessing the Sort Keys Now we want to apply the same kind of sorting behavior to the Author(s) column of our table. By adding the sort-alpha class to its table header cell, the Author(s)column can be sorted with our existing code. But ideally authors should be sorted by last name, not first. Since some books have multiple authors, and some authors have middle names or initials listed, we need outside guidance to determine what part of the text to use as our sort key. We can supply this guidance by wrapping the relevant part of the cell in a tag: <tr>   <td>     <img src="../covers/small/1847192386.png" width="49" height="61"             alt="Building Websites with Joomla! 1.5 Beta 1" /></td>   <td>Building Websites with Joomla! 1.5 Beta 1</td>   <td>Hagen <span class="sort-key">Graf</span></td>   <td>Feb 2007</td>   <td>$40.49</td> </tr> <tr>   <td>     <img src="../covers/small/1904811620.png" width="49" height="61"          alt="Learning Mambo: A Step-by-Step Tutorial to Building                                                 Your Website" /></td>   <td>     Learning Mambo: A Step-by-Step Tutorial to Building Your Website   </td>   <td>Douglas <span class="sort-key">Paterson</span></td>   <td>Dec 2006</td>   <td>$40.49</td> </tr> <tr>   <td>     <img src="../covers/small/1904811299.png" width="49" height="61"                   alt="Moodle E-Learning Course Development" /></td>   <td>Moodle E-Learning Course Development</td>   <td>William <span class="sort-key">Rice</span></td>   <td>May 2006</td>   <td>$35.99</td> </tr> Now we have to modify our sorting code to take this tag into account, without disturbing the existing behavior for the Titlecolumn, which is working well. By prepending the marked sort key to the key we have previously calculated, we can sort first on the last name if it is called out, but on the whole string as a fallback: $.each(rows, function(index, row) {   var $cell = $(row).children('td').eq(column);   row.sortKey = $cell.find('.sort-key').text().toUpperCase()                                   + ' ' + $cell.text().toUpperCase(); }); Sorting by the Author(s)column now uses the last name:     If two last names are identical, the sort uses the entire string as a tiebreaker for positioning.
Read more
  • 0
  • 0
  • 19215

article-image-installation-and-basic-features-enterprisedb
Packt
24 Oct 2009
3 min read
Save for later

Installation and basic features of EnterpriseDB

Packt
24 Oct 2009
3 min read
Installing the EnterpriseDB Download PostgrePlus Advanced Server 8.3 ( pgplus-advsvr-windows-83012b.exe (120MB) ) from the following site: http://www.enterprisedb.com/products/download.do. After downloading the program double click the executable file. You may need to choose a language from a list of languages. Here English has been chosen. The welcome window gets displayed as shown. Click Next. Choose the option you need. Read notes on this page to make the choice. Here, the Oracle compatibility has been chosen. Click Next or, choose a different location by browsing. Here the default location is accepted. Click Next. The window that shows up displays all the various features that are available. Pick and choose the features. Here all features are chosen. Click Next. The next window shows the links from where the JDBC drivers for connecting to Oracle and MySQL are available displayed. Click Next . In the window that shows up you need to choose the password for the Operating System UserID and Password. Read the cautionary remarks on this page. Choose Next. At this point your anti-virus program may require you to permit to run the program. McAfee is the anti-virus program on this computer. In the window that gets displayed you may need to choose the administrator's log in credentials. You may also Browse and select the Data Destination Directory. Herein the default is accepted. Click Next. In the windows that gets displayed you may choose the type of environment for which the server will be used as well as the work load for which you may be using the server. The dynamic tuning options available are: Server Utilization Development: This is a development machine and many other applications will be running on it. Stress testing should not be performed with this configuration. EnterpriseDB will use a minimal amount of memory. Mixed: Several applications will be running on this machine. Choose this option for web/application servers. Dedicated: This machine is dedicated to run EnterpriseDB and will use available memory to optimize performance. The Workload Profile Transaction Processing: The running application is a transaction intensive applications. General Purpose: The database will be used for transaction processing as well as complex queries and reporting. Reporting: The database will be used for reporting applications. For this tutorial, the Mixed option for Server Utilization and General Purpose for Workload Profile were chosen. Click on Next. The Summary page gets displayed showing all the options chosen. Click on the Install button. The window with a progress bar gets displayed. You may get a warning from the anti-virus program on your computer to allow the file to be executed. Click OK to allow install.
Read more
  • 0
  • 0
  • 2302

article-image-dynamic-theming-drupal-6-part-2
Packt
24 Oct 2009
8 min read
Save for later

Dynamic Theming in Drupal 6 - Part 2

Packt
24 Oct 2009
8 min read
Creating Dynamic CSS Styling In addition to creating dynamic templates, the Drupal system also enables you to apply CSS dynamically. Drupal creates unique identifiers for various elements of the system and you can use those identifiers to create specific CSS selectors. As a result, you can provide styling that responds to the presence (or absence) of specific conditions on any given page. Two of the most common uses of this technique are covered below: The creation of node-specific styles and the use of $body_classes. Using Dynamic Selectors for Nodes The system generates a unique ID for each node on the website. We can use that unique ID to activate a unique selector by applying this nomenclature for the selector: #node-[nid] {} For example, assume you wish to add a border to the node with the ID of 2. Simply create a new div in style.css with the name: #node-2 {border: 1px solid #336600} Changing the Body Class Based on body_classes One of the most useful dynamic styling tools introduced in Drupal 6 is the implementation of $body_classes. This variable is intended specifically as an aid to dynamic CSS styling. It allows for the easy creation of CSS selectors that are responsive to the layout of the page. This technique is typically used to control the styling where there may be one, two or three columns displayed, depending on the page and the content. Prior to Drupal 6, $layout was used to detect the page layout, that is, one, two or three columns. While $layout can technically still be used, the better practice is to use $body_classes. Implementing $body_classes is a simple matter; just add $body_classes to the body tag of your page.tpl.php file—the Drupal system will do the rest. Once the body tag is altered to include this variable, the class associated with the body tag will change automatically in response to the conditions on the page at that time. Now, all you have to do is create the CSS selectors that you wish to see applied in the various situations. Let's step through this with a quick example. Open up your page.tpl.php file and modify the body tag as follows: <body class="<?php print $body_classes; ?>"> This will now automatically create a class for the page based on the conditions on the page. The chart below shows the options this presents: Condition Class Available no sidebars .no-sidebar one sidebar .one-sidebar left sidebar visible .sidebar-left right sidebar visible .sidebar-right two sidebars .two-sidebars front page .front not front page .not-front logged in .logged-in not logged in .not-logged-in page visible .page-[page type               node visible .node-type-[name of type]       $body_classes provides the key to easily creating a theme that includes collapsible sidebars. To set up this functionality, modify the page.tpl.php file to include $body_classes. Now, go to the style.css file and create the following selectors: .one-sidebar {}.sidebar-left {}.sidebar-right {}.no-sidebar {}.two-sidebars {} The final step is to create the styling for each of the selectors above (as you see fit). When the site is viewed, the system-generated value of $body_classes will determine which selector is applied. You can now specify, through the selectors above, exactly how the page appears—whether the columns collapse, the resulting widths of the remaining columns, and so on , and so on. Working with Template Variables As we have seen, above, Drupal produces variables that can be used to enhance the functionality of themes. Typically, a theme-related function returns values reflecting the state of the page on the screen. A function may indicate, for example, whether the page is the front page of the site, or whether there are one, two, or three active columns (for example, the variable $body_classes). Tapping into this information is a convenient way for a theme developer to style a site dynamically. The default Drupal variables cover the most common (and essential) functions, including creating unique identifiers for items. Some of the Drupal variables are unique to particular templates; others are common to all. In addition to the default variables, you can also define your own variables. Using the function theme_preprocess(), you can either set new variables, or unset existing ones that you do not want to use. In Drupal 6, preprocess functions have made working with variables easier and cleaner. By using the preprocessor, you can set up variables within your theme that can be accessed by any of your templates. The code for the preprocess function is added to your template.php file, thereby keeping the actual template files (the .tpl.php files) free of unnecessary clutter. Note that the preprocess functions only apply to theming hooks implemented as templates; plain theme functions do not interact with the preprocessors. In Drupal 5 and below, the function _phptemplate_variables served the same purpose as the preprocess function. For a list of the expected preprocess functions and their order of precedence, see http://drupal.org/node/223430 Typically, if you wish to implement a preprocessor applicable to your theme, you will use one of the following:   Name of preprocessor Application [engineName]_preprocess This namespace should be used for your base theme. Should be named after the theme engine used by the theme. Will apply to all hooks. [engineName]_preprocess_ [hookname] Should be used for your base theme. Also named after the theme engine applicable to the theme but note that it is specific to a single hook. [themeName]_preprocess This namespace should be used for subthemes. Will apply to all hooks. [themeName]_preprocess_ [hookname] Should be used for subthemes. Note that it is specific to a single hook. Let's look first at intercepting and overriding the default variables and then at creating your own variables. Intercepting and Overriding Variables You can intercept and override the system's existing variables. Intercepting a variable is no different in practice from intercepting a themable function: you simply restate it in the template.php file and make your modifications there, leaving the original code in the core intact. To intercept an existing variable and override it with your new variable, you need to use the function _phptemplate_preprocess(). Add this to your template.php file according to the following syntax: <?phpfunction phptemplate_preprocess(&$vars) {$vars['name'] = add your code here...;}?> Note that nothing should be returned from these functions. The variables have to be passed by reference, as indicated by the ampersand before variables, e.g., &$vars. Let's take a very basic example and apply this. Let's override $title inpage.tpl.php. To accomplish this task, add the following code to the template.php file: <?php function phptemplate_preprocess(&$vars) { $vars['title'] = 'override title';}?> Remember to clear your theme registry! With this change made and the file saved to your theme, the string override title will appear, substituted for the original $title value. Making New Variables Available The preprocess function also allows you to define additional variables in your theme. To create a new variable, you must declare the function in the template.php file. In order for your theme to have its preprocessors recognized, the template associated with the hook must exist inside the theme. If the template does not exist in your theme, copy one and place it in the theme directory. The syntax is the same as that just used for intercepting and overriding a variable, as seen above. The ability to add new variables to the system is a powerful tool and gives you the ability to add more complex logic to your theme. Summary In this two part article we covered the basics needed to make your Drupal theme responsive to the contents and the users. By applying the techniques discussed here, you can control the theming of pages based on content, state of the page or the users viewing them. Taking the principles one step further, you can also make the theming of elements within a page conditional. The ability to control the templates used and the styling of the page and its elements is what we call dynamic theming. We covered not only the basic ideas behind dynamic theming, but also the techniques needed to implement this powerful tool. Among the items discussed at length were the use of suggestions to control template display, and the implementation of $body_classes. Also covered in this article, was the use of the preprocess function to work with variables inside your theme
Read more
  • 0
  • 0
  • 1770
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-rss-web-widget
Packt
24 Oct 2009
8 min read
Save for later

RSS Web Widget

Packt
24 Oct 2009
8 min read
What is an RSS Feed? First of all, let us understand what a web feed is. Basically, it is a data format that provides frequently updated content to users. Content distributors syndicate the web feed, allowing users to subscribe, by using feed aggregator. RSS feeds contain data in an XML format. RSS is the term used for describing Really Simple Syndication, RDF Site Summary, or Rich Site Summary, depending upon the different versions. RDF (Resource Description Framework), a family of W3C specification, is a data model format for modelling various information such as title, author, modified date, content etc through variety of syntax format. RDF is basically designed to be read by computers for exchanging information. Since, RSS is an XML format for data representation, different authorities defined different formats of RSS across different versions like 0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0. The following table shows when and by whom were the different RSS versions proposed. RSS Version Year Developer's Name RSS 0.90 1999 Netscape introduced RSS 0.90. RSS 0.91 1999 Netscape proposed the simpler format of RSS 0.91. 1999 UserLand Software proposed the RSS specification. RSS 1.0 2000 O'Reilly released RSS 1.0. RSS 2.0 2000 UserLand Software proposed the further RSS specification in this version and it is the most popular RSS format being used these days. Meanwhile, Harvard Law school is responsible for the further development of the RSS specification. There had been a competition like scenario for developing the different versions of RSS between UserLand, Netscape and O'Reilly before the official RSS 2.0 specification was released. For a detailed history of these different versions of RSS you can check http://www.rss-specifications.com/history-rss.htm The current version RSS is 2.0 and it is the common format for publishing RSS feeds these days. Like RSS, there is another format that uses the XML language for publishing web feeds. It is known as ATOM feed, and is most commonly used in Wiki and blogging software. Please refer to http://en.wikipedia.org/wiki/ATOM for detail. The following is the RSS icon that denotes links with RSS feeds. If you're using Mozilla's Firefox web browser then you're likely to see the above image in the address bar of the browser for subscribing to an RSS feed link available in any given page. Web browsers like Firefox and Safari discover available RSS feeds in web pages by looking at the Internet media type application/rss+xml. The following tag specifies that this web page is linked with the RSS feed URL: http://www.example.com/rss.xml<link href="http://www.example.com/rss.xml" rel="alternate" type="application/rss+xml" title="Sitewide RSS Feed" /> Example of RSS 2.0 format First of all, let’s look at a simple example of the RSS format. <?xml version="1.0" encoding="UTF-8" ?><rss version="2.0"><channel> <title>Title of the feed</title> <link>http://www.examples.com</link> <description>Description of feed</description> <item> <title>News1 heading</title> <link>http://www.example.com/news-1</link> <description>detail of news1 </description> </item> <item> <title>News2 heading</title> <link>http://www.example.com/news-2</link> <description>detail of news2 </description> </item></channel></rss> The first line is the XML declaration that indicates its version is 1.0. The character encoding is UTF-8. UTF-8 characters support many European and Asian characters so it is widely used as character encoding in web. The next line is the rss declaration, which declares that it is a RSS document of version 2.0 The next line contains the <channel> element which is used for describing the detail of the RSS feed. The <channel> element must have three required elements <title>, <link> and <description>. The title tag contains the title of that particular feed. Similarly, the link element contains the hyperlink of the channel and the description tag describes or carries the main information of the channel. This tag usually contains the information in detail. Furthermore, each <channel> element may have one or more <item> elements which contain the story of the feed. Each <item> element must have the three elements <title>, <link> and <description> whose use is similar to those of channel elements, but they describe the details of each individual items. Finally, the last two lines are the closing tags for the <channel> and <rss> elements. Creating RSS Web Widget The RSS widget we're going to build is a simple one which displays the headlines from the RSS feed, along with the title of the RSS feed. This is another widget which uses some JavaScript, PHP CSS and HTML. The content of the widget is displayed within an Iframe so when you set up the widget, you've to adjust the height and width. To parse the RSS feed in XML format, I've used the popular PHP RSS Parser – Magpie RSS. The homepage of Magpie RSS is located at http://magpierss.sourceforge.net/. Introduction to Magpie RSS Before writing the code, let's understand what the benefits of using the Magpie framework are, and how it works. It is easy to use. While other RSS parsers are normally limited for parsing certain RSS versions, this parser parses most RSS formats i.e. RSS 0.90 to 2.0, as well as ATOM feed. Magpie RSS supports Integrated Object Cache which means that the second request to parse the same RSS feed is fast— it will be fetched from the cache. Now, let's quickly understand how Magpie RSS is used to parse the RSS feed. I'm going to pick the example from their homepage for demonstration. require_once 'rss_fetch.inc';$url = 'http://www.getacoder.com/rss.xml';$rss = fetch_rss($url);echo "Site: ", $rss->channel['title'], "<br>";foreach ($rss->items as $item ) { $title = $item[title]; $url = $item[link]; echo "<a href=$url>$title</a></li><br>";} If you're more interested in trying other PHP RSS parsers then you might like to check out SimplePie RSS Parser (http://simplepie.org/) and LastRSS (http://lastrss.oslab.net/). You can see in the first line how the rss_fetch.inc file is included in the working file. After that, the URL of the RSS feed from getacoder.com is assigned to the $url variable. The fetch_rss() function of Magpie is used for fetching data and converting this data into RSS Objects. In the next line, the title of RSS feed is displayed using the code $rss->channel['title']. The other lines are used for displaying each of the RSS feed's items. Each feed item is stored within an $rss->items array, and the foreach() loop is used to loop through each element of the array. Writing Code for our RSS Widget As I've already discussed, this widget is going to use Iframe for displaying the content of the widget, so let's look at the JavaScript code for embedding Iframe within the HTML code. var widget_string = '<iframe src="http://www.yourserver.com/rsswidget/rss_parse_handler.php?rss_url=';widget_string += encodeURIComponent(rss_widget_url);widget_string += '&maxlinks='+rss_widget_max_links;widget_string += '" height="'+rss_widget_height+'" width="'+rss_widget_width+'"';widget_string += ' style="border:1px solid #FF0000;"';widget_string +=' scrolling="no" frameborder="0"></iframe>';document.write(widget_string); In the above code, the widget string variable contains the string for displaying the widget. The source of Iframe is assigned to rss_parse_handler.php. The URL of the RSS feed, and the headlines from the feed are passed to rss_parse_handler.php via the GET method, using rss_url and maxlinks parameters respectively. The values to these parameters are assigned from the Javascript variables rss_widget_url and rss_widget_max_links. The width and height of the Iframe are also assigned from JavaScript variables, namely rss_widget_width and rss_widget_height. The red border on the widget is displayed by assigning 1px solid #FF0000 to the border attribute using the inline styling of CSS. Since, Inline CSS is used, the frameborder property is set to 0 (i.e. the border of the frame is zero). Displaying borders from the CSS has some benefit over employing the frameborder property. While using CSS code, 1px dashed #FF0000 (border-width border-style border-color) means you can display a dashed border (you can't using frameborder), and you can use the border-right, border-left, border-top, border-bottom attributes of CSS to display borders at specified positions of the object. The scrolling property is set to no here, which means that the scroll bar will not be displayed in the widget if the widget content overflows. If you want to show a scroll bar, then you can set this property to yes. The values of JavaScript variables like rss_widget_url, rss_widget_max_links etc come from the page where we'll be using this widget. You'll see how the values of these variables will be assigned from the section at the end where we'll look at how to use this RSS widget.  
Read more
  • 0
  • 0
  • 4517

article-image-gobolinux-interview-lucas-villa-real
Packt
24 Oct 2009
6 min read
Save for later

GoboLinux: An Interview with Lucas Villa Real

Packt
24 Oct 2009
6 min read
GoboLinux is popular for its filesystem hierarchy which breaks away from the traditional Unix Filesystem Hierarchy Standard (FHS). So basically you wouldn't find any /etc or /usr directries under Gobo. In turn, files of a particular program are stored in their own separate directories like /Programs/GCC/2.95.3/lib. This means Gobo's package management system has its advantages since users can now install multiple versions of the same program without conflicts. To find out more about Gobo and why it does things the way it does, I talk to one of its main developers Lucas Villa Real. Mayank Sharma: So why did you break away from the traditional FHS? Are there any particular advantages? Lucas Villa Real: The major aim was to have a simple way of creating and sharing binary packages from programs compiled and installed from their source code. Splitting the filesystem tree into per-program subtrees was the most logical thinking, as packages could be created just by compressing its directory, or removed by deleting that. Another interesting advantage is that more than one version of the same program can be installed in the system at a given time, as each version lives inside its own directory. And this gives us a very unique feature: no database is needed to tell which packages are installed and what files each of them offer; that's just a matter of checking the directory contents inside /Programs. MS: How do you maintain UNIX compatibility in the background? Doesn't this effect the speed of complex programs like OpenOffice.org? LVR: Every time a new application is installed in GoboLinux, its contents are linked inside a global /System/Links tree. This tree presents subdirs such as Executables, Libraries, Headers and Shared, among others. So, having a centralized point where programs' contents can be reached makes it possible to achieve UNIX compatibility by presenting symlinks that point the desired legacy entry to the /System/Links corresponding one. And this comes with a great advantage: by having entries such as /bin, /sbin, /usr/bin and /usr/sbin pointing to /System/Links/Executables, the applications will always find what they're looking for—given that the file exists. This extra level of indirection introduced by the symlinks require one more step when opening or getting information on files, but that's a really cheap and fast procedure, especially when compared to the entire file manipulation operations. And anyways that already happens in traditional systems when an application tries to open a shared library, which is usually presented as a symlink to the real shared object. It's interesting to note that although we have those compatibility symlinks they're all hidden from the end user by default, thanks to a kernel extension written by us. MS: I've read Gobo's filesystem makes installing applications easier. But wouldn't this require application developers to package their apps to conform with Gobo's filesystem? LVR: Many application developers are already doing that by using autoconf, automake or just by writing well behaved Makefiles. In fact GoboLinux doesn't require anything special from application developers other than the usual care that they should already take regarding portability in their projects. MS: How does Gobo's "design" let users install multiple versions of the same app? How about uninstallation? LVR: Every installed program gets its own directory, such as /Programs/GCC/4.2.1. That avoids conflicts  with files coming from different versions, as they'll be stored in a different location (eg: /Programs/GCC/4.1.1). For uninstallation, it's just as simple as removing the desired program or version from the /Programs tree. The broken symlinks that'll be left over can be either treated automatically by a daemon such as the GoboLinux Listener or manually by a script shipped with the distribution. MS: So why haven't other distros taken to Gobo's filesystem? Is it difficult to implement from the distro developer's point of view? LVR: It's difficult, because they would have to make many important changes to their package management scripts and to many existing distro-specific applications, such as boot scripts configuration, for example. MS: Apart from the filesystem what are the other features that make Gobo unique? What's a rootless Gobo install? LVR: A Rootless GoboLinux is a set of scripts that makes it possible for anyone running an UNIX-like operating system to run GoboLinux tools inside their own home directory. That makes it possible for users in eg: Mac OS X to run Compile and get the program installed in a GoboLinux-like structure. And that doesn't require special admin privileges, as everything is installed inside the directory specified by the user (usually their home dir, or another where he/she has write access to). Answering the first question, we have, as principle, to try to ship every package as close as possible to the original one, avoiding patches that modify their behavior. This contrasts with many distributions out there, which usually try to merge as many patches as possible to enhance applications (and sometimes breaking them). Also, the alternative design of Gobo tends to attract a very diverse group of people who like to "think outside the box", such as users of alternative shells and lesser-known programming languages. They usually contribute with many good ideas when we're brainstorming for new features. MS: What does the immediate future hold for Gobo? Any areas where you could use some help? LVR: We're doing a series of snapshot releases in the process of stabilizing 014. The best help we can use now is to get people to download those snapshots, give them a try and report any problems they find at http://bugs.gobolinux.org. We're also always open for new contributors to help maintain the "recipes tree" for the Compile tool. MS: Where do you see Gobo in a couple of years? LVR: In a couple of years, I expect Gobo to be fully grown from being a small niche distro into a larger community. The main technical foundations have been laid and we already have a small but vibrant community of users. We still have some more work on infrastructure ahead of us but from now on I think the prospects are the best possible. MS: Thanks for you time Lucas, and best of luck developing Gobo.   You might also be interested in reading: The Economics of Open Source Donations 2007 Open Source Content Management System Award  
Read more
  • 0
  • 0
  • 3916

article-image-securing-small-business-server-2008
Packt
24 Oct 2009
5 min read
Save for later

Securing the Small Business Server 2008

Packt
24 Oct 2009
5 min read
To do this, we are essentially completing the tasks in the home screen of the Windows SBS Console, which should look like the following screenshot. Assumptions I'm assuming that you understand the concepts of firewalls and ports; otherwise, you will struggle to safely configure your network. I'm also aware that OneCare, for servers, only provides an introductory offer for anti-malware and another product will be required; however, it is easier to describe the installation of one product rather than trying to answer for all products, so I'm using OneCare as a template. You will, however, need an anti-malware product that is server aware, or need to exclude server product locations such as the exchange data stores and other locations. Network security configuration There are a few areas where we can improve the security of the network. They are around the firewall, reducing the traffic that arrives at the SBS 2008 server, and the security certificate that is used to secure and identify the server communications. Configuring the firewall ports You will need the following ports configured on your firewall to direct traffic to SBS 2008: If you were using SBS 2003, then you can close down ports 444 and 4125, which might have previously been open. Loading a third-party security certificate SBS 2008 creates a security certificate to secure its communications. Certificates are only valuable if everybody seeing them trusts the system that issues the certificate. All computers that are part of the SBS 2008 network trust the SBS 2008 server, so trust is achieved in this way. For those that are not part of the SBS 2008 network, a special certificate must be loaded onto those machines so they will trust SBS 2008, else they will provide warnings to users about the integrity of the communication. There are organizations called Certificate Authorities who have established trust in the marketplace and most IT systems trust the certificates they issue. If you wish to have a more publically trusted certificate, then you will need to purchase one of these. One area where third-party certificates are often needed is when using mobile devices, to enable the loading of the SBS 2008 certificate onto the phones. Without the certificate on the phone, synchronization of Outlook information to the phone cannot take place. Importing a certificate If you already have a certificate or have purchased one and have been sent a file containing the certificate including the private keys, then you should follow this process. There are two steps to follow: Importing the certificate into the Local Computer Certificate store Assigning the certificate using the SBS Console Importing the certificate Start Windows SBS Console (Advanced Mode) from the Start menu and click on the Network tab and then the connectivity button. As this is the advanced console, you will see extra tasks available on the righthand side. Click on the Manage certificates task—if this is not present, check you are running the Advanced Mode console: it will say so in the title bar. This will run a management console with the certificates for your computer made visible. Expand the Personal tree and right-click on Certificates and select Import from the All Tasks menu item. Click Next to pass through the welcome screen for the Certificate Import Wizard and then click on the Browse button to locate the certificate. Then, click on Next to continue. You will now be required to enter your Password to enable access to the key. I would put a check mark in the two remaining check boxes to Mark the key as exportable to enable you to export the certificate should you need to in the future and include the extended properties. Then, click on Next. You will be required to confirm the location, which should be Personal and again click on Next. If it is not set to Personal, click on the Browse button and change the Certification store to Personal. Now click on Finish to complete the process and you will see a message stating that The import was successful. Close the Certificates Management console. Assigning the certificate In the Windows SBS Console, click the task Add a trusted certificate to start the process. Click on Next to skip past the introduction. If you have assigned a certificate before, you will be told that A valid trusted certificate already exists and you have the choice of renewing your existing certificate or replacing it. Select I want to replace the existing certificate with a new one and click on Next. If you have not added a trusted certificate before, then you will not see this screen. On the Get the certificate page, select the option to use a certificate already installed on the server and click on Next. The certificate that you installed will show in the list with a Type of Trusted, while the certificates issued by SBS 2008 will show as Self-issued. Select your Trusted certificate and click on Next. Click on Next to start the process and then Finish to exit the wizard.
Read more
  • 0
  • 0
  • 6484

article-image-miro-interview-nicholas-reville
Packt
24 Oct 2009
6 min read
Save for later

Miro: An Interview with Nicholas Reville

Packt
24 Oct 2009
6 min read
Kushal Sharma: What is the vision behind Miro? Nicholas Reville: There's an opportunity to build a new, open mass medium of online television. We're developing the Miro Internet TV platform so that watching Internet video channels will be as easy as watching TV and broadcasting a channel will be open to everyone. Unlike traditional TV, everyone will have a voice. KS: Does PCF finance the entire project or do you have any other contributors? NR: We have tons of help from volunteers – translating the software, coding, testing, and providing user support. We would not be able to do nearly enough without our community. KS: Are the developers full-time PCF employees or is it similar to other Open Source projects where people voluntarily contribute to the community in their spare-time? NR: We have 6 full-time developers and also volunteers. We're a hybrid model, like Mozilla. KS: Please highlight the most crucial features of Miro, and the idea behind having those features as part of this application. NR: The most crucial feature of Miro is the ability to download and play video RSS feeds. It's a truly open way to distribute video online. Using RSS means that creators can publish with any company they want and users can bring together video from multiple sources into one application. KS: How many languages is Miro translated into? NR: Miro is at least partially translated into more than 40 languages, but we always need helping revising and improving the translations. KS: How is Miro different from other players from the technological perspective? NR: Above all, Miro is open-source. That means that anyone can work on the code, improve, and customize it. Beyond this, Miro is unique in a number of ways. It runs on Mac, Windows, and Linux. It can play almost any video format. And it has more HD content available than any other Internet TV application. KS: Are the Torrent download capabilities as well developed as any other standalone Bit Torrent Client? Please tell us something more about it's download capabilities, the share ratio, configurable upload limits while downloading the torrents etc. compared to other software? NR: Our current version of Miro keeps the BitTorrent capabilities very simple and doesn't provide many options. We think that most users don't even notice when they are downloading a torrent feed, however, we want to expand our options and features for power users in future versions – expect much more bit torrent control in 3 months or so. KS: What type of support do you have for Miro? NR: Most of our support is provided user-to-user in the discussion forums – they are very useful, actually. In addition, because we are an open project, anyone can file a bug or even fix a bug. In the long-term this means we will have a more stable user experience than closed competitors. KS: With a host of TV channels and video content going online, viewers could really use a common solution for all their media needs rather than keeping tabs on multiple sources. How do you see Miro being instrumental in providing this? NR: We think that an open platform for video is the only way to create a unified experience for video. Miro is the only really open Internet video solution right now and we think we have a crucial role to play in unifying Internet TV in an open way. KS: Does Miro download Internet TV programs and store it on the hard disk or does it stream live media like any other online service? NR: For now, Miro downloads everything that's watched. This is useful in two key ways: first, you can watch HD video with no skipping or buffering delays. Second, you can move those files onto any external device, with no DRM or other restrictions. In the future we may add a streaming option for some special cases, or the ability to start watching while the download is in progress. KS: Subscription-free content is a great gift that viewers get with Internet TV, however, bandwidth issues could be a concern for some users. What minimum bandwidth requirements would you suggest for satisfactory Internet TV performance on Miro? Furthermore, does Miro have an alternate solution for users having low Internet bandwidth? NR: Miro actually works better than most Internet video solutions for low bandwidth users. On a dial-up connection, streaming video solutions are unusable. Miro will download videos in those circumstances – it may happen slowly, but once you have the video you can watch it full speed with no skipping. KS: I remember a statement on the PCF site saying “Miro is designed to eliminate gatekeepers”. Could you please elaborate on this? NR: Miro works with open standards and is designed to be decentralized, like the web. That means that users can use Miro to connect directly to any video publisher – they don't need our permission and the files don't travel through our servers. Companies like Joost design their software to be highly centralized so that they can control both users and creators. It's time to leave that model behind. KS: So far, what has the response been like? NR: Response has been great. Last month alone, we had more than 200,000 downloads and we've been growing with each release. I expect that when we release version 1.0 in November we'll see even faster growth. KS: What are your future plans for Miro in terms of releases, updates, functionality, etc.? NR: After version 1.0 is released, we'll be making major changes to Miro to improve performance and add an extension system that will give people new ways of customizing the software to fit their needs. KS: To me, Miro’s agenda is a lot more than simply creating a good player. You’re attempting to change the face of Internet Video and the way it’s being hosted right now. How would you describe the future of Miro and Internet Video to our readers? NR: We want Miro to push online video in an open direction. We're hoping to build the best video experience possible, something that can be a true substitute for traditional television. But that doesn't mean we want to control the future of online video – we want other people to build open video distribution platforms as well. Openness is vital to the future of our mass media. KS: What other projects is the PCF involved in? NR: Right now, PCF is exclusively focused on making video more open and Miro is at the center of that. KS: Thank you for your time Nicholas, and good luck developing Miro!
Read more
  • 0
  • 0
  • 2638
article-image-jquery-table-manipulation-part-2
Packt
24 Oct 2009
6 min read
Save for later

jQuery Table Manipulation: Part 2

Packt
24 Oct 2009
6 min read
Advanced Row Striping Row striping can be as simple as two lines of code to alternate the background color: $(document).ready(function() {   $('table.sortable tbody tr:odd').addClass('odd');   $('table.sortable tbody tr:even').addClass('even'); }); If we declare background colors for the odd and even classes as follows, we can see the rows in alternating shades of gray: tr.even {   background-color: #eee; } tr.odd {   background-color: #ddd; } While this code works fine for simple table structures, if we introduce non‑standard rows into the table, such as sub-headings, the basic odd-even pattern no longer suffices. For example, suppose we have a table of news items grouped by year, with columns for date, headline, author, and topic. One way to express this information is to wrap each year's news items in a <tbody> element and use <th colspan="4"> for the subheading. Such a table's HTML (in abridged form) would look like this: <table class="striped"> <thead> <tr> <th>Date</th> <th>Headline</th> <th>Author</th> <th class="filter-column">Topic</th> </tr> </thead><tbody> <tr> <th colspan="4">2007</th> </tr> <tr> <td>Mar 11</td> <td>SXSWi jQuery Meetup</td> <td>John Resig</td> <td>conference</td> </tr> <tr> <td>Feb 28</td> <td>jQuery 1.1.2</td> <td>John Resig</td> <td>release</td> </tr> <tr> <td>Feb 21</td> <td>jQuery is OpenAjax Compliant</td> <td>John Resig</td> <td>standards</td> </tr> <tr> <td>Feb 20</td> <td>jQuery and Jack Slocum's Ext</td> <td>John Resig</td> <td>third-party</td> </tr></tbody><tbody> <tr> <th colspan="4">2006</th> </tr> <tr> <td>Dec 27</td> <td>The Path to 1.1</td> <td>John Resig</td> <td>source</td> </tr> <tr> <td>Dec 18</td> <td>Meet The People Behind jQuery</td> <td>John Resig</td> <td>announcement</td> </tr> <tr> <td>Dec 13</td> <td>Helping you understand jQuery</td> <td>John Resig</td> <td>tutorial</td> </tr></tbody><tbody> <tr> <th colspan="4">2005</th> </tr> <tr> <td>Dec 17</td> <td>JSON and RSS</td> <td>John Resig</td> <td>miscellaneous</td> </tr></tbody></table> With separate CSS styles applied to <th> elements within <thead> and <tbody>, a snippet of the table might look like this: To ensure that the alternating gray rows do not override the color of the subheading rows, we need to adjust the selector expression: $(document).ready(function() { $('table.striped tbody tr:not([th]):odd').addClass('odd'); $('table.striped tbody tr:not([th]):even').addClass('even');}); The added selector, :not([th]), removes any table row that contains a <th> from the matched set of elements. Now the table will look like this: Three-color Alternating Pattern There may be times when we want to apply more complex striping. For example, we can apply a pattern of three alternating row colors rather than just two. To do so, we first need to define another CSS rule for the third row. We'll also reuse the odd and even styles for the other two, but add more appropriate class names for them: tr.even,tr.first { background-color: #eee;}tr.odd,tr.second { background-color: #ddd;}tr.third { background-color: #ccc;} To apply this pattern, we start the same way as the previous example—by selecting all rows that are descendants of a <tbody>, but filtering out the rows that contain a <th<. This time, however, we attach the .each() method so that we can use its built-in index: $(document).ready(function() { $('table.striped tbody tr').not('[th]').each(function(index) { //Code to be applied to each element in the matched set. });}); To make use of the index, we can assign our three classes to a numeric key: 0, 1, or 2. We'll do this by creating an object, or map: $(document).ready(function() { var classNames = { 0: 'first', 1: 'second', 2: 'third' }; $('table.striped tbody tr').not('[th]').each(function(index) { // Code to be applied to each element in the matched set. });}); Finally, we need to add the class that corresponds to those three numbers, sequentially, and then repeat the sequence. The modulus operator, designated by a %, is especially convenient for such calculations. A modulus returns the remainder of one number divided by another. This modulus, or remainder value, will always range between 0 and one less than the dividend. Using 3 as an example, we can see this pattern: 3/3 = 1, remainder 0.4/3 = 1, remainder 1.5/3 = 1, remainder 2.6/3 = 2, remainder 0.7/3 = 2, remainder 1.8/3 = 3, remainder 2. And so on. Since we want the remainder range to be 0 – 2, we can use 3 as the divisor (second number) and the value of index as the dividend (first number). Now we simply put that calculation in square brackets after classNames to retrieve the corresponding class from the object variable as the .each() method steps through the matched set of rows: $(document).ready(function() { var classNames = { 0: 'first', 1: 'second', 2: 'third' }; $('table.striped tbody tr').not('[th]').each(function(index) { $(this).addClass(classNames[index % 3]); });}); With this code in place, we now have the table striped with three alternating background colors: We could of course extend this pattern to four, five, six, or more background colors by adding key-value pairs to the object variable and increasing the value of the divisor in classNames[index % n].
Read more
  • 0
  • 0
  • 4287

article-image-creating-and-managing-user-groups-joomla-and-virtuemart
Packt
24 Oct 2009
9 min read
Save for later

Creating and Managing User Groups in Joomla! and VirtueMart

Packt
24 Oct 2009
9 min read
User manager In Joomla!, there is one User Manager component from where you can manage the users of that site. However, for the VirtueMart component, there is another  user manager which should be used for the VirtueMart shop. To be clear about  the differences of these two user managers, let us look into both. Joomla! user manager Let us first try Joomla!'s user manager. Go to the Joomla! control panel and click on the User Manager icon or click on Site | User Manager. This brings the User Manager screen of Joomla!: We see that the users registered to the Joomla! site are listed in this screen. This screen shows the username, full name, enabled status, group that the user is assigned to, email of the user, date and time when they last visited, and user ID. From this screen, you may guess that any user can be enabled or disabled by clicking on the icon in the Enabled column. Enabled user accounts show a green tick mark in the Enabled column. For viewing the details of any user, click on that user's name in the Name column. That brings up the User:[Edit] screen: As you see, the User Details section shows some important information about the user including Name, Username, E-mail, Group, and so on. You can edit and change these settings including the password. In the Group selection box, you must select one level. The deepest level gets the highest permission in the system. From this section, you can also block a user and decide whether they will receive system  emails or not. In the Parameters section, you can choose the Front-end Language and Time Zone for that user. If you have created contact items using Joomla!'s Contacts component, you may assign one contact to this user in the Contact Information section. VirtueMart user manager Let us now look into VirtueMart's user manager. From the Joomla! control panel, select Components | VirtueMart to reach the VirtueMart Administration Panel. To view the list of the user's registered to the VirtueMart store, click on Admin | Users. This brings the User List screen: As you can see, the User List screen shows the list of users registered to the shop. The screen shows their username, full name, group the user is assigned to, and their shopper group. In the Group column, note that there are two groups mentioned. One group is without brackets and another is inside brackets. The group name mentioned inside brackets is Joomla!'s standard user groups, whereas the one without brackets is VirtueMart's user group. We are going to learn about these user groups in the  next section. For viewing the details of a user, click on the user's name in Username column. That brings the Add/Update User Information screen: The screen has three tabs: General User Information, Shopper Information, and Order List. The General User Information tab contains the same information which was shown in Joomla!'s user manager's User: [Edit] screen. The Shopper Information tab contains shop related information for the user: The Shopper Information section contains: a vendor to which the user is registered the user group the user belongs to a customer number/ID the shopper group Other sections in this tab are: Shipping Addresses, Bill To Information, Bank Account, and any other section you have added to the user registration or account maintenance form. These sections contain fields which are either available on the registration or account maintenance form. If the user has placed some orders, the Order List tab will list the orders placed by that user. If no order has been placed,  the Order List tab will not be visible. Which user manager should we use? As we can see, there is a difference between Joomla!'s user manager and VirtueMart's user manager. VirtueMart's user manager shows some additional information fields, which are necessary for the operation of the shop. Therefore, whenever you are managing users for your shop, use the user manager in the VirtueMart component, not Joomla!'s user manager. Otherwise, all customer information will not be added or updated. This may create some problems in operating the VirtueMart store. User Groups Do you want to decide who can do what in your shop? There is a very good way for doing that in Joomla! and VirtueMart. Both Joomla! and VirtueMart have some predefined user groups. In both cases, you can create additional groups and assign permission levels to these groups. When users register to your site, you assign them to one of the user groups. Joomla! user groups Let us first look into Joomla! user groups. Predefined groups in Joomla! are  described below: User Group Permissions Public Frontend Registered Users in this group can login to the Joomla! site and view the contents, sections, categories, and the items which are marked only for registered users. This group has no access to content management. Author Users in this group get all the permissions the Registered group has. In addition to that, users in this group can submit articles for publishing, and can edit their own articles. Editor Users of this group have all the above permissions, and also can edit articles submitted by other users. However, they cannot publish the contents. Publisher Users in this group can login to the system and submit, edit, and publish their own content as well as contents submitted by other users. Public Backend Manager Users in this group can login to the administration panel and manage content items including articles, sections, categories, links, and so on. They cannot manage users, install modules or components, manage templates and languages, and access global configurations. Users in this group can access some of the components for which the administrator has given permission. Administrator In addition to content management, users in this group can add a user to Super Administrator group, edit a user, access the global configuration settings, access the mail function, and manage/install templates and language files. Super Administrator Users in this group can access all administration functions. For every site, at least one should be in this group to perform global configurations. You cannot delete a user in this group or move him/her to another group. As you can see, most of the users registering to your site should be assigned to the Registered group. By default, Joomla! assigns all newly registered users to the Registered group. You need to add some users to the Editor or Publisher group if they need to add or publish content to the site. The persons who are managing the shop should be assigned to other Public Backend groups such as Manager, Administrator or Super Administrator. VirtueMart user groups Let us now look into the user groups in VirtueMart. To see the user groups, go to VirtueMart's administration panel and click on Admin | User Groups. This shows the User Group List screen: By default, you will see four user groups: admin, storeadmin, shopper, and demo. These groups are used for assigning permissions to users. Also, note the values in the User Group Level column. The higher the value in this field, the lower the permissions assumed for the group. The admin group has a level value of 0, which means it has all of the permissions, and of course, more than the next group storeadmin. Similarly, storeadmin group has more permissions than the shopper group. These predefined groups are key groups in VirtueMart, and you cannot modify or delete these groups. These groups have the following permissions: Group Permissions admin This group has permissions to use all of the modules except checkout and shop. The admin group does not need these because admin users usually do not shop in their store. storeadmin This group has fewer permissions than admin group. Users in this group can access all the modules except the admin, vendor, shop, and checkout modules. They cannot set the global configurations for the store, but can add and edit payment methods, products, categories, and so on. shopper This group has the least permission among the three key groups. By default, users registered to the shop are assigned to this group. Users in this group can fully access the account module, and can use some functions of the shop, coupon, and checkout modules. demo This is a demo group created by default so that administrators can test and play with it. For most of the shops, these four predefined groups will be enough to implement appropriate permissions. However, in some cases you may need to create a new user group and assign separate permissions to that group. For example, you may want to employ some people as store managers who will add products to the catalog and manage the orders. They cannot add or edit payment methods, shipping methods, or other settings, except product and orders. If you add these people to the storeadmin group then they get more permissions than required. In such situations, a good solution is to create a new group, add selected user accounts to that group, and assign permissions to that group. Creating a new user group For creating a new user group, click on the New button in the toolbar on the User Group List screen. This brings Add/Edit a User Group screen: In the Add/Edit a User Group screen, enter the group's name and group level. You must type a higher value than existing groups (for example, 1000). Click on the Save icon to save the user group. You will now see the newly created user group in the User Group List screen.
Read more
  • 0
  • 0
  • 8734

article-image-economics-open-source-donations
Packt
24 Oct 2009
8 min read
Save for later

The Economics of Open Source Donations

Packt
24 Oct 2009
8 min read
Donations play a crucial role in supporting Free and Open Source Software projects. At times readers will write in to share their positive experience with a utility or program or a distribution that I have written about. Now don't confuse them with your average technical-bent-of-mind Linux user. These are accountants, home-office businessman, and even carpenters and plumbers, who've saved a lot of money thanks to open source software. And they have one question in mind -- how do I help the person behind the program? I generally recommend everyone to find the project's forum boards, or IRC channel, or mailing list and try and help other new users. Some do, and eventually even graduate to write documentation, like simple installation steps or how to install dependencies, in forum board posts. But some readers are incapable of even that kind of help. After my interview with Sebastian Trüg of K3b, a reader wrote in surprised that the software he had been using for writing MP3s for his grandchildren, ever since his grandson installed Kubuntu on his box, was written by a college student. He wanted to help, but didn't know how. K3b just worked for him. His demands from the distribution were minimal and so was his technical understanding. Recommending such people (and in fact others too) to donate to their favorite projects, isn't a bad idea. In fact I point them to Ladislav Bodnar's DistroWatch donations program to get a feel for the idea. I am not sure how many people take my advice seriously and do actually donate, but a couple of them wrote back after my interview with Bodnar, where he expressed surprise about the lack of response or even a courteous "thank you" from big projects after receiving donations. "What do they use the money for", they all wanted to know. Some suggested themselves that it's because "they are such big groups, and they all have jobs." So why are donations important? Since it seems to bother so many people, I thought I'd ask someone in the know. Fabio Erculiani, lead-developer of the two-man development team that churns out the popular Gentoo-based Sabayon Linux lists some common expenses of running a FOSS project. "We have hosting bills," explains Erculiani who has passed on a job offer by Google to complete his studies, "backup systems such as NASs, RAID arrays (hard drives tend to break often here... I had two breakages in around 6 months), new hardware, especially video cards, processors, wifi cards (usb, pcmcia, pci). We also bought a Mac Mini with a fundraiser at the end of 2006. I think that the most important thing, at our stage, is to keep a good and tested support. We also need to finance the development. This means two things: first, paying the electricity to run 2-3 servers 24/7/365 and secondly, spend time on long term projects, like Entropy, our upcoming new binary package manager." That's quite a list. "I think donations are important for projects that are done by developers in their spare time like I did the first 8 years of K3b," agrees Sebastian Trüg, lead-developer at K3b, the popular CD/DVD burning app. Trüg now works full time on free software, sponsored by Mandriva and spends about 30% of his time working on K3b. If you think donations aren't important for big projects whose developers have regular jobs, think again. "Donations are critical to the CentOS Project," comments Johnny Hughes, one of CentOS's 14 volunteer developers that develop this enterprise-class distribution. "Money is required to allow developers to attend FOSS events outside their area. Money and hardware donations are also required for development machines to build CentOS and for a network to distribute CentOS. We have been much more successful at obtaining hardware donations than at obtaining monetary donations, but both are important." But for Samuel Baggen, who works full-time on his popular Elive Live CD, donations are not just important, they are essential. "The donations received are required," explains Baggen, "so I can work on Elive full time without needing a regular job. With enough donations I can spend all my time on Elive, support the community and respond and work on their feedback." With enough donations Baggen hopes to start paying for serious services for Elive like professional designers, coders, etc. Encouraging users to donate Since it's such a critical component to their existence, many projects take great measures to get users to donate. Donations to the GIMP project for example are tax exempt in the US. Many projects also throw in a little extra for their donating users. Erculiani offers Sabayon branded goodies and is thinking of offering a premium membership where users will be able to get extra stuff like dedicated mirrors and discounted prices in the e-shop. "Last year we bought two new Dual Core processors," he says, "and this year I have finally updated my server with a new CPU, mainboard, RAM and two hard drives. We have also paid the hosting service and even gave some money to other projects." Hughes though doesn't like the idea of providing faster mirrors, goodies, or anything else extra about their distribution to people who donate. "As we believe strongly in free software," underlines Hughes, "we want CentOS to be available to everyone, and hope that they will use it and then donate." But CentOS does provide hardware donors with free advertising on their website and in the future will be offering some paid support for users that want that service. Trüg has only asked for donations once. "I hope that users will get the idea themselves :)." He also believes that since he offers no extra goodies, users will only donate out of good will. When he had that fund raiser for new hardware, Trüg overshot his goal by 500%. Currently, you can buy the official K3b Handbook which is so far only in German but an English translation will be available soon. Baggen on the other hand has tried a more "adventurous" strategy to get users to donate and was even criticized by some users. He made donations mandatory to download stable releases of Elive. "There are many users," shares Baggen, "who only donate $0.01 but I don't worry about that too much because the users who are satisfied with Elive and support a better future for Elive will bring more cool people into the Elive world. The donation for download system is sufficient enough to maintain the future of the project. More donations though will mean more features and a brighter future. We will be looking into fun ways to raise money in the future." Baggen has recently started offering paid bonus-disks that allow users to install popular software with the click of a button. But what really triggers donations? Are goodies motivating enough to donate? I am skeptical. Without blowing my own trumpet, I wonder if that K3b user would have donated (if he ever did) if I hadn't interviewed Trüg. Hughes agrees there is a connection between a project's popularity, the press coverage it receives and its user base. "How a project gets that press," he explains, "is obviously to provide a quality product that people need and are willing to write and talk about." Contests and awards, according to Hughes, provide another avenue for getting press coverage and expanding the user base. "Since only a small percentage of users actually donate, the bigger your user base, the larger the donation group." That might work for a big project like a complete distribution but for an application like K3b, a broad user-base doesn't guarantee donations. Trüg nails this perfectly. "The way I experienced it," he shares, "there is a phase in which the project becomes popular, that is, when people discover it as a better alternative. That is when they donate the most. Now, K3b comes with every distribution and is the default burning application which means there is no more "discovering of a new project". The result is that the donations are less frequent." Final thoughts Donations are important to FOSS projects, big and small. Some projects go out of their way to ensure donating users get more in return than the satisfaction of helping their favorite project. While it would seem a project's popularity and a sizable user-base would ensure monetary support, as applications become more reliable and just work out of the box, they might adversely affect a project's chances of receiving donations. But one thing's certain. Irrespective of whether you decide to donate or not, the developer or developers behind the project will continue hacking. Spirit, after all, cannot be donated.   You might also be interested in reading: Open Source Receives Royalties Boost 2007 Open Source Content Management System Award
Read more
  • 0
  • 0
  • 4424
article-image-dynamic-theming-drupal-6-part-1
Packt
24 Oct 2009
9 min read
Save for later

Dynamic Theming in Drupal 6 - Part 1

Packt
24 Oct 2009
9 min read
Using Multiple Templates Most advanced sites built today employ multiple page templates. In this section, we will look at the most common scenarios and how to address them with a PHPTemplate theme. While there are many good reasons for running multiple page templates, you should not create additional templates solely for the purpose of disabling regions to hide blocks. While the approach will work, it will result in a performance hit for the site, as the system will still produce the blocks, only to then wind up not displaying them for the pages. The better practice is to control your block visibility. Using a Separate Admin Theme With the arrival of Drupal 5, one of the most common Drupal user requests was satisfied; that is, the ability to easily designate a separate admin theme. In Drupal, designating a separate theme for your admin interface remains a simple matter that you can handle directly from within the admin system. To designate a separate theme for your admin section, follow these steps: Log in and access your site's admin system. Go to Administer | Site configuration | Administration theme. Select the theme you desire from the drop-down box listing all the installed themes. Click Save configuration, and your selected theme should appear immediately. Multiple Page or Section Templates In contrast to the complete ease of setting up a separate administration theme is the comparative difficulty of setting up multiple templates for different pages or sections. The bad news is that there is no admin system shortcut—you must manually create the various templates and customize them to suit your needs. The good news is that creating and implementing additional templates is not difficult and it is possible to attain a high degree of granularity with the techniques described below. Indeed, should you be so inclined, you could literally define a distinct template for each individual page of your site. Drupal employs an order of precedence based on a naming convention (or "suggestions" as they are now being called on the Drupal site). You can unlock the granularity of the system through proper application of the naming convention. It is possible, for example, to associate templates with every element on the path, or with specific users, or with a particular functionality—all through the simple process of creating a new template and naming it appropriately. The system will search for alternative templates, preferring the specific to the general, and failing to find a more specific template, will apply the default page.tpl.php. Consider the following example of the order of precedence and the naming convention in action. The custom templates above could be used to override the default page.tpl.php and theme either an entire node (page-node.tpl.php), or simply the node with an ID of 1 (page-node-1.tpl.php),or the node in edit mode (page-node-edit.tpl.php), depending on the name given the template. In the example above, the page-node templates would be applied to the node in full page view. In contrast, should you wish to theme the node in its entirety, you would need to intercept and override the default node.tpl.php. The fundamental methodology of the system is to use the first template file it finds and ignore other, more general templates (if any). This basic principle, combined with proper naming of the templates, gives you control over the template used in various situations. The default suggestions provided by the Drupal system should be sufficient for the vast majority of theme developers. However, if you find that you need additional suggestions beyond those provided by the system, it is possible to extend your site and add new suggestions. See http://drupal.org/node/223440 for a discussion of this advanced Drupal theming technique. Let's take a series of four examples to show how this feature can be used to provide solutions to common problems: Create a unique homepage template. Use a different template for a group of pages. Assign a specific template to a specific page. Designate a specific template for a specific user. Create a Unique Homepage Template Let's assume that you wish to set up a unique template for the homepage of a site. Employing separate templates for the homepage and the interior pages is one of the most common requests web developers hear. With Drupal, you can, without having to create a new template, achieve some variety within a theme by controlling the visibility of blocks on the homepage. If that simple technique does not give you enough flexibility, you will need to consider using a dedicated template that is purpose-built for your homepage content. The easiest way to set up a distinct front page template is to copy the existing page.tpl.php file, rename it, and make your changes to the new file. Alternatively, you can create a new file from scratch. In either situation, your front-page-specific template must be named page-front.tpl.php. The system will automatically display your new file for the site's homepage, and use the default page.tpl.php for the rest of the site. Note that page-front.tpl.php is whatever page you specify as the site's front page via the site configuration settings. To override the default homepage setting visit Administer | Site configuration | Site information, then enter the URL you desire into the field labeled Default home page. Use a Different Template for a Group of Pages Next, let's associate a template with a group of pages. You can provide a template to be used by any distinct group of pages, using as your guide the path for the pages. For example, to theme all the user pages you would create the template page-user.tpl.php. To theme according to the type of content, you can associate your page template with a specific node, for example, all blog entry pages can be controlled by the filepage-blog-tpl.php. The table below presents a list of suggestions you can employ to theme various pages associated with the default functionalities in the Drupal system. Suggestion Affected Page page-user.tpl.php user pages page-blog.tpl.php blog pages (but not the individual node pages) page-forum.tpl.php forum pages (but not the individual node pages) page-book.tpl.php book pages (but not the individual node pages) page-contact.tpl.php contact form (but not the form content)   Assign a Specific Template to a Specific Page Taking this to its extreme, you can associate a specific template with a specific page. By way of example, assume we wish to provide a unique template for a specific content item. Let's assume our example page is located at http://www.demosite.com/node/2/edit. The path of this specific page gives you a number of options. We could theme this page with any of the following templates (in addition to the default page.tpl.php): page-node.tpl.php page-node-2.tpl.php page-node-edit.tpl.php A Note on Templates and URLsDrupal bases the template order of precedence on the default path generated by the system. If the site is using a module like pathauto, which alters the path that appears to site visitors, remember that your templates will still be displayed based on the original paths. The exception here being page-front.tpl.php, which will be applied to whatever page you specify as the site's front page via the site configuration settings (Administer | Site configuration| Site information). Designate a Specific Template for a Specific User Assume that you want to add a personalized theme for the user with the ID of 1(the Drupal equivalent of a Super Administrator). To do this, copy the existing page.tpl.php file, rename it to reflect its association with the specific user, and make any changes to the new file. To associate the new template file with the user, name the file: page-user-1.tpl. Now, when user 1 logs into the site, they will be presented with this template. Only user 1 will see this template and only when he or she is logged in and visiting the account page. The official Drupal site includes a collection of snippets relating to the creation of custom templates for user profile pages. The discussion is instructive and worth review, though you should always be a bit cautious with user-submitted code snippets as they are not official releases from the Drupal Association. See, http://drupal.org/node/35728 Dynamically Theming Page Elements In addition to being able to style particular pages or groups of pages, Drupal and PHPTemplate make it possible to provide specific styling for different page elements. Associating Elements with the Front Page Drupal provides $is_front as a means of determining whether the page currently displayed is the front page. $is_front is set to true if Drupal is rendering the front page; otherwise it is set to false. We can use $is_front in our page.tpl.php file to help toggle display of items we want to associate with the front page. To display an element on only the front page, make it conditional on the state of $is_front. For example, to display the site mission on only the front page of the site, wrap $mission (in your page.tpl.php file) as follows: <?php if ($is_front): ?> <div id="mission"> <?php print $mission; ?> </div><?php endif; ?> To set up an alternative condition, so that one element will appear on the front page but a different element will appear on other pages, modify the statement like this: <?php if ($is_front): ?> //whatever you want to display on front page<?php else: ?> //what is displayed when not on the front page<?php endif; ?> $is_front is one of the default baseline variables available to all templates.
Read more
  • 0
  • 0
  • 2952

article-image-vbnet-application-sql-anywhere-10-database-part-2
Packt
24 Oct 2009
3 min read
Save for later

VB.NET Application with SQL Anywhere 10 database: Part 2

Packt
24 Oct 2009
3 min read
[Read the first part of this article here] Now you can click on the Preview Data… hyperlink which opens up the Preview Data window as shown in Figure 19. The Select an object to preview field gets populated automatically to run the getData () method. When you click on the Preview button, the grey area is populated by a table showing the retrieved rows of data from the Customers table as shown in Figure 19. Figure 19 Click on the Close button in the above window. In the various tasks of the DataGridView many options are chosen by default. You may also check reordering of the column by placing a check mark in the Edit Column Reordering in Figure 18 which opens Edit Columns window as shown in Figure 20, another useful control to manipulate the columns so that the columns you want to see are the first few columns. Figure 20 You may want to edit the columns and change some of the items such as reordering of the columns, column name, column width, etc. All this can be done from this screen. For this tutorial only the columns width was changed. A label was added and its text was changed to, "Demo 10 Database Customers" as shown in Figure 21. Figure 21     Build the project from the main menu item, Build. Now when the program is run by clicking the Debug --> Start without debugging, or by pressing Ctrl+F5, the program runs and Form1 is displayed as shown in Figure 22. Figure 22 Figure 23 shows the properties of the dataset DsAny that is created when the data source was created. Figure 23   The schema of the above dataset is shown in Figure 24. This gets added to the project files in the Solution Explorer. Figure 24   Using the smart tasks on the CustomerBindingSource you can carry out few of the indicated tasks shown in Figure 25. Figure 25   The properties of the CustomerBindingSource are shown in Figure 26. Figure 26 The CustomerTableAdapter directly connects to the database and it has its own properties window as shown in Figure 27. You will be able to edit queries in the dataset designer, add query, etc using the hyperlinks at the bottom of the properties window. Figure 27 Alternatively you will be able to carry out similar tasks from the smart tasks on the CustomerTableAdapter component in the component tray as shown in Figure 28. In Microsoft applications, you have more than one way of carrying out a task. Figure 28 The Object Browser shown in Figure 29 for this project shows the various data related classes that are used in the application working behind scenes as not a single line of code was explicitly used for this form to display the data. Figure 29  
Read more
  • 0
  • 0
  • 3469
Modal Close icon
Modal Close icon