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-flex-101-flash-builder-4-part-1
Packt
16 Oct 2009
11 min read
Save for later

Flex 101 with Flash Builder 4: Part 1

Packt
16 Oct 2009
11 min read
  The article is intended towards developers who have never used Flex before and would like to exercise a “Hello World” kind of tutorial. The article does not aim to cover Flex and FB4 in detail but rather focuses on the mechanics of FB4 and getting an application running with minimal effort. For developers familiar with Flex and the predecessor to Flash Builder 4 (Flex Builder 2 or 3), it contains an introduction to FB4 and some differences in the way you go about building Flex Applications using FB4. Even if you have not programmed before and are looking at understanding how to make a start in developing applications, this would serve as a good start. The Flex Ecosystem The Flex ecosystem is a set of libraries, tools, languages and a deployment runtime that provides an end-to-end framework for designing, developing and deploying RIAs. All these together are being branded as a part of the Flash platform. In its latest release, Flex 4, special efforts have been put in to address the designer to developer workflow by letting graphic designers address layout, skinning, effects and general look and feel of your application and then the developers taking over to address the application logic, events, etc. To understand this at a high level, take a look at the diagram shown below. This is a very simplified diagram and the intention is to project a 10,000 ft view of the development, compilation and execution process. Let us understand the diagram now: The developer will typically work in the Flash Builder Application. Flash Builder is the Integrated Development Environment (IDE) that provides an environment for coding, compiling, running / debugging your Flex based applications. Your Flex Application will typically consist of MXML and ActionScript code. ActionScript is an ECMAScript compatible Object Oriented language, whereas MXML is an XML-based markup language. Using MXML you can define/layout your visual components like buttons, combobox, data grids, and others. Your application logic will be typically coded inside ActionScript classes/methods. While coding your Flex Application, you will make use of the Flex framework classes that provide most of the core functionality. Additional libraries like Flex Charting libraries and 3rd party components can be used in your application too. Flash Builder compiles all of this into object byte code that can be executed inside the Flash Player. Flash Player is the runtime host that executes your application. This is high level introduction to the ecosystem and as we work through the samples later on in the article, things will start falling into place. Flash Builder 4 Flash Builder is the new name for the development IDE previously known as Flex Builder. The latest release is 4 and it is currently in public beta. Flash Builder 4 is based on the Eclipse IDE, so if you are familiar with Eclipse based tools, you will be able to navigate your way quite easily. Flash Builder 4 like Flex Builder 3 previously is a commercial product and you need to purchase a development license. FB4 currently is in public beta and is available as a 30-day evaluation. Through the rest of the article, we will make use of FB4 and will be focused completely on that to build and run the sample applications. Let us now take a look at setting up FB4. Setting up your Development Environment To setup Flash Builder 4, follows these steps: The first step should be installing Flash Player 10 on your system. We will be developing with the Flex 4 SDK that comes along with Flash Builder 4 and it requires Flash Player 10. You can download the latest version of Flash Player from here: http://www.adobe.com/products/flashplayer/ Download Flash Builder 4 Public Beta from http://labs.adobe.com/technologies/flashbuilder4/. The page is shown below: After you download, run the installer program and proceed with the rest of the installation. Launch the Adobe Flash Builder Beta. It will prompt first with a message that it is a Trial version as shown below: To continue in evaluation mode, select the option highlighted above and click Next. This will launch the Flash Builder IDE. Let us start coding with Flash Builder 4 IDE. We will stick to tradition and write the “Hello World” application. Hello World using Flash Builder 4 In this section, we will be developing a basic Hello World application. While the application does not do much, it will help you get comfortable with the Flash Builder IDE. Launch the Flash Builder IDE. We will be creating a Flex Project. Flash Builder will help us create the Project that will contain all our files. To create a new Flex Project, click on the File → New → Flex Project as shown below: This will bring up a dialog in which you will need to specify more details about the Flex Project that you plan to develop. The dialog is shown below: You will need to provide at least the following information: Project Name: This is the name of your project. Enter a name that you want over here. In our case, we have named our project MyFirstFB4App. Application Type: We can develop both a Web version and a desktop version of our application using Flash Builder. The web application will then run inside of a web browser and execute within the Flash Player plug-in. We will go with the Web option over here. The Desktop application runs inside the Adobe Integrated Runtime environment and can have more desktop like features. We will skip that option for now. We will let the other options remain as is. We will use the Flex 4.0 SDK and currently we are not integrating with any Server side layer so we will leave that option as None/Other. Click on Finish at this point to create your Flex Project. This will create a main application file called MyFirstFB4App.mxml as shown below. We will come back to our coding a little later but first we must familiarize ourselves with the Flash Builder IDE. Let us first look at the Package Explorer to understand the files that have been created for the Flex Project. The screenshot is shown below: It consists of the main source file MyFirstFB4App.mxml. This is the main application file or in other words the bootstrap. All your source files (MXML and ActionScript code along with assets like images, and others should go under the src folder. They can optionally be placed in packages too. The Flex 4.0 framework consists of several libraries that you compile your code against. You would end up using its framework code, components (visual and non-visual) and other classes. These classes are packaged in a library file with an extension .swc. A list of library files is shown above. You do not need to typically do anything with it. Optionally, you can also use 3rd party components written by other companies and developers that are not part of the Flex framework. These libraries are packages as .SWC files too and they can be placed in the libs folder as shown in the previous screenshot. The typical step is to write and compile your code—build your project. If your build is successful, the object code is generated in the bin-debug folder. When you deploy your application to a Web Server, you will need to pickup the contents from this folder. We will come to that a little later. The html-template folder contains some boiler-plate code that contains the container HTML into which your object code will be referenced. It is possible to customize this but for now, we will not discuss that. Double-click MyFirstFB4App.mxml file. This is our main application file. The code listing is given below: <?xml version="1.0" encoding="utf-8"?> <s:Application minWidth="1024" minHeight="768"> </s:Application> As discussed before, you will typically write one or more MXML files that will contain typically your visual components (although there can be non-visual components also). By visual components, we mean controls like button, combobox, list, tree, and others. It could also contain layout components and containers that help you layout your design as per the application screen design. To view what components, you can place on the main application canvas, select the Design View as shown below: Have a look at the lower half of the left pane. You will see the Components tab as shown below, which would address most needs of your Application Visual design. Click on the Controls tree node as shown below. You will see several controls that you can use and from which, we will use the Button control for this application. Simply select the Button control and drag it to the Design View Canvas as shown below: This will drop an instance of the Button control on the Design View as shown below: Select the Button to see its properties panel as shown below. Properties Panel is where you can set several attributes at design time for the control. In case the Properties panel is not visible, you can get to that by selecting Window → Properties from the main menu. In the Properties panel, we can change several key attributes. All controls can be uniquely identified and addressed in your code via the ID attribute. This is a unique name that you need to provide. Go ahead and give it some meaningful name. In our case, we name it btnSayHello. Next we can change the label so that instead of Button, it can display a message for example, Say Hello. Finally we want to wire some code such that if the button is clicked, we can do some action like display a Message Box saying Hello World. To do that, click the icon next to the On click edit field as shown below. It will provide you two options. Select the option for Generate Event Handler. This will generate the code and switch to the Source view. The code is listed below for your reference. <?xml version="1.0" encoding="utf-8"?> <s:Application minWidth="1024" minHeight="768"> <fx:Script> <![CDATA[ protected function btnSayHello_clickHandler(event:MouseEvent):void { // TODO Auto-generated method stub } ]]> </fx:Script> <s:Button x="17" y="14" label="Button" id="btnSayHello" click="btnSayHello_clickHandler(event)"/> </s:Application> There are few things to note here. As mentioned most of your application logic will be written in ActionScript and that is exactly what Flash Builder has generated for you. All such code is typically added inside a scripting block marked with the <fx:Script> tag. You can place your ActionScript methods over here that can be used by the rest of the application. When we clicked on Generate Event Handler, Flash Builder generated the Event Handler code. This code is in ActionScript and was appropriately placed inside the <fx:Script> block for us. If you look at the code, you can see that it has added a function that is invoked when the click event is fired on the button. The method is btnSayHello_clickHandler and if you notice it has an empty method that is, no implementation. Let us run the application now to see what it looks like. To run the application, click on the   Run icon in the main toolbar of Flash Builder. This will launch the web application as shown below. Clicking the Say Hello button will not do anything at this point since there is no code written inside the handler as we saw above. To display the MessageBox, we add the code shown below (Only the Script section is shown below): <fx:Script> <![CDATA[ import mx.controls.Alert; protected function btnSayHello_clickHandler(event:MouseEvent):void { Alert.show("Hello World"); } ]]> </fx:Script> We use one of the classes (called Alert) from the Flex framework. Like any other language, we need to specify which package we are using the class from so that the compiler can understand it. The Alert class belongs to the mx.controls package and it has a static method called show() which takes a single parameter of type String. This String parameter is the message to be displayed and in our case it is "Hello World". To run this, click Ctrl-S to save your file or File →  Save from the main menu. And click on Run icon in the main toolbar. This will launch the application and on clicking the SayHello button, you will see the Hello World Alert window as shown below.
Read more
  • 0
  • 0
  • 3150

Packt
16 Oct 2009
17 min read
Save for later

WCF – Windows Communication Foundation

Packt
16 Oct 2009
17 min read
What is WCF? WCF is the acronym for Windows Communication Foundation. It is Microsoft's latest technology that enables applications in a distributed environment to communicate with each other. WCF is Microsoft's unified programming model for building service-oriented applications. It enables developers to build secure, reliable, transacted solutions that integrate across platforms and interoperate with existing investments. WCF is built on the Microsoft .NET Framework and simplifies the development of connected systems. It unifies a broad array of distributed systems capabilities in a composable, extensible architecture that supports multiple transports, messaging patterns, encodings, network topologies, and hosting models. It is the next version of several existing products—ASP.NET's web methods (ASMX) and Microsoft Web Services Enhancements (WSE) for Microsoft .NET, .NET Remoting, Enterprise Services, and System.Messaging. The purpose of WCF is to provide a single programming model that can be used to create services on the .NET platform for organizations. Why is WCF used for SOA? As we have seen in the previous section, WCF is an umbrella technology that covers ASMX web services, .NET remoting, WSE, Enterprise Service, and System.Messaging. It is designed to offer a manageable approach to distributed computing, broad interoperability, and direct support for service orientation. WCF supports many styles of distributed application development by providing a layered architecture. At its base, the WCF channel architecture provides asynchronous, untyped message-passing primitives. Built on top of this base are protocol facilities for secure, reliable, transacted data exchange and a broad choice of transport and encoding options. Let us take an example to see why WCF is a good approach for SOA. Suppose a company is designing a service to get loan information. This service could be used by the internal call center application, an Internet web application, and a third-party Java J2EE application such as a banking system. For interactions with the call center client application, performance is important. For communication with the J2EE-based application however, interoperability becomes the highest goal. The security requirements are also quite different between the local Windows-based application, and the J2EE-based application running on another operating system. Even transactional requirements might vary, with only the internal application being allowed to make transactional requests. With these complex requirements, it is not easy to build the desired service with any single existing technology. For example, the ASMX technology may serve well for the interoperability, but its performance may not be ideal. The .NET remoting will be a good choice from the performance perspective, but it is not good at interoperability. Enterprise Services could be used for managing object lifetimes and defining distributed transactions, but Enterprise Services supports only a limited set of communication options. Now with WCF, it is much easier to implement this service. As WCF has unified a broad array of distributed systems capabilities, the get loan service can be built with WCF for all of its application-to-application communication. The following shows how WCF addresses each of these requirements: Because WCF can communicate using web service standards, interoperability with other platforms that also support SOAP, such as the leading J2EE-based application servers, is straightforward. You can also configure and extend WCF to communicate with web services using messages not based on SOAP, for example, simple XML formats such as RSS. Performance is of paramount concern for most businesses. WCF was developed with the goal of being one of the fastest distributed application platforms developed by Microsoft. To allow for optimal performance when both parties in a communication are built on WCF, the wire encoding used in this case is an optimized binary version of an XML Information Set. Using this option makes sense for communication with the call center client application, because it is also built on WCF, and performance is an important concern. Managing object lifetimes, defining distributed transactions, and other aspects of Enterprise Services, are now provided by WCF. They are available to any WCF-based application, which means that the get loan service can use them with any of the other applications that it communicates with. Because it supports a large set of the WS-* specifications, WCF helps to provide reliability, security, and transactions when communicating with any platform that supports these specifications. The WCF option for queued messaging, built on Message Queuing, allows applications to use persistent queuing without using another set of application programming interfaces. The result of this unification is greater functionality, and significantly reduced complexity. WCF architecture The following diagram illustrates the major layers of the Windows Communication Foundation (WCF) architecture. This diagram is taken from the Microsoft web site (http://msdn.microsoft.com/en-us/library/ms733128.aspx): The Contracts layer defines various aspects of the message system. For example, the Data Contract describes every parameter that makes up every message that a service can create or consume. The Service runtime layer contains the behaviors that occur only during the actual operation of the service, that is, the runtime behaviors of the service. The Messaging layer is composed of channels. A channel is a component that processes a message in some way, for example, authenticating a message. In its final form, a service is a program. Like other programs, a service must be run in an executable format. This is known as the hosting application. In the next section, we will explain these concepts in detail. Basic WCF concepts—WCF ABCs There are many terms and concepts around WCF, such as address, binding, contract, endpoint, behavior, hosting, and channels. Understanding these terms is very helpful when using WCF. Address The WCF Address is a specific location for a service. It is the specific place to which a message will be sent. All WCF services are deployed at a specific address, listening at that address for incoming requests. A WCF Address is normally specified as a URI, with the first part specifying the transport mechanism, and the hierarchical part specifying the unique location of the service. For example, http://www.myweb.com/myWCFServices/SampleService can be an address for a WCF service. This WCF service uses HTTP as its transport protocol, and it is located on the server www.myweb.com, with a unique service path of myWCFServices/SampleService. The following diagram illustrates the three parts of a WCF service address. Binding Bindings are used to specify the transport, encoding, and protocol details required for clients and services to communicate with each other. Bindings are what WCF uses to generate the underlying wire representation of the endpoint. So, most of the details of the binding must be agreed upon by the parties that are communicating. The easiest way to achieve this is for clients of a service to use the same binding that the service uses. A binding is made up of a collection of binding elements. Each element describes some aspect of how the service communicates with clients. A binding must include at least one transport binding element, at least one message encoding binding element (which can be provided by the transport binding element by default), and any number of other protocol binding elements. The process that builds a runtime out of this description allows each binding element to contribute code to that runtime. WCF provides bindings that contain common selections of binding elements. These can either be used with their default settings, or the default values can be modified according to user requirements. These system-provided bindings have properties that allow direct control over the binding elements and their settings. The following are some examples of the system-provided bindings: BasicHttpBinding, WSHttpBinding, WSDualHttpBinding, WSFederationHttpBinding, NetTcpBinding, NetNamedPipeBinding, NetMsmqBinding, NetPeerTcpBinding, and MsmqIntegrationBinding. Each one of these built-in bindings has predefined required elements for a common task, and is ready to be used in your project. For instance, the BasicHttpBinding uses HTTP as the transport for sending SOAP 1.1 messages, and it has attributes and elements such as receiveTimeout, sendTimeout, maxMessageSize, and maxBufferSize. You can accept the default settings of its attributes and elements, or overwrite them as needed. Contract A WCF contract is a set of specifications that define the interfaces of a WCF service. A WCF service communicates with other applications according to its contracts. There are several types of WCF contracts, such as Service Contract, Operation Contract, Data Contract, Message Contract, and Fault Contract. Service contract A service contract is the interface of the WCF service. Basically, it tells others what the service can do. It may include service-level settings, such as the name of the service, the namespace of the service, and the corresponding callback contracts of the service. Inside the interface, it can define a bunch of methods, or service operations for specific tasks. Normally, a WCF service has at least one service contract. Operation contract An operation contract is defined within a service contract. It defines the parameters and return type of an operation. An operation can take data of a primitive (native) data type, such as an integer as a parameter, or it can take a message, which should be defined as a message contract type. Just as a service contract is an interface, an operation contract is a definition of an operation. It has to be implemented in order that the service functions as a WCF service. An operation contract also defines operation-level settings, such as the transaction flow of the operation, the directions of the operation (one-way, two-way, or both ways), and fault contract of the operation. The following is an example of an operation contract: [WCF::FaultContract(typeof(MyWCF.EasyNorthwind.FaultContracts.ProductFault))]MyWCF.EasyNorthwind.MessageContracts.GetProductResponseGetProduct(MyWCF.EasyNorthwind.MessageContracts.GetProductRequest request); In this example, the operation contract's name is GetProduct, and it takes one input parameter, which is of type GetProductRequest (a message contract) and has one return value, which is of type GetProductResponse (another message contract). It may return a fault message, which is of type ProductFault (a fault contract), to the client applications. We will cover message contract and fault contract in the following sections. Message contract If an operation contract needs to pass a message as a parameter or return a message, the type of these messages will be defined as message contracts. A message contract defines the elements of the message, as well as any message-related settings, such as the level of message security, and also whether an element should go to the header or to the body. The following is a message contract example: namespace MyWCF.EasyNorthwind.MessageContracts{ /// <summary> /// Service Contract Class - GetProductResponse /// </summary> [WCF::MessageContract(IsWrapped = false)] public partial class GetProductResponse { private MyWCF.EasyNorthwind.DataContracts.Product product; [WCF::MessageBodyMember(Name = "Product")] public MyWCF.EasyNorthwind.DataContracts.Product Product { get { return product; } set { product = value; } } }} In this example, the namespace of the message contract is MyWCF.EasyNorthwind.MessageContracts, and the message contract's name is GetProductResponse. This message contract has one member, which is of type Product. Data contract Data contracts are data types of the WCF service. All data types used by the WCF service must be described in metadata to enable other applications to interoperate with the service. A data contract can be used by an operation contract as a parameter or return type, or it can be used by a message contract to define elements. If a WCF service uses only primitive (native) data types, it is not necessary to define any data contract. The following is an of example data contract: namespace MyWCF.EasyNorthwind.DataContracts{ /// <summary> /// Data Contract Class - Product /// </summary> [WcfSerialization::DataContract(Namespace = "http://MyCompany.com/ ProductService/EasyWCF/2008/05", Name = "Product")] public partial class Product { private int productID; private string productName; [WcfSerialization::DataMember(Name = "ProductID", IsRequired = false, Order = 0)] public int ProductID { get { return productID; } set { productID = value; } } [WcfSerialization::DataMember(Name = "ProductName", IsRequired = false, Order = 1)] public string ProductName { get { return productName; } set { productName = value; } } }} In this example, the namespace of the data contract is MyWCF.EasyNorthwind.DataContracts, the name of the data contract is Product, and this data contract has two members (ProductID and ProductName).   Fault contract In any WCF service operation contract, if an error can be returned to the caller, the caller should be warned of that error. These error types are defined as fault contracts. An operation can have zero or more fault contracts associated with it. The following is a fault contract example: namespace MyWCF.EasyNorthwind.FaultContracts{ /// <summary> /// Data Contract Class - ProductFault /// </summary> [WcfSerialization::DataContract(Namespace = "http://MyCompany.com/ ProductService/EasyWCF/2008/05", Name = "ProductFault")] public partial class ProductFault { private string faultMessage; [WcfSerialization::DataMember(Name = "FaultMessage", IsRequired = false, Order = 0)] public string FaultMessage { get { return faultMessage; } set { faultMessage = value; } } }} In this example, the namespace of the fault contract is MyWCF.EasyNorthwind.FaultContracts, the name of the fault contract is ProductFault, and the fault contract has only one member (FaultMessage). Endpoint Messages are sent between endpoints. Endpoints are places where messages are sent or received (or both), and they define all of the information required for the message exchange. A service exposes one or more application endpoints (as well as zero or more infrastructure endpoints). A service can expose this information as the metadata that clients can process to generate appropriate WCF clients and communication stacks. When needed, the client generates an endpoint that is compatible with one of the service's endpoints. A WCF service endpoint has an address, a binding, and a service contract(WCF ABC). The endpoint's address is a network address where the endpoint resides. It describes, in a standard-based way, where messages should be sent. Each endpoint normally has one unique address, but sometimes two or more endpoints can share the same address. The endpoint's binding specifies how the endpoint communicates with the world, including things such as transport protocol (TCP, HTTP), encoding (text, binary), and security requirements (SSL, SOAP message security). The endpoint's contract specifies what the endpoint communicates, and is essentially a collection of messages organized in the operations that have basic Message Exchange Patterns (MEPs) such as one-way, duplex, or request/reply. The following diagram shows the components of a WCF service endpoint. Behavior A WCF behavior is a type, or settings to extend the functionality of the original type. There are many types of behaviors in WCF, such as service behavior, binding behavior, contract behavior, security behavior and channel behavior. For example, a new service behavior can be defined to specify the transaction timeout of the service, the maximum concurrent instances of the service, and whether the service publishes metadata. Behaviors are configured in the WCF service configuration file. Hosting A WCF service is a component that can be called by other applications. It must be hosted in an environment in order to be discovered and used by others. The WCF host is an application that controls the lifetime of the service. With .NET 3.0 and beyond, there are several ways to host the service. Self hosting A WCF service can be self-hosted, which means that the service runs as a standalone application and controls its own lifetime. This is the most flexible and easiest way of hosting a WCF service, but its availability and features are limited. Windows services hosting A WCF service can also be hosted as a Windows service. A Windows service is a process managed by the operating system and it is automatically started when Windows is started (if it is configured to do so). However, it lacks some critical features (such as versioning) for WCF services. IIS hosting A better way of hosting a WCF service is to use IIS. This is the traditional way of hosting a web service. IIS, by nature, has many useful features, such as process recycling, idle shutdown, process health monitoring, message-based activation, high availability, easy manageability, versioning, and deployment scenarios. All of these features are required for enterprise-level WCF services. Windows Activation Services hosting The IIS hosting method, however, comes with several limitations in the service-orientation world; the dependency on HTTP is the main culprit. With IIS hosting, many of WCF's flexible options can't be utilized. This is the reason why Microsoft specifically developed a new method, called Windows Activation Services, to host WCF services. Windows Process Activation Service (WAS) is the new process activation mechanism for Windows Server 2008 that is also available on Windows Vista. It retains the familiar IIS 6.0 process model (application pools and message-based process activation) and hosting features (such as rapid failure protection, health monitoring, and recycling), but it removes the dependency on HTTP from the activation architecture. IIS 7.0 uses WAS to accomplish message-based activation over HTTP. Additional WCF components also plug into WAS to provide message-based activation over the other protocols that WCF supports, such as TCP, MSMQ, and named pipes. This allows applications that use the non-HTTP communication protocols to use the IIS features such as process recycling, rapid fail protection, and the common configuration systems that were only available to HTTP-based applications. This hosting option requires that WAS be properly configured, but it does not require you to write any hosting code as part of the application. [Microsoft MSN, Hosting Services, retrieved on 3/6/2008 from http://msdn2.microsoft.com/en-us/library/ms730158.aspx] Channels As we have seen in the previous sections, a WCF service has to be hosted in an application on the server side. On the client side, the client applications have to specify the bindings to connect to the WCF services. The binding elements are interfaces, and they have to be implemented in concrete classes. The concrete implementation of a binding element is called a channel. The binding represents the configuration, and the channel is the implementation associated with that configuration. Therefore, there is a channel associated with each binding element. Channels stack on top of one another to create the concrete implementation of the binding—the channel stack. The WCF channel stack is a layered communication stack with one or more channels that process messages. At the bottom of the stack is a transport channel that is responsible for adapting the channel stack to the underlying transport (for example, TCP, HTTP, SMTP and other types of transport). Channels provide a low-level programming model for sending and receiving messages. This programming model relies on several interfaces and other types collectively known as the WCF channel model. The following diagram shows a simple channel stack: Metadata The metadata of a service describes the characteristics of the service that an external entity needs to understand in order to communicate with the service. Metadata can be consumed by the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate a WCF client and the accompanying configuration that a client application can use to interact with the service. The metadata exposed by the service includes XML schema documents, which define the data contract of the service, and WSDL documents, which describe the methods of the service. Though WCF services will always have metadata, it is possible to hide the metadata from outsiders. If you do so, you have to pass the metadata to the client side by other means. This practice is not common, but it gives your services an extra layer of security. When enabled via the configuration settings through metadata behavior, metadata for the service can be retrieved by inspecting the service and its endpoints. The following configuration setting in a WCF service configuration file will enable the metadata publishing for HTTP transport protocol: <serviceMetadata httpGetEnabled="true" />
Read more
  • 0
  • 0
  • 2350

article-image-jboss-portals-and-ajax-part-2
Packt
16 Oct 2009
7 min read
Save for later

JBoss Portals and AJAX - Part 2

Packt
16 Oct 2009
7 min read
AJAX support for markup Special tags are added to layout JSPs that facilitate the placement of AJAX features on a page. Similarly, renderers are used to interpret the tags and to render AJAX-driven content. The obvious advantage is the in-built support for the auto-creation and control of AJAX components on portal pages. Layout markup Layouts provide a structure for the creation and serving of portal pages. Layouts aggregate all of the content generated by the portlet, based on region and order, merge them with some additional content provided by the portal, and serve a response back to the user. By providing support for AJAX in the layout, helps facilitate the easy development and implementation of dynamic functionality in pages, with minimal effort. Layout markup is implemented using JSP tags. The JBoss JSP tag library, portlet-layout.tld, offers tags that facilitate the implementation of AJAX features in layouts. A JSP layout can be changed to an AJAX-supported page simply by adding references to the tags. Hence, using tags also helps with the easy implementation of features. The following is the layout page from the default portal generic layout ${JBOSS_PORTAL_HOME}serverdefaultdeployjboss-portal.sarportal-core.warlayoutsgenericindex.jsp, and shows AJAX support implemented as tags: <%@ page import="org.jboss.portal.server.PortalConstants" %><%@ taglib uri="/WEB-INF/theme/portal-layout.tld" prefix="p" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head> <title><%= PortalConstants.VERSION.toString() %></title> <meta http-equiv="Content-Type" content="text/html;"/> <!-- to correct the unsightly Flash of Unstyled Content. --> <script type="text/javascript"></script> <!-- inject the theme, default to the Renaissance theme if nothing is selected for the portal or the page --> <p:theme themeName="renaissance"/> <!-- insert header content that was possibly set by portlets on the page --> <p:headerContent/> <%@include file="/layouts/common/modal_head.jsp"%></head><body id="body"><p:region regionName='AJAXScripts' regionID='AJAXScripts'/><%@include file="/layouts/common/modal_body.jsp"%><div id="portal-container"> <div id="sizer"> <div id="expander"> <div id="logoName"></div> <table border="0" cellpadding="0" cellspacing="0" id="header-container"> <tr> <td align="center" valign="top" id="header"> <!-- Utility controls --> <p:region regionName='dashboardnav' regionID='dashboardnav'/> <!-- navigation tabs and such --> <p:region regionName='navigation' regionID='navigation'/> <div id="spacer"></div> </td> </tr> </table> <div id="content-container"> <!-- insert the content of the 'left' region of the page, and assign the css selector id 'regionA' --> <p:region regionName='left' regionID='regionA'/> <!-- insert the content of the 'center' region of the page, and assign the css selector id 'regionB' --> <p:region regionName='center' regionID='regionB'/> <hr class="cleaner"/> </div> </div> </div></div><div id="footer-container" class="portal-copyright">Powered by <a class="portal-copyright" href="http://www.jboss.com/products/jbossportal">JBoss Portal</a><br/></div><p:region regionName='AJAXFooter' regionID='AJAXFooter'/></body></html> Renderer markup The portal combines the renderers and layouts to generate the final content. Enabling support for AJAX in the renderer just requires adding the statement <ajax-enabled>true</ajax-enabled> to the renderer descriptor. The following example, at {JBOSS_PORTAL_HOME}serverdefaultdeployjbossportal.sarportal-core.warWEB-INFlayoutportal-renderSet.xml, shows the renderer configuration of the emptyRenderer RenderSet for AJAX support: <renderSet name="emptyRenderer"> <set content-type="text/html"> <ajax-enabled>true</ajax-enabled> <region-renderer> org.jboss.portal.theme.impl.render.empty.EmptyRegionRenderer </region-renderer> <window-renderer> org.jboss.portal.theme.impl.render.empty.EmptyWindowRenderer </window-renderer> <portlet-renderer> org.jboss.portal.theme.impl.render.empty.EmptyPortletRenderer </portlet-renderer> <decoration-renderer> org.jboss.portal.theme.impl.render.empty.EmptyDecorationRenderer </decoration-renderer> </set></renderSet> AJAX support for content Whereas the layout and renderer contribute to AJAX behavior at the markup level, JBoss portal's support for object-level configuration can be leveraged to provide AJAX support at the page level. The object property inherits a configured behavior from its parent. Currently, two features are offered for AJAX-driven content: Drag and drop: Facilitates easy movement of portlets to various locations on screen using the mouse. Screen Refresh: Allows sub-components of pages or individual portlets to refresh themselves without refreshing the entire page. Drag-and-Drop As the name suggests, this feature is triggered by a user action, and allows a portlet to detach itself from a specific location on the page and move to a different location on the page. This allows for the customization of the user interface to a form that is most convenient to the user. The dynamic view behavior comes from a combination of DHTML and asynchronous server-side communication. Due to the nature of the behavior, drag-and-drop capability is available and effective only in dashboard pages where there are multiple portlets and the page layout can be personalized. The feature is allowed by default on the dashboard, but can be turned off by setting the value in the configuration file to false. The following is a snippet of the default object configuration file ( jboss-portal.sar/conf/data/default-object.xml ), which illustrates the enabling of the feature. Please note that this can also be configured using the administration console user interface of the JBoss server. <deployment> <if-exists>keep</if-exists> <context> <context-name>dashboard</context-name> <properties> ... <!-- Set the dnd property --> <property> <name>theme.dyna.dnd_enabled</name> <value>true</value> </property> ... </properties> </context></deployment> <name>theme.dyna.dnd_enabled</name> value enables or disables the drag-and-drop behavior. Partial content refresh One of the most expensive processes in a portal is the refresh of portlets when the page is generated. For every user action on a page, the portal calls all of the portlet methods in a serial, but non-specific order, which involves a significant amount of time and server-side processing. Partial content refresh support mitigates these issues to a large extent with an effective use of client-server asynchronous communication. When the state of a single portlet changes, a partial content refresh facilitates the update and refresh of only that portlet, instead of for all of the portlets on the page. This prevents the regeneration of the whole page and the initialization of all of the portlets on the page. The following image illustrates the partial content refresh flow:   The partial refresh capability is compatible with the JSR-168 portlet API, which allows for programmatic update of portlet states during runtime. Partial refreshes can be enabled through portal object configuration or through configuration at the default server level.
Read more
  • 0
  • 0
  • 2066

article-image-maintaining-optimizing-and-upgrading-your-site-drupal-6-part-2
Packt
16 Oct 2009
9 min read
Save for later

Maintaining, Optimizing and Upgrading Your Site in Drupal 6: Part 2

Packt
16 Oct 2009
9 min read
Maintaining content As you continue to add content to your web site, you will need to ensure that your content is properly moderated, that old content is removed, and that changes to web site content are tracked. Creating content revisions Good Eatin' Goal: Create revisions of content to ensure that you have a complete record of changes to your web site's content. Additional modules needed: None. Basic steps We have simply updated our pages as necessary to add new functionality and content. However, if you have many editors, content that changes frequently, a need to view the history of a page, or need the ability to easily return to an old version of a page, you will want to store multiple revisions of your pages. To do this, carry out the following steps: Edit the content for which you want to create a new revision. Make the changes as needed and, before saving, expand the Revision information section. Select the Create new revision option and enter a message describing the changes that you have made to the node. When you save the content, you will see a new tab called Revisions. Clicking on this tab will show you a list of all of the revisions that have been created for the page. If you would like to return to an older version of the page, you can click the revert link. Or, if you want to remove an older revision, you can click the delete link to get rid of it permanently. You can control which users have access to the revision system by using the Permissions Manager. Drupal allows you to control which users can: view revisions, revert revisions, and delete revisions. If you want to force users to always create new revisions when editing content, edit the content type and then expand the Workflow settings. Change the default options to select the Create new revision option. When editors change content, the Create new revision option will be selected by default, and they will not be able to change the option unless they have the administer nodes permission. If you want to approve all revisions before publication, you can deselect the Published checkbox. Comparing content revisions Good Eatin' Goal: Compare the text of two different revisions of a page. Additional modules needed: Diff (http://drupal.org/project/diff). Basic steps Although the built-in functionality for creating revisions in Drupal works perfectly well, it can be difficult to review the changes that were made in each revision. The Diff module makes comparing revisions very easy. Begin by installing and activating the Diff module. To use the Diff module, simply view the revisions for any page. You will notice that the Revisions list has changed to allow you to select the revisions to be compared. Select the revisions to compare and then click on the Show diff button. Drupal will then display information about the text that has been changed, added, or deleted. Moderate content Good Eatin' Goal: Find questionable or offensive content, and remove it from your site, easily. Additional modules needed: Modr8 (http://drupal.org/project/modr8). Basic steps An unfortunate side effect of having a web site on the Internet is that, at some point, a malicious user will attempt to post inappropriate content on your site. If your site is extremely busy, you may find yourself with a large amount of content to review and approve. The Modr8 module can help you manage the workload and can send emails to users letting them know when their content has been approved or rejected. Begin by installing and activating the Modr8 module. The settings for the Modr8 module can be accessed by selecting Site configuration and then Modr8, from the Administer menu. The basic settings control how often logs are removed. Alternatively, you can choose to keep the logs forever. You can also change the number of items in the moderation queue to be displayed at a time, as well as the default action for the content that requires moderation. You can also configure the email settings for the moderation queue, including the text of the emails, and whether or not emails should be sent to the user who posted the content when their content is approved and/or when their content is rejected. You can also choose to send an email if the moderator does not take action for the item and wants to send a note to the author. If you would like new content to be added to the moderation queue automatically, you can edit the content type and select the In moderation queue setting in the workflow section. To view the moderation queue, select Content management and then Moderated content, from the Administer menu. The moderation queue appears as follows: From this page, you can approve, delete, or defer action on any content that needs moderation. After you make your changes, click Save to complete your selections. You can also display a log of all the moderation actions, by clicking on Reports and then Content moderation log. The moderation log appears as follows: Allowing users to report questionable or offensive content. Good Eatin' Goal: Get feedback from users to learn what they find offensive so the objectionable content can be removed. Additional modules needed: Abuse (http://drupal.org/project/abuse). Basic steps In the last task, we reviewed methods that allowed you to moderate every piece of content that is added to the site. However, this can be a time-intensive task if the proportion of content that you receive that is questionable is low. If this is the case, you can allow your users to help you to moderate the content by using the Abuse module, to let them report items that they find offensive. This strategy has a couple of advantages. Firstly, you are freed from the maintenance of pre-approving all content before it is published. Secondly, it ensures that the content meets community standards, rather than placing you or your editors in charge of defining community standards. The Abuse module also has a Watchlist component that allows you to flag content as suspicious or banned, and automatically move them into a queue for review by an administrator. Begin by downloading and installing the Abuse and Watchlist modules, both of which are included in the Abuse installation. We will begin by editing the Watchlist settings, which can be accessed by selecting Site configuration and then Watchlist settings, from the Administer menu. You can include any words that you want to, in the Watch list and Filtered/banned word list, depending on your target audience and your site's needs; just make sure that you enter one word per line. Items on the Watch list can be viewed while they are in the review queue, and items on the Filtered/banned word list will be hidden until they are reviewed. You can also control which items are automatically added to the Watch list or banned list, based on the Watchlist word settings configured above. You can also force moderation for specific types if they are more prone to abuse. We can now modify the Abuse Moderation settings by selecting Site configuration and then Abuse Moderation settings, from the Administer menu. The first setting controls what content types are subject to abuse reports. The next section of controls how abuse tickets are to be handled by your moderators. If you have multiple moderators for your site, you can select the Abuse Assigned Moderators option. If you use this, you will also need to store the maximum number of items that have been flagged for abuse that are added to the moderator's queue. If moderators live in different time zones, you can set an hour of the day at which all moderation queues are cleared, so that items do not remain in the moderation queue for an overly-long period of time. Finally, you can configure the settings related to all of the items that have been flagged as abusive by a user. The Abuse threshold controls how many complaints must be registered for an item before it is moved into the moderation queue. 3 is a good number to start with, but you may want to increase or decrease the threshold depending on the needs of your site. You can edit the reasons for flagging an item for abuse by selecting Site configuration, then Abuse Moderation settings, and finally Abuse Moderation reasons, from the Administer menu. All available reasons will be listed on the page using a format similar to the example above. You can add new reasons, remove reasons, or change the text for reasons from this page. Before the abuse module is activated, you need to assign permissions to users, so that they can flag content for review. Content that has the abuse module activated will have a new Flag as offensive link added to it, as shown in the following screenshot: When the user clicks on the Flag as offensive link, he or she will be presented with a form where he or she can specify their contact information, and a reason why he or she believes that the content is offensive. Administrators can review content that has been flagged as offensive by clicking on Content management and then Moderate. The administrators can click on the Get More Tickets link to have additional items assigned to them. Once a ticket has been assigned to them, the administrator can view information about the user who submitted the content as well as the user who flagged the content, and choose what action to take for the content. The administrator can either allow the content, or remove the content from the web site. The administrator can also optionally send a warning to the user without further action.
Read more
  • 0
  • 0
  • 1795

article-image-primer-agi-asterisk-gateway-interface
Packt
16 Oct 2009
2 min read
Save for later

A Primer to AGI: Asterisk Gateway Interface

Packt
16 Oct 2009
2 min read
How does AGI work Let's examine the following diagram: As the previous diagram illustrates, an AGI script communicates with Asterisk via two standard data streams—STDIN (Standard Input) and STDOUT (Standard Output). From the AGI script point-of-view, any input coming in from Asterisk would be considered STDIN, while output to Asterisk would be considered as STDOUT. The idea of using STDIN/STDOUT data streams with applications isn't a new one, even if you're a junior level programmer. Think of it as regarding any input from Asterisk with a read directive and outputting to Asterisk with a print or echo directive. When thinking about it in such a simplistic manner, it is clear that AGI scripts can be written in any scripting or programming language, ranging from BASH scripting, through PERL/PHP scripting, to even writing C/C++ programs to perform the same task. Let's now examine how an AGI script is invoked from within the Asterisk dialplan: exten => _X.,1,AGI(some_script_name.agi,param1,param2,param3) As you can see, the invocation is similar to the invocation of any other Asterisk dialplan application. However, there is one major difference between a regular dialplan application and an AGI script—the resources an AGI script consumes.While an internal application consumes a well-known set of resources from Asterisk, an AGI script simply hands over the control to an external process. Thus, the resources required to execute the external AGI script are now unknown, while at the same time, Asterisk consumes the resources for managing the execution of the AGI script.Ok, so BASH isn't much of a resource hog, but what about Java? This means that the choice of programming language for your AGI scripts is important. Choosing the wrong programming language can often lead to slow systems and in most cases, non-operational systems. While one may argue that the underlying programming language has a direct impact on the performance of your AGI application, it is imperative to learn the impact of each. To be more exact, it's not the language itself, but more the technology of the programming language runtime that is important. The following table tries to distinguish between three programming languages' families and their applicability to AGI development.
Read more
  • 0
  • 0
  • 6544

article-image-oracle-wallet-manager
Packt
16 Oct 2009
9 min read
Save for later

Oracle Wallet Manager

Packt
16 Oct 2009
9 min read
  The Oracle Wallet Manager Oracle Wallet Manager is a password protected stand-alone Java application tool used to maintain security credentials and store SSL related information such as authentication and signing credentials, private keys, certificates, and trusted certificates. OWM uses Public Key Cryptographic Standards (PKCS) #12 specification for the Wallet format and PKCS #10 for certificate requests. Oracle Wallet Manager stores X.509 v3 certificates and private keys in industry-standard PKCS #12 formats, and generates certificate requests according to the PKCS #10 specification. This makes the Oracle Wallet structure interoperable with supported third party PKI applications, and provides Wallet portability across operating systems. Additionally, Oracle Wallet Manager Wallets can be enabled to store credentials on hardware security modules that use APIs compliant with the PKCS #11 specification. The OWM creates Wallets, generates certificate requests, accesses Public Key interface-based services, saves credentials into cryptographic hardware such as smart cards, uploads and unloads Wallets to LDAP directories, and imports Wallets in PKCS #12 format. In a Windows environment, Oracle Wallet Manager can be accessed from the start menu. The following screenshot shows the Oracle Wallet Manager Properties: In a Unix like environment, OWM can be accessed directly from the command line with the owm shell script located at $ORACLE_HOME/bin/owm, it requires a graphical environment so it can be launched. Creating the Oracle Wallet If this is the first time the Wallet has been opened, then a Wallet file does not yet exist. A Wallet is physically created in a specified directory. The user can declare the path where the Oracle Wallet file should be created. The user may either specify a default location or declare a particular directory. A file named ewallet.p12 will be created in the specified location. Enabling Auto Login The Oracle Wallet Manager Auto Login feature creates an obfuscated copy of the Wallet and enables PKI-based access to the services without a password. When this feature is enabled, only the user who created the Wallet will have access to it. By default, Single Sign-On (SSO) access to a different database is disabled. The auto login feature must be enabled in order for you to have access to multiple databases using SSO. Checking and unchecking the Auto Login option will enable and disable this feature. mkwallet, the CLI OWM version Besides the Java client, there is a command line interface version of the Wallet, which can be accessed by means of the mkwallet utility. This can also be used to generate a Wallet and have it configured in Auto Login mode. This is a fully featured tool that allows you to create Wallets, and to view and modify their content. The options provided by the mkwallet tool are shown in the following table:     Option Meaning -R rootPwd rootWrl DN keySize expDate Create the root Wallet -e pwd wrl Create an empty Wallet -r pwd wrl DN keySize certReqLoc Create a certificate request, add it to Wallet and export it to certReqLoc -c rootPwd rootWrl certReqLoc certLoc Create a certificate for a certificate request -i pwd wrl certLoc NZDST_CERTIFICATE | NZDST_CLEAR_PTP Install a certificate | trusted point -d pwd wrl DN Delete a certificate with matching DN -s pwd wrl Store sso Wallet -p pwd wrl Dump the content of Wallet -q certLoc Dump the content of the certificate -Lg pwd wrl crlLoc nextUpdate Generate CRL -La pwd wrl crlLoc certtoRevoke Revoke certificate -Ld crlLoc Display CRL -Lv crlLoc cacert Verify CRL signature -Ls crlLoc cert Check certificate revocation status -Ll oidHostname oidPortNumber cacert Fetch CRL from LDAP directory -Lc cert Fetch CRL from CRLDP in cert -Lb b64CrlLoc derCrlLoc Convert CRL from B64 to DER format -Pw pwd wrl pkcs11Lib tokenPassphrase Create an empty Wallet. Store PKCS11 info in it. -Pq pwd wrl DN keysize certreqLoc Create cert request. Generate key pair on pkcs11 device. -Pl pwd wrl Test pkcs11 device login using Wallet containing PKCS11 info. -Px pwd wrl pkcs11Lib tokenPassphrase Create a Wallet with pkcs11 info from a software Wallet.   Managing Wallets with orapki A CLI-based tool, orapki, is used to manage Public Key Infrastructure components such as Wallets and revocation lists. This tool eases the procedures related to PKI management and maintenance by allowing the user to include it in batch scripts. This tool can be used to create and view signed certificates for testing purposes, create Oracle Wallets, add and remove certificate and certificate requests, and manage Certification Revocation Lists (CRLs)—renaming them and managing them against the Oracle Internet Directory. The syntax for this tool is: orapki module command -parameter <value> module can have these values: wallet: Oracle Wallet crl: Certificate Revocation List cert: The PKI Certificate To create a Wallet you can issue this command: orapki wallet create -wallet <Path to Wallet> To create a Wallet with the auto login feature enabled, you can issue the command: orapki wallet create -wallet <Path to Wallet> -autologin To add a certificate request to the Wallet you can use the command: orapki wallet add -wallet <wallet_location> -dn <user_dn> -keySize <512|1024|2048> To add a user certificate to an Oracle Wallet: orapki wallet add -wallet <wallet_location> -user_cert -cert <certificate_location> The options and values available for the orapki tool depend on the module to be configured: orapki Action Description and Syntax orapki cert create Creates a signed certificate for testing purposes. orapki cert create [-wallet <wallet_location>] -request <certificate_request_location> -cert <certificate_location> -validity <number_of_days> [-summary] orapki cert display Displays details of a specific certificate. orapki cert display -cert <certificate_location> [-summary|-complete] orapki crl delete Deletes CRLs from Oracle Internet Directory.   orapki crl delete -issuer <issuer_name> -ldap <hostname: ssl_port> -user <username> [-wallet <wallet_location>] [-summary] orapki crl diskplay Displays specific CRLs that are stored in Oracle Internet Directory. orapki crl display -crl <crl_location> [-wallet <wallet_location>] [-summary|-complete] orapki crl hash Generates a hash value of the certificate revocation list (CRL) issuer to identify the location of the CRL in your file system for certificate validation. orapki crl hash -crl <crl_filename|URL> [-wallet <wallet_location>] [-symlink|-copy] <crl_directory> [-summary] orapki crl list Displays a list of CRLs stored in Oracle Internet Directory. orapki crl list -ldap <hostname:ssl_port> orapki crl upload Uploads CRLs to the CRL subtree in Oracle Internet Directory. orapki crl upload -crl <crl_location> -ldap <hostname:ssl_port> -user <username> [-wallet <wallet_location>] [-summary] orapki wallet add Add certificate requests and certificates to an Oracle Wallet. orapki wallet add -wallet <wallet_location> -dn <user_dn> -keySize <512|1024|2048> orapki wallet create Creates an Oracle Wallet or to set auto login on for an Oracle Wallet. orapki wallet create -wallet <wallet_location> [-auto_login] orapki wallet display Displays the certificate requests, user certificates, and trusted certificates in an Oracle Wallet. orapki wallet display -wallet <wallet_location> orapki wallet export Export certificate requests and certificates from an Oracle Wallet. orapki wallet export -wallet <wallet_location> -dn <certificate_dn> -cert <certificate_filename>   Oracle Wallet Manager CSR generation Oracle Wallet Manager generates a certificate request in PKCS #10 format. This certificate request can be sent to a certificate authority of your choice. The procedure to generate this certificate request is as follows: From the main menu choose the Operations menu and then select the Add Certificate Request submenu. As shown in the following screenshot, a form will be displayed where you can capture specific information. The parameters used to request a certificate are described next: Common Name: This parameter is mandatory. This is the user's name or entity's name. If you are using a user's name, then enter it using the first name, last name format. Organization Unit: This is the name of the identity's organization unit. It could be the name of the department where the entity belongs (optional parameter). Organization: This is the company's name (optional). Location/City: The location and the city where the entity resides (optional). State/Province: This is the full name of the state where the entity resides. Do not use abbreviations (optional). Country: This parameter is mandatory. It specifies the country where the entity is located. Key Size: This parameter is mandatory. It defines the key size used when a public/private key pair is created. The key size can be as little as 512 bytes and up to 4096 bytes. Advanced: When the parameters are introduced a Distinguished Name (DN) is assembled. If you want to customize this DN, then you can use the advanced DN configuration mode. Once the Certificate Request form has been completed, a PKCS#10 format certificate request is generated. The information that appears between the BEGIN and END keywords must be used to request a certificate to a Certificate Authority (CA); there are several well known certificate authorities, and depending on the usage you plan for your certificate, you could address the request to a known CA (from the browser perspective) so when an end user accesses your site it doesn't get warned about the site's identity. If the certificate will be targeted at a local community who doesn't mind about the certificate warning, then you may generate your own certificate or ask a CA to issue a certificate for you. For demonstration purposes, we used the Oracle Certificate Authority (OCA) included with the Oracle Application Server. OCA will provide the Certificate Authority capabilities to your site and it can issue standard certificates, suitable for the intranet users. If you are planning to use OCA then you should review the license agreements to determine if you are allowed to use it.  
Read more
  • 0
  • 0
  • 7656
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-building-facebook-application-part-2
Packt
16 Oct 2009
11 min read
Save for later

Building a Facebook Application: Part 2

Packt
16 Oct 2009
11 min read
Mock AJAX and your Facebook profile I'm sure that you've heard of AJAX (Asynchronous JavaScript and XML) with which you can build interactive web pages. Well, Facebook has Mock AJAX, and with this you can create interactive elements within a profile page. Mock AJAX has three attributes that you need to be aware of: clickwriteform: The form to be used to process any data. clickwriteid: The id of a component to be used to display our data. clickwriteurl: The URL of the application that will process the data. When using Mock AJAX, our application must do two things: Return the output of any processed data (and we can do that by using either echo or print). Define a form with which we'll enter any data, and a div to receive the processed data Using a form on your profile Since we want to make our application more interactive, one simple way is to add a form. So, for our first example we can add a function (or in this case a set of functions) to appinclude.php that will create a form containing a simple combo-box: function country_combo () {/*You use this function to display a combo-box containing a list of countries. It's in its own function so that we can use it in other forms without having to add any extra code*/$country_combo = <<<EndOfText<select name=sel_country><option>England</option><option>India</option></select>EndOfText;return $country_combo;}function country_form () {/*Like country_combo-box we can use this form where ever needed because we've encapsulated it in its own function */global $appcallbackurl;$country_form = "<form>";$country_form .= country_combo ();$country_form .= <<<EndOfText<input type="submit" clickrewriteurl="$appcallbackurl" clickrewriteid="info_display" value="View Country"/><div id="info_display" style="border-style: solid; border-color: black; border-width: 1px; padding: 5px;">No country selected</div></form>EndOfText;return $country_form;}function display_simple_form () {/*This function displays the country form with a nice subtitle (on the Profile page)*/global $facebook, $_REQUEST;#Return any processed dataif (isset($_REQUEST['sel_country'])) { echo $_REQUEST['sel_country'] . " selected"; exit;}#Define the form and the div$fbml_text = <<<EndOfText<fb:subtitle><fb:name useyou=false uid=$user firstnameonly=true possessive=true> </fb:name> Suspect List</fb:subtitle>EndOfText;$fbml_text .= country_form ();$facebook->api_client->profile_setFBML($fbml_text, $user);echo $fbml_text;} And, of course, you'll need to edit index.php: display_simple_form (); You'll notice from the code that we need to create a div with the id info_display, and that this is what we use for the clickrewriteid of the submit button. You'll also notice that we're using $appcallbackurl for the clickrewriteurl ($appcallbackurl is defined in appinclude.php). Now, it's just a matter of viewing the new FMBL (by clicking on the application URL in the left-navigation panel): If you select a country, and then click on View Country, you'll see: I'm sure that you can see where we're going with this. The next stage is to incorporate this form into our Suspect Tracker application. And the great thing now is that because of the functions that we've already added to appinclude.php, this is now a very easy job: function first_suspect_tracker () {global $facebook, $_REQUEST;if (isset($_REQUEST['sel_country'])) { $friend_details = get_friends_details_ by_country ($_REQUEST['sel_country']); foreach ($friend_details as $friend) { $div_text .= "<fb:name uid=" . $friend['uid'] . " firstnameonly=false></fb:name>, "; } echo $div_text; exit;}$fbml_text .= country_form ();$facebook->api_client->profile_setFBML($fbml_text, $user);$facebook->redirect($facebook->get_facebook_url() . '/profile.php');} You may also want to change the country_form function, so that the submit button reads View Suspects. And, of course, we'll also need to update index.php. Just to call our new function: <?phprequire_once 'appinclude.php';first_suspect_tracker ();?> This time, we'll see the list of friends in the selected country: or: OK, I know what you're thinking, this is fine if all of your friends are in England and India, but what if they're not? And you don't want to enter the list of countries manually, do you? And what happens if someone from a country not in the list becomes your friend? Obviously, the answer to all of these questions is to create the combo-box dynamically. Creating a dynamic combo-box I'm sure that from what we've done so far, you can work out how to extract a list of countries from Facebook: function country_list_sql () {/*We're going to be using this piece of SQL quite often so it deserves its own function*/global $user;$country_list_sql = <<<EndSQLSELECT hometown_location.countryFROM userWHERE uid IN (SELECT uid1FROM friendWHERE uid2=$user)EndSQL;return $country_list_sql;}function full_country_list () {/*With the SQL in a separate function this one is very short and simple*/global $facebook;$sql = country_list_sql ();$full_country_list = $facebook-> api_client->fql_query($sql);print_r ($full_country_list);} However, from the output, you can see that there's a problem with the data: If you look through the contents of the array, you'll notice that some of the countries are listed more than once—you can see this even more clearly if we simulate building the combo-box: function options_country_list () {global $facebook;$sql = country_list_sql ();$country_list = $facebook->api_client->fql_query($sql);foreach ($country_list as $country){ echo "option:" . $country['hometown_location']['country'] ."<br>";}} From which, we'd get the output: This is obviously not what we want in the combo-box. Fortunately, we can solve the problem by making use of the array_unique method, and we can also order the list by using the sort function: function filtered_country_list () {global $facebook;$sql = country_list_sql ();$country_list = $facebook->api_client->fql_query($sql);$combo_full = array();foreach ($country_list as $country){ array_push($combo_full, $country['hometown_location']['country']);}$combo_list = array_unique($combo_full);sort($combo_list);foreach ($combo_list as $combo){ echo "option:" . $combo ."<br>";}} And now, we can produce a usable combo-box: Once we've added our code to include the dynamic combo-box, we've got the workings for a complete application, and all we have to do is update the country_combo function: function country_combo () {/*The function now produces a combo-box derived from the friends' countries */global $facebook;$country_combo = "<select name=sel_country>";$sql = country_list_sql ();$country_list = $facebook->api_client->fql_query($sql);$combo_full = array();foreach ($country_list as $country){ array_push($combo_full, $country['hometown_location']['country']);}$combo_list = array_unique($combo_full);sort($combo_list);foreach ($combo_list as $combo){ $country_combo .= "<option>" . $combo ."</option>";}$country_combo .= "</select>";return $country_combo;} Of course, you'll need to reload the application via the left-hand navigation panel for the result: Limiting access to the form You may have spotted a little fly in the ointment at this point. Anyone who can view your profile will also be able to access your form and you may not want that (if they want a form of their own they should install the application!). However, FBML has a number of if (then) else statements, and one of them is <fb:if-is-own-profile>: <?phprequire_once 'appinclude.php';$fbml_text = <<<EndOfText<fb:if-is-own-profile>Hi <fb:name useyou=false uid=$user firstnameonly=true></fb:name>, welcome to your Facebook Profile page.<fb:else>Sorry, but this is not your Facebook Profile page - it belongs to <fb:name useyou=false uid=$user firstnameonly=false> </fb:name>,</fb:else></fb:if-is-own-profile>EndOfText;$facebook->api_client->profile_setFBML($fbml_text, $user);echo "Profile updated";?> So, in this example, if you were logged on to Facebook, you'd see the following on your profile page: But anyone else viewing your profile page would see: And remember that the FBML is cached when you run: $facebook->api_client->profile_setFBML($fbml_text, $user); Also, don't forget, it is not dynamic that is it's not run every time that you view your profile page. You couldn't, for example, produce the following for a user called Fred Bloggs: Sorry Fred, but this is not Your Facebook Profile page - it belongs to Mark Bain That said, you are now able to alter what's seen on the screen, according to who is logged on. Storing data—keeping files on your server From what we've looked at so far, you already know that you not only have, but need, files stored on your server (the API libraries and your application files). However, there are other instances when it is useful to store files there. Storing FBML on your server In all of the examples that we've worked on so far, you've seen how to use FBML mixed into your code. However, you may be wondering if it's possible to separate the two. After all, much of the FBML is static—the only reason that we include it in the code is so that we can produce an output. As well as there may be times when you want to change the FBML, but you don't want to have to change your code every time you do that (working on the principle that the more times you edit the code the more opportunity there is to mess it up). And, of course, there is a simple solution. Let's look at a typical form: <form><div id="info_display" style="border-style: solid; border-color: black; border-width: 1px; padding: 5px;"></div><input name=input_text><input type="submit" clickrewriteurl="http://213.123.183.16/f8/penguin_pi/" clickrewriteid="info_display" value="Write Result"></form> Rather than enclosing this in $fbml_text = <<<EndOfText ... EndOfText; as we have done before, you can save the FBML into a file on your server, in a subdirectory of your application. For example /www/htdocs/f8/penguin_pi/fbml/form_input_text.fbml. "Aha" I hear your say, "won't this invalidate the caching of FBML, and cause Facebook to access my server more often than it needs?" Well, no, it won't. It's just that we need to tell Facebook to update the cache from our FBML file. So, first we need to inform FBML that some external text needs to be included, by making use of the <fb:ref> tag, and then we need to tell Facebook to update the cache by using the fbml_refreshRefUrl method: function form_from_server () {global $facebook, $_REQUEST, $appcallbackurl, $user;$fbml_file = $appcallbackurl . "fbml/form_input_text.fbml";if (isset($_REQUEST['input_text'])) { echo $_REQUEST['input_text']; exit;}$fbml_text .= "<fb:ref url='" . $fbml_file . "' />";$facebook->api_client->profile_setFBML($fbml_text, $user);$facebook->api_client->fbml_refreshRefUrl($fbml_file);echo $fbml_text;} As far as your users are concerned, there is no difference. They'll just see another form on their profile page: Even if your users don't appreciate this leap forward, it will make a big difference to your coding—you're now able to isolate any static FBML from your PHP (if you want). And now, we can turn our attention to one of the key advantages of having your own server—your data. Storing data on your server So far, we've concentrated on how to extract data from Facebook and display it on the profile page. You've seen, for example, how to list all of your friends from a given country. However, that's not how Pygoscelis' list would work in reality. In reality, you should be able to select one of your friends and add them to your suspect list. We will, therefore, spend just a little time on looking at creating and using our own data. We're going to be saving our data in files, and so your first job must be to create a directory in which to save those files. Your new directory needs to be a subdirectory of the one containing your application. So, for example, on my Linux server I would do: cd /www/htdocs/f8/penguin_pi       #Move to the application directory mkdir data #Create a new directory chgrp www-data data                          #Change the group of the directory chmod g+w data                                  #Ensure that the group can write to data
Read more
  • 0
  • 0
  • 2555

article-image-recording-calls-freepbx-25
Packt
16 Oct 2009
2 min read
Save for later

Recording Calls in FreePBX 2.5

Packt
16 Oct 2009
2 min read
Asterisk has a wonderful, built-in ability to record calls. No additional software is required to make this happen. When Asterisk records a call, both sides of the call are recorded and written out to a file for playback on a computer. Call recording is often performed in call centers to ensure call quality, or to keep calls for later review, should the need arise. Asterisk provides the ability to record all of the calls, or to selectively record calls. In this article, we will look the following:   General recording options Recording calls to extensions Recording calls to queues Recording calls to conferences Maintaining call recordings Before enabling call recording for your PBX, make sure that you are aware of the legalities surrounding call recordings and privacy laws. Call recordings are prohibited in certain places, unless the caller is told that the call will be recorded. For example, in the state of California all of the parties on the call must consent to the call being recorded before it begins. Playing back a message stating that the call is being recorded prior to the call being answered is considered a valid form of consent. Recording formats FreePBX allows calls to be recorded in the following formats: WAV WAV49 ULAW ALAW SLN GSM Each format has its own ratio of file size to recording quality, and certain formats will not play on all of the computers. A comparison between all of the  available formats is as follows:
Read more
  • 0
  • 0
  • 3484

article-image-displaying-sql-server-data-using-linq-data-source
Packt
16 Oct 2009
2 min read
Save for later

Displaying SQL Server Data using a Linq Data Source

Packt
16 Oct 2009
2 min read
Create web site project and add LinqDataSource control Open Visual Studio 2008 from its shortcut on the desktop. Click File | New | Web Site...(or Shift+Alt+N) to open the New Web Site window. Change the default name of the site to a name of your choice (herein LinqDemo)on your local web server as shown. Make sure you are creating a .NET Framework 3.5 web site as shown here. Drag and drop a LinqDataSource control from Toolbox|Data shown in the next figure on to the Default.aspx This creates an instance of the control LinqDataSource1 as shown. The figure also shows the smart tasks of this control as shown. Create a data context for the LinqDataSource control In order to use this control you also need to create a data context. Right click the localhost web site and choose Add New Item...to open the Add New Item - http://localhost/ LinqDemo window as shown. In the Visual Studio installed templates highlight Linq to SQL Classes. Change the default name from DataClasses.dbml to a name of your choosing. Herein MyDC.dbml. Click Add. This pops-up a Microsoft Visual Studio warning message as shown. The preferred location for this file is in the App_Code folder of your project as suggested here. Click on Yes. This adds a MyDC.dbml file to APP_Code folder as shown. MyDC.dbml consists of two components MyDC.dbml and MyDC.designer.vb to the App_Code folder as shown . Double click the MyDC.dbml node in the APP_Code folder. This opens the ObjectRelational Designer and the designer surface with two panes as shown. Read the instructions in the windows. In the left pane you can drag and drop items from the Server Explorer in Visual Studio to create the appropriate classes and in the right pane you can drag and drop stored procedures. In this article we will be looking at just creating classes from table objects.
Read more
  • 0
  • 0
  • 3888

article-image-optimizing-lighttpd
Packt
16 Oct 2009
5 min read
Save for later

Optimizing Lighttpd

Packt
16 Oct 2009
5 min read
If our Lighttpd runs on a multi-processor machine, it can take advantage of that by spawning multiple versions of itself. Also, most Lighttpd installations will not have a machine to themselves; therefore, we should not only measure the speed but also its resource usage. Optimizing Compilers: gcc with the usual settings (-O2) already does quite a good job of creating a fast Lighttpd executable. However, -O3 may nudge the speed up a tiny little bit (or slow it down, depending on our system) at the cost of a bigger executable system. If there are optimizing compilers for our platform (for example, Intel and Sun Microsystems each have compilers that optimize for their CPUs), they might even give another tiny speed boost. If we do not want to invest money in commercial compilers, but maximize on what gcc has to offer, we can use Acovea, which is an open source project that employs genetic algorithms and trial-and-error to find the best individual settings for gcc on our platform. Get it from http://www.coyotegulch.com/products/acovea/ Finally, optimization should stop where security (or, to a lesser extent, maintainability) is compromised. A slower web server that does what we want is way better than a fast web server obeying the commands of a script kiddie. Before we optimize away blindly, we better have a way to measure the "speed". A useful measure most administrators will agree with is "served requests per second". http_load is a tool to measure the requests per second. We can get it from http://www.acme.com/software/http_load/. http_load is very simple. Give it a site to request, and it will flood the site with requests, measuring how many are served in a given amount of time. This allows a very simplistic approach to optimizing Lighttpd: Tweak some settings, run http_load with a sufficient realistic scenario, and see if our Lighttpd handles more or less requests than before. We do not yet know where to spend time optimizing. For this, we need to make use of timing log instrumentation that has been included with Lighttpd 1.5.0 or even use a profiler to see where the most time is spent. However, there are some "big knobs" to turn that can increase performance, where http_load will help us find a good setting. Installing http_load http_load can be downloaded as a source .tar file (which was named .tar.gz for me, though it is not gzipped). The version as of this writing is 12Mar2006. Unpack it to /usr/src (or another path by changing the /usr/src) with: $ cd /usr/src && tar xf /path/to/http_load-12Mar2006.tar.gz$ cd http_load-12Mar2006 We can optionally add SSL support. We may skip this if we do not need it. To add SSL support we need to find out where the SSL libs and includes are. I assume they are in /usr/lib and /usr/include, respectively, but they may or may not be the same on your system. Additionally, there is a "SSL tree" directory that is usually in /usr/ssl or /usr/local/ssl and contains certificates, revocation lists, and so on. Open the Makefile with a text editor and look at line 11 to 14, which reads: #SSL_TREE = /usr/local/ssl#SSL_DEFS = -DUSE_SSL#SSL_INC = -I$(SSL_TREE)/include#SSL_LIBS = -L$(SSL_TREE)/lib -lssl -lcrypto Change them to the following (assuming the given directories are correct): SSL_TREE = /usr/sslSSL_DEFS = -DUSE_SSLSSL_INC = -I/usr/includeSSL_LIBS = -L/usr/lib -lssl -lcrypto Now compile and install http_loadwith the following command: $ make all install Now we're all set to load-test our Lighttpd. Running http_load tests We just need a URL file, which contains URLs that lead to the pages our Lighttpd serves. http_load will then fetch these pages at random as long as, or as often as we ask it to. For example, we may have a front page with links to different articles. We can just start putting a link to our front page into the URL file, which we will name urls to get started; for example, http://localhost/index.html. Note that the file just contains URLs, nothing less, nothing more (for example, http_load does not support blank lines). Now we can make our first test run: $ http_load -parallel 10 -seconds 60 urls This will run for one minute and try to open 10 connections per second. Let's see if our Lighttpd keeps up: 343 fetches, 10 max parallel, 26814 bytes, in 60 seconds78.1749 mean bytes/connection5.71667 fetches/sec, 446.9 bytes/secmsecs/connect: 290.847 mean, 9094 max,15 minmsecs/first-response: 181.902 mean, 9016 max, 15 minHTTP response codes: code 200 - 327   As we can see, it does. http_load needs one of the two start conditions and one of the two stop conditions plus a URL file to run. We can create the URL file manually or crawl our document root(s) with the following python script called crawl.py: #!/usr/bin/python#run from document root, pipe into URLs file. For example:# /path/to/docroot$ crawl.py > urlsimport os, re, syshostname = "http://localhost/"for (root, dirs, files) in os.walk("."): for name in files: filepath = os.path.join(root, name) print re.sub("./", hostname, filepath)   You can download the crawl.oy file from http://www.packtpub.com/files/code/2103_Code.zip. Capture the output into a file to use as URL file. For example, start the script from within our document root with: $ python crawl.py > urls This will give us a urls file, which will make http_load try to get all files (given that we have specified enough requests). Then we can start http_load as discussed in the preceding example. http_load takes the following options:  
Read more
  • 0
  • 0
  • 7278
article-image-ajaxdynamic-content-and-interactive-forms-joomla
Packt
16 Oct 2009
13 min read
Save for later

AJAX/Dynamic Content and Interactive Forms in Joomla!

Packt
16 Oct 2009
13 min read
AJAX: an acronym that Jesse James Garret of AdaptivePath.com came up with in 2005. Just a few short years later, it seems like every site has a "taste" of AJAX in it. If you're totally new to AJAX, I'll just point out that, at its core, AJAX is nothing very scary or horrendous. AJAX isn't even a new technology or language. Essentially, AJAX stands for: Asynchronous JavaScript and XML, and it is the technique of using JavaScript and XML to send and receive data between a web browser and a web server. The biggest advantage this technique has is that you can dynamically update a piece of content on your web page or web form with data from the server (preferably formatted in XML), without forcing the entire page to reload. The implementation of this technique has made it obvious to many web developers that they can start making advanced web applications (sometimes called RIAs—Rich Interface Applications) that work and feel more like software applications than web pages. Keep in mind that the word AJAX is starting to have its own meaning (as you'll also note its occasional use here as well as all over the Web as a proper noun rather than an all-cap acronym). For example, a Microsoft web developer may use VBScript instead of JavaScript to serve up Microsoft Access database data that is transformed into JSON (not XML) using a .NET server-side script. Today, that guy's site would still be considered an AJAX site rather than an "AVAJ" site (yep, AJAX just sounds cooler). In fact, it's getting to the point where just about anything on a web site (that isn't in Flash) that slides, moves, fades, or pops up without rendering a new browser window is considered an "Ajaxy" site. In truth, a large portion of these sites don't truly qualify as using AJAX, they're just using straight-up JavaScripting. Generally, if you use cool JavaScripts in your Joomla! site, it will probably be considered Ajaxy, despite not being asynchronous or using any XML. Want more info on this AJAX business? The w3schools site has an excellent introduction to AJAX, explaining it in straightforward simple terms. They even have a couple of great tutorials that are fun and easy to accomplish even if you only have a little HTML, JavaScript and server-side script (PHP or ASP) experience (no XML experience required): http://w3schools.com/ajax/. Preparing for dynamic content and interactive forms Gone are the days of clicking, submitting, and waiting for the next page to load, or manually compiling your own content from all your various online identities to post in your site. A web page using AJAX techniques (if applied properly) will give the user a smoother and leaner experience. Click on a drop-down option and check-box menus underneath are immediately updated with the relevant choices—no submitting, no waiting. Complicated forms that, in the past, took two or three screens to process can be reduced into one convenient screen by implementing the form with AJAX. As wonderful as this all sounds, I must again offer a quick disclaimer: I understand that, like with drop-down menus and Flash, you may want AJAX to be in your site, or your clients are demanding that AJAX be in their sites. Just keep in mind, AJAX techniques are best used in situations where they truly benefit a user's experience of a page; for example, being able to painlessly add relevant content via an extension or cutting a lengthy web process form down from three pages to one. In a nutshell, using an AJAX technique simply to say your site is an AJAX site is probably not a good idea. You should be aware that, if not implemented properly, some uses of AJAX can compromise the security of your site. You may inadvertently end up disabling key web browser features (such as back buttons or the history manager). Then there's all the basic usability and accessibility issues that JavaScript in general can bring to a site. Some screen readers may not be able to read a new screen area that's been generated by JavaScript. If you cater to users who rely on tabbing through content, navigation may be compromised once new content is updated. There are also interface design problems that AJAX brings to the table (and Flash developers can commiserate). Many times, in trying to limit screen real estate and simplify a process, developers actually end up creating a form or interface that is unnecessarily complex and confusing, especially when your user is expecting a web page to, well, act like a normal web page. Remember to check in with Don't Make Me Think: This is the Steve Krug book I recommend for help with any interface usability questions you may run into.Really interested in taking on AJAX? For you programmers, I highly recommend "AJAX and PHP: Building Responsive Web Applications", Cristian Darie, Bogdan Brinzarea, Filip Chereches-Tosa, and Mihai Bucica, Packt Publishing. In it, you'll learn the ins and outs of AJAX development, including handling security issues. You'll also do some very cool stuff, such as make your own Google-style auto-suggest form and a drag-and-drop sortable list (and that's just two of the many fun things to learn in the book). So, that said, you're now all equally warned and armed with all the knowledgeable resources I can think to throw at you. Let's get to it: how exactly do you go about getting something Ajaxy into your Joomla! site? Joomla! extensions Keep in mind, extensions are not part of your template. They are additional files with Joomla!-compatible PHP code, which are installed separately into their own directories in your Joomla! 1.5 installation. Once installed, they are available to be used with any template that is also installed in your Joomla! installation. Even though these are not part of your template, you might have to prepare your template to be fully compatible with them. Some extensions may have their own stylesheets, which are installed in their extension directory. Once you've installed an extension, you may want to go into your own template's stylesheet so that it nicely displays XHTML objects and content that the extension may output into your site. Extensions are any component, module or plugin that you install into your Joomla! 1.5 installation. Components control content that displays in the main type="component" jdoc tag in your template. Note that components may also have module settings and the ability to display content in assigned module positions. The poll component is a good example of a component that also has module settings. Modules are usually smaller and lighter and only display in module positions. Plugins generally help you out more on the backend of your site, say to switch WYSIWYG editors or with enabling OpenID logins, but as we'll see, some plugins can affect the display of your site to users as well. Deciding where AJAX is best used On the whole, we're going to look at the most popular places where AJAX can really aid and enrich your site's user experience. We'll start with users adding comments to articles and pages and streamlining that process. We'll then take a look at a nice plugin that can enhance pagination for people reading long articles on your site. We'll then move on to the RSS Reader module, which can enhance the content in your modules (and even makes your users have fun arranging them). Finally, we'll realize that AJAX isn't just for impressing your site users. You, as an administrator, can (and do) take advantage of AJAX as well. Please note: These extensions were chosen by me based on the following criteria: 1. They provided some useful enhancement to a basic site.2. They, at the time of this writing, were free and received very good feedback on Joomla!.org's extensions site: http://extensions.Joomla.org. In the next few pages, I'll walk you through installing these extensions and discuss any interesting insights for doing so, and benefits of their enhancements (and some drawbacks). But you must use the extension links provided to make sure you download the latest stable versions of these extensions and follow the extension author's installation guides when installing these into your Joomla! site. If you run into any problems installing these extensions, please contact the extension's author for support. Always be sure to take the normal precaution of backing up your site before installation, at least for any non-stable extensions you may decide to try. Installing the Joomla! comment component Chances are, if you've invested in Joomla! 1.5 as your CMS, you need some powerful capabilities. Easy commenting with "captcha" images to reduce spam is always helpful: http://extensions.Joomla.org/extensions/contacts-&-feedback/comments/4389/details To install this extension (and the other few coming up), you have to basically go to Extensions | Install/Uninstall and upload the extension's ZIP file. You'll then proceed to the plugin, component, and/or modules panel and activate the extension so that it is ready to be implemented on your site. Upon installing this comment component, to my surprise, it told me that it was for an older version of Joomla! Everything on the download page seemed to indicate it worked with 1.5. The installation error did mention that I just needed to activate the System Legacy plugin and it would work. So I did, and the comment form appeared on all my article pages. This may seem like a step backward, but for extensions like this, which are very useful, if they work well and stay stable in Legacy Mode, a developer may have made the decision to leave well enough alone. The developer will most likely eventually upgrade the extension (especially if Legacy Mode goes away in future versions of Joomla!). Just be sure to sign up for updates or check back on any extensions you use if you do upgrade your site. You should do this regardless of whether your extensions run natively or in Legacy Mode. The advantage of AJAX in a comment form is that a user isn't distracted and comments post smoothly and right away (a bit of instant gratification for the user, even if you never "confirm" the post and it never gets actually published for other viewers). This extension outputs tables, but for the ease of handling robust comments and having a great admin area to manage them, I'll make do. The following screenshot shows the Joomla! comment component appearing in an article page: As you can see in my previous image, I have some strong styles that are trying to override the component's styles. A closer look at the output HTML will give me some class names and objects that I can target with CSS. The administration panel's Component | Joomla! Comment | Other Component settings page also allows quite a few customization options. The Layout tab also offers several included style sheets to select from as well as the option to copy the CSS sheet out to my template's directory (the component will do this automatically). This way, I can amend it with my own specific CSS, giving my comment form a better fit with my template's design. Installing the core design Ajax Pagebreak plugin If your site has long articles that get broken down regularly in to three or more pages, Pagebreak is a nice plugin that uses Ajax to smoothly load the next page. It's a useful feature that will also leave your site users with a little "oh wow" expression. http://www.greatJoomla.com/news/plugins/demo-core-design-ajaxpagebreak-plugin.html After successfully installing this plugin, I headed over to the Extensions | Plugin Manager and activated it. I then beefed out an article (with Lorem Ipsum) and added page breaks to it on the Home Page. It's hard to see in a screenshot, but it appears below the Prev and Next links without a full browser redraw. I've set my site up with SEO-friendly URLs, and this plugin does amend the URLs with a string; that is, http://yoururl.com/1.5dev/menu-item-4?start=1. I'm not sure how this will really affect the SEO "friendliness" value of my URL, but it does give me a specific URL to give to people if I want to send them to a targeted page, which is very good for accessibility. One thing to note, the first page of the article is the original URL; that is, http://yoururl.com/1.5dev/menu-item-4. The second page then appends ?start=1, the third page becomes ?start=2, and so on. Just be aware that when sending links out to people, it is always best to pull the URL directly from the site so that you know it's correct! Installing the AJAX RSS Reader Version 3 with Draggable Divs module RSS feeds are a great way to bring together a wide variety of content as well as bring all your or your organization's "social network happenings" to one place in your own site. I like to use RSS feeds to get people interested in knowing what an organization is doing (or tweeting), or reading, and so on. Having links and lists of what's currently going on can compel users to link to you, join your group, follow you, and become a friend, a fan, or whatever. This AJAX powered module has the extra feature of being draggable and somewhat editable. This is a nice way to draw a user in to the feeds and let them play with them and arrange the information to their taste. Sometimes, sorting and reorganizing makes you see connections and possibilities that you didn't see before. The next image may seem confusing, but it's a screenshot of the top div box being dragged and dropped: http://extensions.Joomla!.org/extensions/394/details AJAX: It's not just for your site's users I've already mentioned, when applied properly, how AJAX can aid in interface usability. Joomla! attempts to take advantage of this within its Administration panel by enhancing it with relevant information and compressing multiple page forms into one single screen area. Here's a quick look at how Joomla! already uses AJAX to enhance its Administration panel forms: The following image shows how the image uploader uses a "lightbox" div layer effect so that you can keep track of where you are in the content editor. In the next image, you can see how Joomla! helps keep the administration area cleared up by using smooth-sliding accordion panels. This helps you see everything on one page and have access to just what you need, when you need it.
Read more
  • 0
  • 0
  • 3125

article-image-managing-and-enhancing-multi-author-blogs-wordpress-27part-1
Packt
16 Oct 2009
18 min read
Save for later

Managing and Enhancing Multi-Author Blogs with WordPress 2.7(Part 1)

Packt
16 Oct 2009
18 min read
Creating an author page template If you have different authors on your blog, then my suggestion to you would be to display the biographical and contact information of each author on his own dedicated page. Luckily, WordPress allow us to do just that. Getting ready In this recipe, we're going to create an author page template for the purpose of displaying author related information. Make sure that you have understood the creation and usage of a page template. How to do it Create a new file named authors.php on your WordPress theme directory. Insert the following code into your file named authors.php: <?php/*Template Name: Authors Page*/?><?php get_header(); ?><div id="content" class="narrowcolumn"><?phpif(isset($_GET['author_name'])) :$curauth = get_userdatabylogin($author_name);else :$curauth = get_userdata(intval($author));endif;?><h2>About <?php echo $curauth->nickname; ?></h2><div class="excerpt"><?php echo $curauth->nickname; ?> personal website:<a href="<?php echo $curauth->user_url; ?>"><?php echo $curauth->user_url; ?></a></div><?php echo $curauth->user_description; ?><h2>Latest posts by <?php echo $curauth->nickname; ?>:</h2>Chapter 6133<ul><?php if ( have_posts() ) : while ( have_posts() ) :the_post(); ?><li><a href="<?php the_permalink() ?>"><?php the_title();?></a> on <?php the_time('d M Y'); ?></li><?php endwhile; else: ?><p><?php _e('No posts by this author.'); ?></p><?php endif; ?></ul></div><!--/content--><?php get_sidebar(); ?><?php get_footer(); ?> Save the file and upload it to the wp-content/themes/yourtheme folder of your WordPress install. Log in to your WordPress dashboard, create a new page, and select the Authors Page as a page template. Give it the title of your choice, such as, About the Author and publish the page. Open the single.php file from your theme. Depending on the theme that you're using, you may need to add the following code in order to display the author's name and a link to the author's page: Posted by <?php the_author_posts_link(); ?> Once you have saved the modifications made in your single.php file, visit one of your blog posts and click on the author name. The author page is displayed showing the author name, description, and web site. How it works The first thing that we need to know is the name of the author whose information is to be displayed. To do so, we have to get the author_name parameter sent via the GET method. With this value, we can initialize a $curauth php object that will allow us to get some personal information about the author, such as his web site, email, biography, and so on, with the help of the classic php syntax, that is, $curauth->nickname;. Once the author data, that is to be displayed, has been retrieved, we shall add a WordPress loop in order to be able to view the recent posts by this author. The following screenshot shows a well-prepared author page: There's more... In the preceding example we retrieved the author name, description, and web site URL. However, as you may know, users can provide much more information (in Administration, Profile, Your Profile options) such as their email address, AIM and Yahoo! messenger nickname, and login information. A few more template tags can be used to retrieve another kind of information from the author data. These tags are listed under the There's more! section of Displaying author-related information on posts, which we will see later in this article. Displaying a custom login form in your blog's sidebar It doesn't matter whether you're running a multi-author blog, or a blog where readers can register. Having a login form embedded in your sidebar will make your blog look a lot more professional and user friendly. Here is what you can expect from this recipe. In the following screenshot, a login form has been added to the K2 theme sidebar. Getting ready To achieve this recipe, you'll have to edit the sidebar.php file from your theme. The following hack works with WordPress 2.0 to 2.8. How to do it Open the sidebar.php file for editing. Find the opening <ul> tag and paste the following code under it: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2><?php echo $user_identity ?></h2><ul><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li></ul><?php elseif ( get_option('users_can_register') ) : ?>Managing and Enhancing Multi-Author Blogs136<h2>Identification</h2><ul><li><form action="<?php bloginfo('url')?>/wp-login.php" method="post"><p><label for="log"><input type="text" name="log"id="log" value="<?php echo wp_specialchars (stripslashes($user_login), 1) ?>" size="22" /> User</label><br /><label for="pwd"><input type="password"name="pwd" id="pwd" size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme"id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url')?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif ?></li> Save the file. Your users can now login directly from your blog's sidebar. How it works The working of this code is quite simple. First, you initialize the global variables to get the user ID, name, and level. Then, you check the value of the $user_ID variable. If the value is not null, which means that the current user is logged in, you then display a quick hello user text and a link to log out. If the user isn't logged in, you check whether registering is allowed on the blog. If the user is logged in, then you simply display an HTML form that allows the user to log in directly from the blog. A link has also been included for registration if the current user doesn't have an account yet. This code was inspired from a tutorial available at www.wpdesigner.com. Adding a control panel to your blog's sidebar Now that you have learned how to check whether a user is logged in or not, why not learn how to add a small control panel to your blog's sidebar that is only visible to the logged in users. In this recipe, you'll learn how to achieve this task. Getting ready The upcoming piece of code works in exactly the same way as the code from the previous recipe does. It is all about checking if the user is logged in and whether he or she has the right to do a certain kind of thing. The following screenshot shows a simple, but useful, control panel which is similar to the one we're about to create: How to do it Open sidebar.php for editing. Find the first opening <ul> HTML tag, and paste the following code under the <ul> tag: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echourlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php endif; ?></li> Once you are done, save the file. The allowed users can now go to their dashboard, edit their profile, or write a new post directly from the blog. How it works As mentioned earlier, this code works in the same way as the code that was used to create a login form in the sidebar. After you've made sure that the $user_ID variable isn't null, you work towards displaying the options available to the user. It is possible to define what a user can perform according to his role (administrator, author, contributor, subscriber, and so on). We're going to have a look at this in the next recipe. There's more... Now that you have learned how to add a control panel to the blog's sidebar, let's go ahead and try out something new. Adding a login form and a control panel Now that you know how to add a login form and a mini control panel to your blog's sidebar, why not try mixing the two codes? If the user isn't logged in, we'll display the login form. Otherwise, the custom panel will be shown to the user. The code below works in the same way as the two that we studied previously. Add the following code to the sidebar.php file of your theme: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php elseif ( get_option('users_can_register') ) : ?><h2>Identification</h2><ul><li><form action="<?php bloginfo('url') ?>/wp-login.php"method="post"><p><label for="log"><input type="text" name="log" id="log" value="<?php echo wp_specialchars(stripslashes($user_login), 1)?>" size="22" /> User</label><br /><label for="pwd"><input type="password" name="pwd" id="pwd"size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme" id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url') ?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif; ?></li> The custom logging form for unregistered users will look similar to the following screenshot: And the control panel for logged in users will look similar to the following screenshot: Configuring author roles Now that you have learned about the different aspects of the user's roles and capabilities, there's probably something that you're finding a little frustrating. By default, you can't configure author roles to fit your blog's needs. For example, a contributor can't upload images. Moreover, by default, you can't change it. Luckily, there's a plugin called Role Manager which allows you to configure author roles in the way that you want. Getting ready The Role Manager plugin can be found at the following link: http://www.im-web-gefunden.de/wordpress-plugins/role-manager/ Download it, unzip it onto your hard drive, and install it as any other WordPress plugin. How to do it Once the Role Manager plugin is installed, log in to your WordPress dashboard and go to Users | Roles. A list of all of the available user roles will be displayed. For each role you can define what the user can do. For example, you can choose to let a contributor upload images. What is even better is that you're not limited to the 5 default user roles that are provided by WordPress. The Role Manager plugin allows you to create new roles, as well as the ability to rename, copy, or delete existing ones. How it works The job of the Role Manager plugin is pretty easy. It simply creates custom roles with the options that you have defined and save it on the WordPress database. There's more... Now that we have configured the author roles, let's learn how to control the author's actions. Controlling what authors can do Even if your blog is powered by multiples authors, it is still your blog. Therefore, you shouldn't allow every author to have the right to edit posts or delete comments. Since version 2.0, WordPress features user roles. User roles are defined as a group of actions that can be accomplished by a specific range of users. For example, the administrator can edit theme files, but the subscribers can't. User roles and their capabilities Here are the 5 predefined roles for WordPress users: Administrator: The administrator is the blog owner. He has unlimited access to all of the administration features such as writing posts, editing his own posts along with the posts from other authors, installing plugins, selecting a new theme, editing themes, and editing plugin files. Editor: The editor can write or publish posts, upload images, edit his own posts, and manage other's posts. Author: The author can write, publish, and edit his own his own posts. He's also allowed to upload images for use in his posts. Contributor: A contributor can write posts but can't publish them himself. Once he has written a post, the post is pending approval from the administrator. The contributor can't upload images either. This role is very good for guest authors on your own blog. Subscriber: A subscriber is a registered user of your blog, but can't write posts. For an exhaustive description of user roles and capabilities, you should read the related page in WordPress Codex: http://codex.wordpress.org/Roles_and_Capabilities. Controlling what users can see in your theme In the previous example, we built a sidebar control panel that allows the user to edit the current post. However, the code doesn't let you control which kind of author is allowed to edit the current post. For now, even if only the users with a sufficient role level will be capable of editing the post, every logged in user can see the related link. The solution to that problem is a built-in WordPress function, called current_user_can(). As an argument, this function takes a string describing the action or the required role level to perform a specific task. For example, the following code will provide a link to edit the current post to the administrators only: <?phpif (current_user_can('level_10')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> The current_user_can() function accepts user_0 to user_10 as a parameter. Here is the conversion table between the role levels and the roles: Suscriber: level_0 Contributor: level_1 Author: level_2 to level_4 Editor: level_5 to level_7 Administrator: level_8 to level_10 The current_user_can() function can also be used with a specific action as a parameter. This is the recommended use, as the level parameter is becoming obsolete. The following example checks if the current user can edit a post he previously published. If yes, then a link to edit the post will be displayed. <?phpif (current_user_can('edit_published_posts')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> Here are all of the arguments that are accepted by the current_user_can() function:      switch_themes      edit_themes      activate_plugins      edit_plugins      edit_users      edit_files      manage_options      moderate_comments      manage_categories      manage_links      upload_files      import      unfiltered_html      edit_posts      edit_others_posts      edit_published_posts      edit_pages      edit_others_pages      edit_published_pages      edit_published_pages      delete_pages      delete_others_pages      delete_published_pages      delete_posts      delete_others_posts      delete_published_posts      delete_private_posts      edit_private_posts      read_private_posts      delete_private_pages      edit_private_pages      read_private_pages      delete_users      create_users      unfiltered_upload      edit_dashboard      update_plugins      delete_plugins Displaying author-related information on posts In a multi-author blog, it's always good for the reader to know the author of the article that they're currently reading. It's even better if they can grab some extra information about the author, such as his website, a short bio, and so on. In this recipe, you'll learn how to edit your single.php theme file to automatically retrieve the author-related information, and display it at the top of the page. Getting ready As we're going to display author information on posts, the first thing to do is to make sure that your contributing authors have entered their biography and other information into the WordPress database. Any author can enter his information by logging in to the WordPress dashboard, and then going to Profile. The blog administrator can edit all of the profiles. The following screenshot shows the WordPress 2.7 profile editor for the authors. How to do it Once you have made sure that your authors have successfully filled their information, you can start coding by carrying out the following steps: Open the file single.php for addition. Paste the following code within the loop: <div id="author-info"><h2>About the author: <?php the_author();?></h2><?php the_author_description(); ?><?php the_author();?>'s website: <a href="<?php the_author_url();?>"><?php the_author_url(); ?></a><br />Other posts by <?php the_author_posts_link(); ?></div><!--/author-info--> Save the file and visit your blog. You will notice that your posts now automatically display the author-related information, as shown in the following screenshot: How it works WordPress provides a dozen of author-related template tags, which are an easy way to retrieve information that is entered by authors in their profile. Note that all of these tags must be used within the loop for them to work. There's more... Here are all the available template tags related to authors:
Read more
  • 0
  • 1
  • 2846

article-image-creating-matrix-report-using-analysis-services-cube
Packt
16 Oct 2009
4 min read
Save for later

Creating a matrix report using the Analysis Services Cube

Packt
16 Oct 2009
4 min read
Reviewing Jayaram's other OLAP related articles may greatly help in understanding this article. Creating the CUBE will be essential to work with this hands-on. If you are already experienced and have an appropriate CUBE to work with you may directly go to the section on deriving a dataset. The CUBE used in this hands-on is a simple one. It does not even have a "Time" dimension although Microsoft in Visual Studio gives a warning that you should have one. However for the purposes of demonstration and doing the hands-on a CUBE without the "Time" dimension should be adequate. The two previous articles on creating a CUBE provide the necessary background for this article. Create a data source with a CUBE Create an Analysis Services Cube (herein called MyNwind.cube) using the TestNorthwind as the database. The Measures and Dimensions for this cube are as shown in the next figure. Start your Report Builder 2.0. Make sure you have started the reporting services using the Reporting Services Configuration Manager. In Report Builder 2.0 click on New | Data source... under Report Data. Provide the following information: Name: SrcCubeSelect connection type: Microsoft SQL Server Analysis ServicesConnection String: Data Source=Hodentek2SANGAM; Initial Catalog=NwindRTM Herein NwindRTM is the name of the Datasource in the Analysis Server. (Alternately you may build this source as shown). Click OK on the Data Source Properties window. Add a dataset to the report Right click on SrcCube and choose Add DataSet... In the Dataset Properties window make the following changes: Name: QryCubeData source: SrcCubeQuery Type: text Click on Query Designer... button. At first you will see only the Metadata of the cube displayed as in the left side of the next figure. Expand Customers, Orders, and Products in the dimensions and drop them on the list header in the bottom pane on the right hand side of the next figure. Drag and drop Freight from Orders under Measures as shown. For each of the dimensions using an operator create a filter expression as shown. For example, the Products included in the query range from Product IDs 3 to 9; the Customer ID (some specific ones are chosen), similarly theCategory ID (only those with ID's 2, 3, 4, and 5 are included in the query). The design of the query with these filtering choices is as shown in the previous figure. The filtering tool is very flexible and all the items namely Dimension, Hierarchy, Operator and Filter Expression can be designed in this interface using either drop-down pick lists choices or drop-downs with checkboxes as shown here. Run the query by clicking on the toolbar item (!) and review the results. Click OK on the Query Designer. The Dataset Properties window shows up with this query designed according to your choices in the query item window as shown. Close the Dataset Properties window. Report Design In Report Builder 2.0 click on New Table or Matrix wizard. In the Choose a dataset window accept the default and click Next. Drag and drop Customer_ID in the Row Groups drop area. Drag and drop Order_ID below Customer_ID in the Row Groups drop area. Drag and drop Product_ID in the Column Groups drop area. Drag and drop Freight into the Values drop area and click on Next. In the Choose the layout window accept Expand/collapse groups and choose the option Stepped, subtotal above. Click Next and choose some style (herein Ocean) and click Finish. The final report design is as shown here. Click Home | Run. The report gets displayed after processing as shown here. The orders from a particular customer have been expended in this view. Summary Report Builder 2.0 can used to author reports based on Analysis Services Cubes. The interface is very flexible and the Query Designer is very easy to use as shown in this article. If you have read this article you may be interested to view : Creating an Analysis Services Cube with Visual Studio 2008 - Part 1 Creating an Analysis Services Cube with Visual Studio 2008 - Part 2
Read more
  • 0
  • 0
  • 3698
article-image-simplifying-parallelism-complexity-c
Packt
16 Oct 2009
7 min read
Save for later

Simplifying Parallelism Complexity in C#

Packt
16 Oct 2009
7 min read
Specializing the algorithms for segmentation with classes So far, we have been developing applications that split work into multiple independent jobs and created classes to generalize the algorithms for segmentation. We simplified the creation of segmented and parallelized algorithms, generalizing behaviors to simplify our code and to avoid repeating the same code on every new application. However, we did not do that using inheritance, a very powerful object-oriented capability that simplifies code re-use. C# is an object-oriented programming language that supports inheritance and offers many possibilities to specialize behaviors to simplify our code and to avoid some synchronization problems related to parallel programming. How can we use C# object-oriented capabilities to define specific segmented algorithms prepared for running each piece in an independent thread using ParallelAlgorithm and ParallelAlgorithmPiece as the base classes? The answer is very simple—by using inheritance and the factory method class creational pattern (also known as virtual constructor). Thus, we can advance into creating a complete framework to simplify the algorithm optimization process. Again, we can combine multithreading with object-oriented capabilities to reduce our development time and avoid synchronization problems. Besides, using classes to specialize the process of splitting a linear algorithm into many pieces will make it easier for the developers to focus on generating very independent parts that will work well in a multithreading environment, while avoiding side-effects. Time for action – Preparing the parallel algorithm classes for the factory method You made the necessary changes to the ParallelAlgorithmPiece and the ParallelAlgorithm classes to possibly find planets similar to Mars in the images corresponding to different galaxies. NASA's CIO was impressed with your parallel programming capabilities. Nevertheless, he is an object-oriented guru, and he gave you the advice to apply the factory method pattern to specialize the parallel algorithm classes in each new algorithm. That could make the code simpler, more re-usable, and easier to maintain. He asked you to do so. The NASA scientists would then bring you another huge image processing challenge for your parallel programming capabilities—a sunspot analyzer. If you resolve this problem using the factory method pattern or something like that, he will hire you! However, be careful, because you must avoid some synchronization problems! First, we are going to create a new project with tailored versions of the ParallelAlgorithmPiece and ParallelAlgorithm classes. This way, later, we will be able to inherit from these classes and apply the factory method pattern to specialize in parallel algorithms: Create a new C# Project using the Windows Forms Application template in Visual Studio or Visual C# Express. Use SunspotsAnalyzer as the project's name. Open the code for Program.cs. Replace the line [STAThread] with the following line (before the Main method declaration): [MTAThread] Copy the file that contains the original code of the ParallelAlgorithmPiece and the ParallelAlgorithm classes (ParallelAlgorithm.cs) and include them in the project. Add the abstract keyword before the declarations of theParallelAlgorithmPiece and the ParallelAlgorithm classes, as shown in the following lines (we do not want to create instances directly from these abstract classes): abstract class ParallelAlgorithmPieceabstract class ParallelAlgorithm Change the ThreadMethod method declaration in the ParallelAlgorithmPiece class (add the abstract keyword to force us to override it in subclasses): public abstract void ThreadMethod(object poThreadParameter); Add the following public abstract method to create each parallel algorithm piece in the ParallelAlgorithm class (the key to the factory method pattern): public abstract ParallelAlgorithmPieceCreateParallelAlgorithmPiece(int priThreadNumber); Add the following constructor with a parameter to the ParallelAlgorithmPiece class: public ParallelAlgorithmPiece(int priThreadNumberToAssign){priThreadNumber = priThreadNumberToAssign;} Copy the original code of the ParallelAlgorithmPiece class CreatePieces method and paste it in the ParallelAlgorithm class (we move it to allow creation of parallel algorithm pieces of different subclasses). Replace the lloPieces[i].priBegin and lloPieces[i].priEnd private variables' access with their corresponding public properties access lloPieces[i].piBegin and lloPieces[i].piEnd. Change the new CreatePieces method declaration in the ParallelAlgorithm class (remove the static clause and add the virtual keyword to allow us to override it in subclasses and to access instance variables): public virtual List<ParallelAlgorithmPiece>CreatePieces(long priTotalElements, int priTotalParts) Replace the line lloPieces[i] = new ParallelAlgorithmPiece(); in the CreatePieces method declaration in the ParallelAlgorithm class with the following line of code (now the creation is encapsulated in a method, and also, a great bug is corrected, which we will explain later): lloPieces.Add(CreateParallelAlgorithmPiece(i)); Comment the following line of code in the CreatePieces method in the ParallelAlgorithm class (now the new ParallelAlgorithmPiece constructor assigns the value to piThreadNumber): //lloPieces[i].piThreadNumber = i; Replace the line prloPieces = ParallelAlgorithmPiece. CreatePieces(priTotalElements, priTotalParts); in the CreateThreads method declaration in the ParallelAlgorithm class with the following line of code (now the creation is done in the new CreatePieces method): prloPieces = CreatePieces(priTotalElements, priTotalParts); Change the StartThreadsAsync method declaration in the ParallelAlgorithm class (add the virtual keyword to allow us to override it in subclasses): public virtual void StartThreadsAsync() Change the CollectResults method declaration in the ParallelAlgorithm class (add the abstract keyword to force us to override it in subclasses): public abstract void CollectResults(); What just happened? The code required to create subclasses to implement algorithms, following a variation of the factory method class creational pattern, is now held in the ParallelAlgorithmPiece and ParallelAlgorithm classes. Thus, when we create new classes that will inherit from these two classes, we can easily implement a parallel algorithm. We must just fill in the gaps and override some methods, and we can then focus on the algorithm problems instead of working hard on the splitting techniques. We also solved some bugs related to the previous versions of these classes. Using C# programming language's excellent object-oriented capabilities, we can avoid many problems related to concurrency and simplify the development process using high-performance parallel algorithms. Nevertheless, we must master many object-oriented design patterns to help us in reducing the complexity added by multithreading and concurrency. Defining the class to instantiate One of the main problems that arise when generalizing an algorithm is that the generalized code needed to coordinate the parallel algorithm must create instances of the subclasses that represent the pieces. Using the concepts introduced by the factory method class creational pattern, we solved this problem with great simplicity. We made the necessary changes to the ParallelAlgorithmPiece and ParallelAlgorithm classes to implement a variation of this design pattern. First, we added a constructor to the ParallelAlgorithmPiece class with the thread or piece number as a parameter. The constructor assigns the received value to the priThreadNumber private variable, accessed by the piThreadNumber property: public ParallelAlgorithmPiece(int priThreadNumberToAssign){priThreadNumber = priThreadNumberToAssign;} The subclasses will be able to override this constructor to add any additional initialization code. We had to move the CreatePieces method from the ParallelAlgorithmPiece class to the ParallelAlgorithm class. We did this because each ParallelAlgorithm subclass will know which ParallelAlgorithmPiece subclass to create for each piece representation. Thus, we also made the method virtual, to allow it to be overridden in subclasses. Besides, now it is an instance method and not a static one. There was an intentional bug left in the previous CreatePieces method. As you must master lists and collections management in C# in order to master parallel programming, you should be able to detect and solve this little problem. The method assigned the capacity, but did not add elements to the list. Hence, we must use the add method using the result of the new CreateParallelAlgorithmPiece method. lloPieces.Add(CreateParallelAlgorithmPiece(i)); The creation is now encapsulated in this method, which is virtual, and allows subclasses to override it. The original implementation is shown in the following lines: public virtual ParallelAlgorithmPiece CreateParallelAlgorithmPiece(int priThreadNumber){return (new ParallelAlgorithmPiece(priThreadNumber));} It returns a new ParallelAlgorithmPiece instance, sending the thread or piece number as a parameter. Overriding this method, we can return instances of any subclass of ParallelAlgorithmPiece. Thus, we let the ParallelAlgorithm subclasses decide which class to instantiate. This is the principle of the factory method design pattern. It lets a class defer instantiation to subclasses. Hence, each new implementation of a parallel algorithm will have its new ParallelAlgorithm and ParallelAlgorithmPiece subclasses. We made additional changes needed to keep conceptual integrity with this new approach for the two classes that define the behavior of a parallel algorithm that splits work into pieces using multithreading capabilities.
Read more
  • 0
  • 0
  • 2494

article-image-jquery-ui-accordion-widget-part-1
Packt
16 Oct 2009
9 min read
Save for later

jQuery UI Accordion Widget - Part 1

Packt
16 Oct 2009
9 min read
Accordion's structure Let's take a moment to familiarize ourselves with what an accordion is made of. Within the outer container is a series of links. These links are the headings within the accordion and each heading will have a corresponding content panel, or drawer as they are sometimes referred to, which opens when the heading is clicked. The following screenshot shows these elements as they may appear in an accordion: It's worth remembering that when using the accordion widget, only one content panel can be open at any one time. Let's implement a basic accordion now. In a blank page in your text editor, create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 1</title> </head> <body> <ul id="myAccordion"> <li> <a href="#">Header 1</a> <div>Wow, look at all this content that can be shown or hidden with a simple click!</div> </li> <li> <a href="#">Header 2</a> <div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. </div> </li> <li> <a href="#">Header 3</a> <div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> </li> </ul> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save the file as accordion1.html in your jqueryui folder and try it out in a browser. We haven't specified any styling at all at this stage, but as you can see from the following screenshot, it still functions exactly as intended: Little code is required for a basic working version of the accordion widget. A simple unordered list element is the mark-up foundation which is transformed by the library into the accordion object. The following three separate external script files are required for an accordion: The jQuery library itself (jquery-1.2.6.js) The UI base file (ui.core.js) The accordion source file (ui.accordion.js) The first two files are mandatory requirements of all components of the UI library. They should be linked to in the order shown here. Each widget also has its own source file, and may depend on other components as well. The order in which these files appear is important. The jQuery library must always appear first, followed by the UI base file. After these files, any other files that the widget depends upon should appear before the widget's own script file. The library components will not function as expected if files are not loaded in the correct order. Finally, we use a custom <script> block to turn our <ul> element into the accordion. We can use the jQuery object shortcut $ to specify an anonymous function which will be executed as soon as the document is ready. This is analogous to using $(document).ready(function(){}) and helps to cut down on the amount of code we have to type. Following this, we use the simple ID selector $("#myAccordion") to specify the element on the page we want to transform. We then use the accordion() constructor method to create the accordion Other elements can be turned into accordions as well. All list element variants are supported including ordered lists and definition lists. You don't even need to base the accordion on a list element at all. You can build a perfectly functional accordion using just nested <div> and <a> elements, although additional configuration will be required In the above example, we used an empty fragment (#) as the value of the href attribute. You should note that any URLs supplied for accordion headers will not be followed when the header is clicked within the accordion when using the default implementation. Styling the accordion With no styling, the accordion will take up 100% of the width of its container. Like with other widgets, we have several options for styling the accordion. We can create our own custom stylesheet to control the appearance of the accordion and its content, we can use the default or flora themes that come with the library, or we can use Theme Roller to create an extensive skin for the whole library. Let's see how using the flora theme for the accordion will cause it to render. In accordion1.html, add the following <link> tag to the <head> of the page: <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.accordion.css"> Save the new file as accordion2.html, also in the jqueryui folder, and view it again in a browser. It should appear something like this: The accordion theme file assumes that an unordered list is being used as the basis of the widget and specifically targets <li> elements with certain style rules. We can easily create our own custom theme to style the accordion for situations where we want to use a non-list-based accordion widget, or if we simply want different colors or font styles. You can use the excellent Firebug plugin for Firefox, or another DOM viewer, to see the class names that are automatically added to certain elements when the accordion is generated. You can also read through an un-minified version of the source file if you really feel like it. These will be the class names that we'll be targeting with our custom CSS. The following screenshot shows Firebug in action: Change accordion2.html so that it appears as follows (new code is shown in bold): <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="styles/accordionTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 3</title> </head> <body> <div id="myAccordion"> <span class="corner topLeft"></span><span class="corner topRight"></span><span class="corner bottomLeft"></span><span class="corner bottomRight"></span> <div><a href="#">Header 1</a><div>Wow, look at all this content that can be shown or hidden with a simple click!</div></div> <div><a href="#">Header 2</a><div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti.</div></div> <div><a href="#">Header 3</a><div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div></div> </div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save this version as accordion3.html in the jqueryui folder. The class name ui-accordion is automatically added to the accordion's container element. Therefore, we can use this as a starting point for most of our CSS selectors. The links that form our drawer headers are given the class ui-accordion-header so we can also target this class name. In a new file, create the following stylesheet: #myAccordion { width:200px; border:2px solid #000000; position:relative; list-style-type:none; padding-left:0;}.ui-accordion-header { text-decoration:none; font-weight:bold; color:#000000; display:block; width:100%; text-align:center;}.ui-accordion div div { font-size:90%;}.ui-accordion a { color:#ffffff; background:url(../img/accordion/header-sprite.gif) repeat-x 0px 0px;}.ui-accordion a.selected { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -22px;}.ui-accordion a:hover { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -44px;}/* container rounded corners */.corner { position:absolute; width:12px; height:13px; background:url(../img/accordion/corner-sprite.gif) no-repeat;}.topLeft { top:-2px; left:-2px; background-position:0px 0px;}.topRight { top:-2px; right:-2px; background-position:0px -13px;}.bottomRight { bottom:-2px; right:-2px; background-position:0px -26px;}.bottomLeft { bottom:-2px; left:-2px; background-position:0px -39px;} Save this file as accordionTheme.css in your styles folder and preview accordion3.html in a browser. We will need a new folder for the images we use in this and subsequent examples. Create a new folder inside the img folder and name it accordion. With just two images, and a few simple style rules, we can drastically change the default appearance of the accordion with our own custom skin as shown in the following screenshot: Configuring accordion The accordion has a range of configurable properties which allow us to easily change the default behaviour of the widget. The following table lists the available properties, their default value, and gives a brief description of their usage:
Read more
  • 0
  • 0
  • 4496
Modal Close icon
Modal Close icon