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

How-To Tutorials

7019 Articles
article-image-author-podcast-bob-griesemer-oracle-warehouse-builder-11g
Packt
09 Apr 2010
1 min read
Save for later

Author Podcast - Bob Griesemer on Oracle Warehouse Builder 11g

Packt
09 Apr 2010
1 min read
Click here to download the interview, or hit play in the media player below.    
Read more
  • 0
  • 0
  • 1542

article-image-unveil-power-your-business-data-oracle-discoverer
Packt
08 Apr 2010
4 min read
Save for later

Unveil the Power of Your Business Data with Oracle Discoverer

Packt
08 Apr 2010
4 min read
A quick guide to Oracle Discoverer packaging Before proceeding to get the Oracle Discoverer software, it’s important to realize what you actually need and what the Oracle Discoverer packaging provides. At the moment, there are two options when it comes to the current Oracle Discoverer software: Oracle Business Intelligence suite, part of Oracle Application Server 10g Release 2 Portal, Forms, Reports and Discoverer suite, part of Oracle Fusion Middleware 11g Release 1 The first option – the Oracle Business Intelligence suite, part of Oracle Application Server 10g Release 2 – includes the following components: Oracle Business Intelligence Discoverer Oracle HTTP Server Oracle Application Server Containers for J2EE (OC4J) Oracle Enterprise Manager 10g Application Server Control Oracle Application Server Web Cache Oracle Application Server Reports Services The first component, Oracle Business Intelligence Discoverer, in the above list represents actually a group of components whose name starts with Discoverer. The package includes: Discoverer Plus Discoverer Viewer Discoverer Services Discoverer Portlet Provider Note, however, that the above list does not include all the Discoverer components. For example, you won’t find the following Discoverer components there: Discoverer Administrator Discoverer Desktop The above components are included in a complementary package called Oracle Business Intelligence Tools. As mentioned at the beginning of this section, another option to take advantage of the Discoverer components is to install the Portal, Forms, Reports and Discoverer suite, which is part of Oracle Fusion Middleware 11g Release 1. This package includes the following components: HTTP Server WebCache Portal Forms Services Forms Builder Reports Services Report Builder/Compiler Discoverer Administrator Discoverer Plus Discoverer Viewer Discoverer Services Discoverer Desktop Enterprise Manager Fusion Middleware Control As you can see, the Portal, Forms, Reports and Discoverer suite, unlike Oracle Business Intelligence suite, does include Discoverer Administrator and Discoverer Desktop. So you won’t need to install another package to obtain these components. A major downside to choosing the Portal, Forms, Reports and Discoverer suite, though, is that it requires some additional software to be installed in your system. Here is the list of the required additional software components: WebLogic Server Repository Creation Utility Identity Management SSO Metadata Repository Creation Assistant Patch Scripts Identity Management 10gR3 Oracle Database Due to this reason – to save you the trouble of installing a lot of software – the "Installation process" section later in this article will cover the installation of Oracle Business Intelligence suite, part of Oracle Application Server 10g Release 2 rather than the Portal, Forms, Reports and Discoverer suite of Oracle Fusion Middleware 11g Release 1. Getting the software Once you have decided on the package you want to install, you can go for it to the OTN’s Software Downloads page at http://www.oracle.com/technology/software/index.html. It’s important to remember that each software component available from this page comes with a Development License, which allows for free download and unlimited evaluation time. You can look at the license at http://www.oracle.com/technology/software/popup-license/standard-license.html. Later, if you so desire, you can always buy products with full-use licenses. So, the OTN’s Software Downloads page, go to the Middleware section and, assuming you want to download Oracle Business Intelligence suite, click the Business Intelligence SE link to proceed to the Oracle Application Server 10g Release 2 (10.1.2.0.2) page at http://www.oracle.com/technology/software/products/ias/htdocs/101202.html. On this page, go down to the Business Intelligence section and find the links to the packages provided for your operating system. Each package is supposed to be copied on a separate CD. The number of CDs and the size of packages to be copied on them may vary depending on the operating system. What you need to do is download the installation packages and then copy each to a CD. Looking through the links to the installation packages, you may notice that Tools CD – the link to the package containing the Oracle Business Intelligence Tools suite – is available only for Microsoft Windows operating system. This is because the components included in the Oracle Business Intelligence Tools suite are Windows-only applications. If, instead of the Oracle Business Intelligence suite, you decided on the Portal, Forms, Reports and Discoverer suite, you have to follow the Oracle Fusion Middleware 11g R1 link in the Middleware section on the OTN’s Software Downloads page. Following that link, you’ll be directed to the Oracle Fusion Middleware 11gR1 Software Downloads page at http://www.oracle.com/technology/software/products/middleware/htdocs/fmw_11_download.html. On this page, go down to the Portal, Forms, Reports and Discoverer section and pick up the distribution divided into several packages. Again, the number of packages within a distribution and their size may vary depending on the operating system.
Read more
  • 0
  • 0
  • 2317

article-image-service-oriented-java-business-integration-proxy
Packt
07 Apr 2010
9 min read
Save for later

Service Oriented Java Business Integration Proxy

Packt
07 Apr 2010
9 min read
Proxy—A Primer Wikipedia defines Proxy as: Proxy may refer to something which acts on behalf of something else. In the software a proxy is a substitute for a target instance and is a general pattern which appears in many other patterns in different variants. Proxy Design Pattern A proxy is a surrogate class for the target object. If a method call has to be invoked in the target object, it happens indirectly through the proxy object. The feature which makes proxy ideal for many situations is that the client or the caller is not aware that it is dealing with the proxy object. The proxy class is shown in the following figure: In the above figure, when a client invokes a method target towards the Target service, the proxy intercepts the call in between. The proxy also expose a similar interface to the target, hence the client is unaware of the dealing with the proxy. Thus the proxy method is invoked. The proxy then delegates the call to the actual target since it cannot provide the actual functionality. When doing so, the proxy can provide call management towards the actual method. The entire dynamics is shown in the following figure: A proxy is usually implemented by using a common, shared interface or super class. Both the proxy and the target share this common interface. Then, the proxy delegates the calls to the target class. JDK Proxy Class JDK provides both the class Proxy and the interface InvocationHandler in the java.lang.reflect package, since version 1.3. Using JDK Proxy classes, you can create your own classes implementing multiple interfaces of your choice, at run time. Proxy is the super class for any dynamic proxy instances you create at run time. Moreover, the Proxy class also accommodates a host of static methods which will help you to create your proxy instances. getProxyClass and newProxyInstance are two such utility methods. The Proxy API is listed in the following in brevity: package java.lang.reflect;public class Proxy implements java.io.Serializable{ protected InvocationHandler h; protected Proxy(InvocationHandler h); public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException; public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException; public static boolean isProxyClass(Class<?> cl); public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException} In the above code, you can invoke the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy, to get a Class instance for the proxy. Proxy objects have one constructor, to which you pass an InvocationHandler object associated with that proxy. When you invoke a method on the proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler. Let us also look at the InvocationHandler API reproduced as follows: package java.lang.reflect;public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object[] args) throws Throwable;} We need to implement this interface and provide code for the invoke method. Once you get a Class instance for the proxy by invoking the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy to. Now, you can get a Constructor object for this proxy from the Class instance. On the constructor you can use newInstance (passing in an invocation handler instance) to create the proxy instance. The created instance should be implementing all the interfaces that were passed to getProxyClass. The steps are shown in the following code: InvocationHandler handler = new SomeInvocationHandler(...);Class proxyClazz = Proxy.getProxyClass(Blah.class.getClassLoader(), new Class[] {Blah.class});Blah blah = (Blah) proxyClazz.getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] {handler}); There is also a shortcut to get a proxy object. You can invoke Proxy.newProxyInstance, which takes a class loader, an array of interface classes, and an invocation handler instance. InvocationHandler handler = new SomeInvocationHandler(...);Blah blah = (Blah) Proxy.newProxyInstance(Blah.class. getClassLoader(),new Class[] {Blah.class}, handler); Now you can invoke methods on the proxy object during which these method invocations are turned into calls on to the invocation handler's invoke method is shown here: blah.interfaceMethod(); Sample JDK Proxy Class We will now write some simple code to demonstrate how you can write your own proxies at run time, for your interface classes. As a first step, if you haven't done it before, edit examples.PROPERTIES, and change the paths there to match your development environment. We will now look at the source code that can be found in the folder ch13JdkProxysrc. The files are explained here: ch13JdkProxysrcSimpleIntf.java public interface SimpleIntf { public void print(); } SimpleIntf is a simple interface with a single method print. print does not accept any parameters and also does not return any value. Our aim is that when we invoke methods on the proxy object for SimpleIntf, the method invocation should be turned into calls to an invocation handler's invoke method. Let us now define an invocation handler in the following code: ch13JdkProxysrcSimpleInvocationHandler.java import java.lang.reflect.InvocationHandler; import java.io.Serializable; import java.lang.reflect.Method; public class SimpleInvocationHandler implements InvocationHandler, Serializable { public SimpleInvocationHandler(){} public Object invoke(final Object obj, Method method, Object[] args) throws Throwable { if (method.getName().equals("print") && (args == null || args.length == 0)) { System.out.println("SimpleInvocationHandler.invoked"); } else { throw new IllegalArgumentException("Interface method does not support param(s) : " + args); } return null; }} Since SimpleIntf.print() does not accept any parameters and also does not return any value, in the invoke method of SimpleInvocationHandler, we double check the intention behind the actual invoker. In other words, we check that no parameters are passed and we return null only. Now, we have all the necessary classes to implement a proxy for SimpleIntf interface. Let us now execute it by writing a Test class. ch13JdkProxysrcTest.java import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; public class Test { public static void main(String[] args) { InvocationHandler handler = new SimpleInvocationHandler(); SimpleIntf simpleIntf = (SimpleIntf)Proxy.newProxyInstance (SimpleIntf.class.getClassLoader(),new Class[] { SimpleIntf. class }, handler); simpleIntf.print(); } } The wiring of the above described interfaces and classes are better represented in the UML class diagram in the following figure: The above figure shows the relationship between various classes and interfaces in the sample. $Proxy0 class represents the actual proxy class generated on the fly and as you can deduce it from the class diagram. $Proxy0 is a type of our interface (SimpleIntf). To build the sample, first change directory to ch13JdkProxy and execute ant as shown here: cd ch13JdkProxyant The command ant run will execute the Test class which will print out the following in the console: ServiceMix JBI Proxy Java proxies for the JBI endpoints can be created in ServiceMix using JSR181 components. For this, the requirement is that the JBI endpoints should expose a WSDL. A jsr181:endpoint takes a value for the serviceInterface attribute. The JBI container will be able to generate the WSDL out of this serviceInterface. Thus, if we have a jsr181:endpoint exposing service to the JBI bus, it is possible to provide a proxy for that service too. The basic configuration for defining a JBI proxy is shown as follows: <jsr181:proxy id="proxyBean" container="#jbi" interfaceName="test:HelloPortType" type="test.Hello" /> Once a proxy is defined, the same can then be referenced from your client bean or from one of your components. The proxied JBI endpoint can then be invoked just like a normal POJO. If you want to define a JBI proxy within a SU, you can follow the configuration given as follows: <jsr181:endpoint annotations="none" service="test:echoService" serviceInterface="test.Echo"> <jsr181:pojo> <bean class="test.EchoProxy"> <property name="echo"> <jsr181:proxy service="test:EchoService" context="#context" type="test.IService" /> </property> </bean> </jsr181:pojo></jsr181:endpoint> Let us now look into a few examples to make the concept clearer. JBI Proxy Sample Implementing Compatible Interface First, we will create a JBI proxy implementing an interface compatible with the target service. Then, in place of the target service we will use the proxy instance, so that any calls intended for the target service will be first routed to the proxy. The proxy in turn will delegate the call to the target service. The structural relationship between various classes participating in the interaction is shown in the following figure: Here, EchoProxyService is the class which we later expose in the JBI bus as the service. This class implements the IEcho interface. In order to demonstrate the proxy, EchoProxyService doesn't implement the service as such, instead depends on the JbiProxy derived out of another class TargetService. The TargetService contains the actual service code. As you can see, both the EchoProxyService and the TargetService implement the same interface. Proxy Code Listing The codebase for the sample is located in the folder ch13JbiProxy1_CompatibleInterface1_JsrProxysrc. This folder contains an interface IEcho and two other classes implementing the IEcho interface namely EchoProxyService and TargetService. These classes are explained here: IEcho.java: The IEcho interface declares a single method echo which takes a String parameter and returns a String. public interface IEcho{ public String echo(String input);} EchoProxyService.java: EchoProxyService is a convenient class which will act as mechanism for routing requests to the JBI proxy. Moreover, EchoProxyService implements the above interface IEcho. public class EchoProxyService implements IEcho{ private IEcho echo; public void setEcho(IEcho echo) { this.echo = echo; } public String echo(String input) { System.out.println("EchoProxyService.echo. this = " + this); return echo.echo(input); }} TargetService.java: TargetService also implements the interface IEcho. TargetService is supposed to be our target service, and we will be generating a JBI proxy for the TargetService. public class TargetService implements IEcho{ public String echo(String input) { System.out.println("TargetService.echo : String. this = " + this); return input; }}
Read more
  • 0
  • 0
  • 1600

article-image-understanding-dotnetnuke-core-architecture-extension
Packt
06 Apr 2010
8 min read
Save for later

Understanding the DotNetNuke Core Architecture- An Extension

Packt
06 Apr 2010
8 min read
The global files The Global.asax.vb and Globals.vb files share similar names but the parts they play in DotNetNuke are vastly different. The Global.asax.vb is used by DotNetNuke to handle application-level events raised by the ASP.NET runtime. The Globals.vb file, on the other hand, is a public module (which is the same as a static class in C#) that contains global utility functions. Before we take a look at these fi les, we first want to look at what object is being passed around in these transactions. Global.asax.vb Much of the logic that used to reside in the Global.asax.vb fi le has now been abstracted to the HTTP modules. We will look into the code that remains. Application_Start When the fi rst request is made to your application (when the fi rst user accesses the portal), a pool of HttpApplication instances are created and the Application_Start event is fi red. This will (theoretically) fire just once and on the first HttpApplication object in the pool. When there is inactivity on your portal for a certain amount of time, the application (or application pool) will be recycled. When the pool is recycled, your application will restart (and this event will fi re again) when the next request is made for your application. As the new version of DotNetNuke uses the .NET website structure, you will find the Global.asax.vb fi le in the App_Code folder. In the Application_Start, we are loading all of the confi gured providers to ensure they are available to the rest of the framework when needed. These are performed in the Application_Start because we want them to be called only once. Private Sub Application_Start(ByVal Sender As Object, ByVal E AsEventArgs)If Config.GetSetting("ServerName") = "" ThenServerName = Server.MachineNameElseServerName = Config.GetSetting("ServerName")End IfComponentFactory.Container = New SimpleContainer()'Install most Providers as Singleton LifeStyleComponentFactory.InstallComponents _(New ProviderInstaller("data", GetType(DotNetNuke.Data.DataProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("caching", GeType(Services.Cache.CachingProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("logging", GetType(Services.Log.EventLog.LoggingProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("scheduling", GetType(Services.Scheduling.SchedulingProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("searchIndex", GetType(Services.Search.IndexingProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("searchDataStore", GetType(Services.Search.SearchDataStoreProvider)))ComponentFactory.InstallComponents_(New ProviderInstaller("friendlyUrl", GetType(Services.Url.FriendlyUrl.FriendlyUrlProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("members", GetType(DotNetNuke.Security.Membership.MembershipProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("roles", GetType(DotNetNuke.Security.Roles.RoleProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("profiles", GetType(DotNetNuke.Security.Profile.ProfileProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("permissions", GetType(DotNetNuke.Security.Permissions.PermissionProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("outputCaching", GetType(DotNetNuke.Services.OutputCache.OutputCachingProvider)))ComponentFactory.InstallComponents _(New ProviderInstaller("moduleCaching", GetType(DotNetNuke.Services.ModuleCache.ModuleCachingProvider)))Dim provider As DotNetNuke.Security.Permissions.PermissionProvider = _DotNetNuke.ComponentModel.ComponentFactory.GetComponent _(Of DotNetNuke.Security.Permissions.PermissionProvider)()If provider Is Nothing ThenComponentFactory.RegisterComponentInstance _(Of DotNetNuke.Security.Permissions.PermissionProvider) _(New DotNetNuke.Security.Permissions.PermissionProvider())End If'Install Navigation and Html Providers as NewInstanceLifestyle (ie a new instance is generated each time the type isrequested, as there are often multiple instances on the page)ComponentFactory.InstallComponents _(New ProviderInstaller("htmlEditor", _GetType(Modules.HTMLEditorProvider.HtmlEditorProvider), _ComponentLifeStyleType.Transient))ComponentFactory.InstallComponents _(New ProviderInstaller("navigationControl", _GetType(Modules.NavigationProvider.NavigationProvider), _ComponentLifeStyleType.Transient))End Sub In previous versions of DotNetNuke, there was a great deal happening in this method. However, this code has been moved into various methods inside of the Initialize class. This was done to support the integrated pipeline mode of IIS 7. If you would like to take a look at what is happening inside of the Initialize class, it can be found in the Common folder of the DotNetNuke.Library project. Examining Application_BeginRequest The Application_BeginRequest is called for each request made to your application. In other words, this will fi re every time a page (tab), or other web request handlers such as a web service or an ashx handler, is accessed in your portal. This section is used to implement the scheduler built into DotNetNuke. Starting in version 2.0, two items, "users online" and "site log", require recurring operations. Also in this method is the call to the Initialize.Init() method that was moved out of the Appli cation_Startup method as mentioned previously. You can fi nd out more about the scheduler by looking at the DotNetNuke Scheduler.pdf document (only if you download the documentation pack). Also note that, there is a host setting that defi nes the running mode of a scheduler, you can check for a scheduler run on every request to your portal, or run the scheduler in a timer mode. Private Sub Global_BeginRequest(ByVal sender As Object, _ByVal e As EventArgs) Handles Me.BeginRequestDim app As HttpApplication = CType(sender, HttpApplication)Dim Request As HttpRequest = app.RequestIf Request.Url.LocalPath.ToLower.EndsWith("scriptresource.axd") _OrElse Request.Url.LocalPath.ToLower.EndsWith("webresource.axd") _OrElse Request.Url.LocalPath.ToLower.EndsWith("gif") _OrElse Request.Url.LocalPath.ToLower.EndsWith("jpg") _OrElse Request.Url.LocalPath.ToLower.EndsWith("css") _OrElse Request.Url.LocalPath.ToLower.EndsWith("js") ThenExit SubEnd If' all of the logic which was previously in Application_Start' was moved to Init() in order to support IIS7 integrated pipelinemode' ( which no longer provides access to HTTP context withinApplication_Start )Initialize.Init(app)'run schedule if in Request modeInitialize.RunSchedule(Request)End Sub The Globals.vb file As part of the namespace-reorganization effort associated with DotNetNuke version 3.0, general utility functions, constants, and enumerations have all been placed in a public module (as just mentioned, module here refers to VB.NET module keyword, not a DotNetNuke module) named Globals . As items in a .NET module are inherently shared, you do not need to instantiate an object in order to use the functions found here. In this module, you will find not only global constants, as shown in the following code: Public Const glbRoleAllUsers As String = "-1"Public Const glbRoleSuperUser As String = "-2"Public Const glbRoleUnauthUser As String = "-3"Public Const glbRoleNothing As String = "-4"Public Const glbRoleAllUsersName As String = "All Users"Public Const glbRoleSuperUserName As String = "Superuser"Public Const glbRoleUnauthUserName As String ="Unauthenticated Users"Public Const glbDefaultPage As String = "Default.aspx"Public Const glbHostSkinFolder As String = "_default"Public Const glbDefaultControlPanel As String = "Admin/ControlPanel/IconBar.ascx"Public Const glbDefaultPane As String = "ContentPane"Public Const glbImageFileTypes As String = "jpg,jpeg,jpe,gif,bmp,png,swf"Public Const glbConfigFolder As String = "Config"Public Const glbAboutPage As String = "about.htm"Public Const glbDotNetNukeConfig As String = "DotNetNuke.config"Public Const glbSuperUserAppName As Integer = -1Public Const glbProtectedExtension As String = ".resources"Public Const glbEmailRegEx As String = "b[a-zA-Z0-9._%-+']+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}b"Public Const glbScriptFormat As String = "<script type=""text/javascript"" src=""{0}"" ></script>"   but a tremendous number of public functions to help you do everything, from retrieving the domain name, as shown: Public Function GetDomainName(ByVal Request As HttpRequest, ByValParsePortNumber As Boolean) As String to setting the focus on a page: Public Sub SetFormFocus(ByVal control As Control) This one file contains a wealth of information for the developer. As there are more than 3070 lines in the fi le and the methods are fairly straightforward, we will not be stepping through this code. The Globals.vb fi le can now be found in the DotNetNuke.Library project in the Common folder. Putting it all together We have spent some time looking at some of the major pieces that make up the core architecture. You might be asking yourself how all this works together. In this section, we will walk you through an overview version of what happens when a user requests a page on your portal. A shown in the preceding diagram, when a user requests any page on your portal, the HTTP Modules that have been declared in the web.config file are hooked into the pipeline. Typically, these modules use the Init method to attach event handlers to application events. The request then goes through the Global.asax page. As just mentioned, some of the events fi red here will be intercepted and processed by the HTTP modules, but the call to run the scheduler will happen in this fi le. Next, the page that was requested, Default.aspx, will be processed. As we stated at the beginning of this article, all requests are sent to the Default.aspx page and all the controls and skins needed for the page are created dynamically by reading the tabID from the requested URL. So let's begin by looking at the HTML for this page.
Read more
  • 0
  • 0
  • 1913

article-image-core-principles-service-oriented-architecture-biztalk-server-2009
Packt
06 Apr 2010
11 min read
Save for later

The core principles of a service-oriented architecture with BizTalk Server 2009

Packt
06 Apr 2010
11 min read
So what exactly is a service? A service is essentially a well-defined interface to an autonomous chunk of functionality, which usually corresponds to a specific business process. That might sound a lot like a regular old object-oriented component to you. While both services and components have commonality in that they expose discrete interfaces of functionality, a service is more focused on the capabilities offered than the packaging. Services are meant to be higher-level, business-oriented offerings that provide technology abstraction and interoperability within a multipurpose "services" tier of your architecture. What makes up a service? Typically you'll find: Contract: Explains what operations the service exposes, types of messages, and exchange patterns supported by this service, and any policies that explain how this service is used. Messages: The data payload exchanged between the service consumer and provider. Implementation: The portion of the service which actually processes the requests, executes the expected business functionality, and optionally returns a response. Service provider: The host of the service which publishes the interface and manages the lifetime of the service. Service consumer: Ideally, a service has someone using it. The service consumer is aware of the available service operations and knows how to discover the provider and determine what type of messages to transmit. Facade: Optionally, a targeted facade may be offered to particularly service consumers. This sort of interface may offer a more simplified perspective on the service, or provide a coarse-grained avenue for service invocation. What is the point of building a service? I'd say it's to construct an asset capable of being reused which means that it's a discrete, discoverable, self-describing entity that can be accessed regardless of platform or technology. Service-oriented architecture is defined as an architectural discipline based on loosely-coupled, autonomous chunks of business functionality which can be used to construct composite applications. Through the rest of this article we get a chance to flesh out many of the concepts that underlie that statement. Let's go ahead and take a look at a few of the principles and characteristics that I consider most important to a successful service-oriented BizTalk solution. As part of each one, I'll explain the thinking behind the principle and then call out how it can be applied to BizTalk Server solutions. Loosely coupled Many of the fundamental SOA principles actually stem from this particular one. In virtually all cases, some form of coupling between components is inevitable. The only way we can effectively build software is to have interrelations between the various components that make up the delivered product. However, when architecting solutions, we have distinct design decisions to make regarding the extent to which application components are coupled. Loose coupling is all about establishing relationships with minimal dependencies. What would a tightly-coupled application look like? In such an application, we'd find components that maintained intimate knowledge of each others' working parts and engaged in frequent, chatty synchronous calls amongst themselves. Many components in the application would retain state and allow consumers to manipulate that state data. Transactions that take place in a tightly coupled application probably adhere to a two-phase commit strategy where all components must succeed together in order for each data interaction to be finalized. The complete solution has its ensemble of components compiled together and singularly deployed to one technology platform. In order to run properly, these tightly-coupled components rely on the full availability of each component to fulfill the requests made of them. On the other hand, a loosely-coupled application employs a wildly different set of characteristics. Components in this sort of application share only a contract and keep their implementation details hidden. Rarely preserving state data, these components rely on less frequent communication where chunky input containing all the data the component needs to satisfy its requestors is shared. Any transactions in these types of applications often follow a compensation strategy where we don't assume that all components can or will commit their changes at the same time. This class of solution can be incrementally deployed to a mix of host technologies. Asynchronous communication between components, often through a broker, enables a less stringent operational dependency between the components that comprise the solution. What makes a solution loosely coupled then? Notably, the primary information shared by a component is its interface. The consuming component possesses no knowledge of the internal implementation details. The contract relationship suffices as a means of explaining how the target component is used. Another trait of loosely coupled solutions is coarse-grained interfaces that encourage the transmission of full data entities as opposed to fine-grained interfaces, which accept small subsets of data. Because loosely-coupled components do not share state information, a thicker input message containing a complete impression of the entity is best. Loosely-coupled applications also welcome the addition of a broker which proxies the (often asynchronous) communication between components. This mediator permits a rich decoupling where runtime binding between components can be dynamic and components can forgo an operational dependency on each other. Let's take a look at an example of loose coupling that sits utterly outside the realm of technology. Completely non-technical loose coupling exampleWhen I go to a restaurant and place an order with my waiter, he captures the request on his pad and sends that request to the kitchen. The order pad (the contract) contains all the data needed by the kitchen chef to create my meal. The restaurant owner can bring in a new waiter or rotate his chefs and the restaurant shouldn't skip a beat as both roles (services) serve distinct functions where the written order is the intersection point and highlight of their relationship. Why does loose coupling matter? By designing a loosely-coupled solution, you provide a level of protection against the changes that the application will inevitably require over its life span. We have to reduce the impact of such changes while making it possible to deploy necessary updates in an efficient manner. How does this apply to BizTalk Server solutions? A good portion of the BizTalk Server architecture was built with loose coupling in mind. Think about the BizTalk MessageBox which acts as a broker facilitating communication between ports and orchestrations while limiting any tight coupling. Receive ports and send ports are very loosely coupled and in many cases, have absolutely no awareness of each other. The publish-and-subscribe bus thrives on the asynchronous transfer of self-describing messages between stateless endpoints. Let's look at a few recommendations of how to build loosely-coupled BizTalk applications. Orchestrations are a prime place where you can either go with a tightly-coupled or loosely-coupled design route. For instance, when sketching out your orchestration process, it's sure tempting to use that Transform shape to convert from one message type to another. However, a version change to that map will require a modification of the calling orchestration. When mapping to or from data structures associated with external systems, it's wiser to push those maps to the edges (receive/send ports) and not embed a direct link to the map within the orchestration. BizTalk easily generates schemas for line-of-business (LOB) systems and consumed services. To interact with these schemas in a very loosely coupled fashion, consider defining stable entity schemas (i.e. "canonical schemas") that are used within an orchestration, and only map to the format of the LOB system in the send port. For example, if you need to send a piece of data into an Oracle database table, you can certainly include a map within an orchestration which instantiates the Oracle message. However, this will create a tight coupling between the orchestration and the database structure. To better insulate against future changes to the database schema, consider using a generic intermediate data format in the orchestration and only transforming to the Oracle-specific format in the send port. How about those logical ports that we add to orchestrations to facilitate the transfer of messages in and out of the workflow process? When configuring those ports, the Port Configuration Wizard asks you if you want to associate the port to a physical endpoint via the Specify Now option. Once again, pretty tempting. If you know that the message will arrive at an orchestration via a FILE adapter, why not just go ahead and configure that now and let Visual Studio.NET create the corresponding physical ports during deployment? While you can independently control the auto-generated physical ports later on, it's a bad idea to embed transport details inside the orchestration file. On each subsequent deployment from Visual Studio.NET, the generated receive port will have any out-of-band changes overwritten by the deployment action. Chaining orchestration together is a tricky endeavor and one that can leave you in a messy state if you are too quick with a design decision. By "chaining orchestrations", I mean exploiting multiple orchestrations to implement a business process. There are a few options at your disposal listed here and ordered from most coupled to least coupled. Call Orchestration or Start Orchestration shape: An orchestration uses these shapes in order to kick off an additional workflow process. The Call Orchestration is used for synchronous connection with the new orchestration while the Start Orchestration is a fire-and-forget action. This is a useful tactic for sharing state data (for example variables, messages, ports) from the source orchestration to the target. However, both options require a tight coupling of the source orchestration to the target. Version changes to the target orchestration would likely require a redeployment of the source orchestration. Partner direct bound ports: These provide you the capability to communicate between orchestrations using ports. In the forward partner direct binding scenario, the sender has a strong coupling to the receiver, while the receiver knows nothing about the sender. This works well in situations where there are numerous senders and only one receiver. Inverse partner direct binding means that there is a tight coupling between the receiver and the sender. The sender doesn't know who will receive the command, so this scenario is intended for cases where there are many receivers for a single sender. In both cases, you have tight coupling on one end, with loose-coupling on the other. MessageBox direct binding: This is the most loosely-coupled way to share data between orchestrations. When you send a message out of an orchestration through a port marked for MessageBox direct binding, you are simply placing a message onto the bus for anyone to consume. The source orchestration has no idea where the data is going, and the recipients have no idea where it's been. MessageBox direct binding provides a very loosely-coupled way to send messages between different orchestrations and endpoints. Critical pointWhile MessageBox direct binding is great, you do lose the ability to send the additional state data that a Call Orchestration shape will provide you. So, as with all architectural decisions, you need to decide if the sacrifice (loose coupling, higher latency) is worth the additional capabilities. Decisions can be made during BizTalk messaging configuration that promote a loosely-coupled BizTalk landscape. For example, both receive ports and send ports allow for the application of maps to messages flying past. In each case, multiple maps can be added. This does NOT mean that all the maps will be applied to the message, but rather, it allows for sending multiple different message types in, and emitting a single type (or even multiple types) out the other side. By applying transformation at the earliest and latest moments of bus processing, you loosely couple external formats and systems from internal canonical formats. We should simply assume that all upstream and downstream systems will change over time, and configure our application accordingly. Another means for loosely coupling BizTalk solutions involves the exploitation of the publish-subscribe architecture that makes up the BizTalk message bus. Instead of building solely point-to-point solutions and figuring that a SOAP interface makes you service oriented, you should also consider loosely coupling the relationship between the service input and where the data actually ends up. We can craft a series of routing decision that take into account message content or context and direct the message to one or more relevant processes/endpoints. While point-to-point solutions may be appropriate for many cases, don't neglect a more distributed pattern where the data publisher does not need to explicitly know exactly how their data will be processed and routed by the message bus. When identifying subscriptions for our send ports, we should avoid tight coupling to metadata attributes that might limit the reuse of the port. For instance, you should try to create subscriptions on either the message type or message content instead of context attributes such as the inbound receive port name. Ports should be tightly coupled to the MessageBox and messages it stores, not to attributes of its publisher. That said, there are clearly cases where a subscriber is specifically looking for data that corresponds to a targeted piece of metadata such as the subject line of the email received by BizTalk. As always, design your solution in a way that solves your business problem in an efficient manner.
Read more
  • 0
  • 0
  • 2852

article-image-understanding-dotnetnuke-core-architecture
Packt
06 Apr 2010
13 min read
Save for later

Understanding the DotNetNuke Core Architecture

Packt
06 Apr 2010
13 min read
Architecture overview As opposed to traditional web applications that may rely on a multitude of web pages to deliver content, DotNetNuke uses a single main page called Default.aspx. The content for this page is generated dynamically by using a tabID value to retrieve the skin and modules needed to build the page requested, from the DotNetNuke database. Before we move on, we should discuss what is meant by a tab and a page. As you read this article, you will notice the word "tab" is sometimes used when referring to pages in your DotNetNuke portal. In the original IBuySpy application, pages were referred to as tabs because they resembled tabs when added to the page. IBuySpy application, the skeleton ASP.NET Framework, was created by Microsoft to demonstrate ASP.NET features, and DotNetNuke was originally derived from it. This continued in the original versions of the DotNetNuke project. Starting with version 3.0, and continuing with version 5.2.x, there has been an ongoing effort to rename most of these instances to reflect what they really are: pages. Most references to "tabs" have been changed to "pages", but the conversion is not complete. For this reason, you will see both—tabs and pages—in the database, in the project files, and in this text. We will use these terms interchangeably throughout this text as we look into the core architecture of DNN. We will begin with a general overview of what happens when a user requests a page on your DotNetNuke portal. The process for rendering a page in DotNetNuke works like this: a user navigates to a page on your portal; this calls the Default.aspx page, passing the tabid parameter in the querystring to let the application identify the page being requested. The example http://www.dotnetnuke.com/Default. aspx?tabid=476 demonstrates this. DotNetNuke 3.2 introduced something called URL rewriting. This takes the querystring shown above and rewrites it so that it is in a format that helps increase search engine hits. We will cover the HTTP module that is responsible for this in more detail later in this article. The rewritten URL would resemble http://localhost/DotNetNuke/Home.aspx. This assumes that the page name for tabid 476 is Home. While referring to URLs in this article we will be using the non-rewritten version of the URL. URL rewriting can be turned off in the friendly URL section of the Host Settings page. The querystring value (?tabid=476) is sent to the database, where the information required for the page is retrieved, as shown in the following diagram: The portal that the user is accessing can be determined in a number of ways, but as you can see from the Tabs table (see the following screenshot), each page/tab contains a reference to the portal it belongs to in the PortalID field. Once the server has a reference to the page that the user requested (using the tabID), it can determine what modules belong to that page. Although there are many more tables involved in this process, you can see that these tables hold not only the page and modules needed to generate the page, but also what pane to place them on (PaneName) and what container skin to apply (ContainerSrc). All of this information is returned to the web server, and the Default.aspx page is constructed with it and returned to the user who requested it along with the required modules and skins, as shown in the following diagram. Now, this is of course a very general overview of the process, but as we work through this article, we will delve deeper into the code that makes this process work, and in the end, show a request work its way through the framework to deliver a page to a user. Diving into the core There are over 160,000 lines of code in the DotNetNuke application. There is no practical (or even possible) way to cover the entire code base. In this section, we will go in depth into what I believe are the main portions of the code base: the PortalSettings as well as the companion classes found in the portals folder; the web.config file including the HTTP Modules and Providers; and the Global.asax and Globals.vb files. We will start our discussion of the core with two objects that play an integral part in the construction of the architecture. The Context object and the PortalSettings class will both be referred to quite often in the code, and so it is important that you have a good understanding of what they do. Using the Context object in your application ASP .NET has taken intrinsic objects like the Request and the Application objects and wrapped them together with other relevant items into an intrinsic object called Context. The Context object (HttpContext) can be found in the System.Web namespace. In the following table, you will find some of the objects that make up the HttpContext object. Title Description Application Gets the HttpApplicationState object for the current HTTP request. Cache Gets the Cache object for the current HTTP request. Current Gets the HttpContext object for the current HTTP request. This is a static (shared in VB) property of the HttpContext class, through which you access all other instance properties discussed in this table, that together enable you to process and respond to an HTTP request. Items Gets a key-value collection that can be used to organize and share data between an IHttpModule and an IHttpHandler during an HTTP request. Request Gets the HttpRequest object for the current HTTP request. This is used to extract data submitted by the client, and information about the client itself (for example, IP ), and the current request. Response Gets the HttpResponse object for the current HTTP response. This is used to send data to the client together with other response-related information such as headers, cacheability, redirect information, and so on. Server Gets the HttpServerUtility object that provides methods used in processing web requests. Session Gets the HttpSessionState instance for the current HTTP request. User Gets or sets security information for the current HTTP request. Notice that most of the descriptions talk about the "current" request object, or the "current" response object. The Global.asax file, which we will look at soon, reacts on every single request made to your application, and so it is only concerned with whoever is "currently" accessing a resource. The HttpContext object contains all HTTP-specific information about an individual HTTP request. In particular, the HttpContext.Current property can give you the context for the current request from anywhere in the application domain. The DotNetNuke core relies on the HttpContext.Current property to hold everything from the application name to the portal settings and through this makes it available to you. The PortalSettings class The portal settings play a major role in the dynamic generation of your pages and as such will be referred to quite often in the other portions of the code. The portal settings are represented by the PortalSettings class which you will find in the EntitiesPortalPortalSettings.vb file. As you can see from the private variables in this class, most of what goes on in your portal will at some point needto access this object. This object will hold everything from the ID of the portal to the default language, and as we will see later, is responsible for determining the skins and modules needed for each page. Private _PortalId As IntegerPrivate _PortalName As StringPrivate _HomeDirectory As StringPrivate _LogoFile As StringPrivate _FooterText As StringPrivate _ExpiryDate As DatePrivate _UserRegistration As IntegerPrivate _BannerAdvertising As IntegerPrivate _Currency As StringPrivate _AdministratorId As IntegerPrivate _Email As StringPrivate _HostFee As SinglePrivate _HostSpace As IntegerPrivate _PageQuota As IntegerPrivate _UserQuota As IntegerPrivate _AdministratorRoleId As IntegerPrivate _AdministratorRoleName As StringPrivate _RegisteredRoleId As IntegerPrivate _RegisteredRoleName As StringPrivate _Description As StringPrivate _KeyWords As StringPrivate _BackgroundFile As StringPrivate _GUID As GuidPrivate _SiteLogHistory As IntegerPrivate _AdminTabId As IntegerPrivate _SuperTabId As IntegerPrivate _SplashTabId As IntegerPrivate _HomeTabId As IntegerPrivate _LoginTabId As IntegerPrivate _UserTabId As IntegerPrivate _DefaultLanguage As StringPrivate _TimeZoneOffset As IntegerPrivate _Version As StringPrivate _ActiveTab As TabInfoPrivate _PortalAlias As PortalAliasInfoPrivate _AdminContainer As SkinInfoPrivate _AdminSkin As SkinInfoPrivate _PortalContainer As SkinInfoPrivate _PortalSkin As SkinInfoPrivate _Users As IntegerPrivate _Pages As Integer The PortalSettings class itself is simple. It is filled by using one of the constructors that accepts one or more parameters. These constructors then call the private GetPortalSettings method . The method is passed a tabID and a PortalInfo object. You already know that the tabID represents the ID of the page being requested, but the PortalInfo object is something new. This class can be found in the same folder as the PortalSettings class and contains the basic information about a portal such as PortalID, PortalName, and Description. However, from the PortalSettings object, we can retrieve all the information associated with the portal. If you look at the code inside the constructors, you will see that the PortalController object is used to retrieve the PortalInfo object. The PortalInfo object is saved in cache for the time that is specifi ed on the Host Settings page. A drop-down box on the Host Settings page (DesktopModulesAdminHostSettingsHostSettings.ascx) is used to set the cache. No caching:0 Light caching:1 Moderate caching:3 Heavy caching:6 The value in this dropdown ranges from 0 to 6; the code in the DataCache object takes the value set in the drop-down and multiplies it by 20 to determine the cache duration. Once the cache time is set, the method checks if the PortalSettings object already resides there. Retrieving these settings from the database for every request would cause your site to run slowly, so placing them in a cache for the duration you select helps increase the speed of your site. Recent versions of DotNetNuke have focused heavily on providing an extensive caching service. An example of this can be seen in the following code: Dim cacheKey As String = String.Format(DataCache.PortalCacheKey,PortalId.ToString())Return CBO.GetCachedObject(Of PortalInfo)(New CacheItemArgs(cacheKey, DataCache.PortalCacheTimeOut,DataCache.PortalCachePriority, PortalId),AddressOf GetPortalCallback) We can see in the previous code that the CBO object is used to return an object from the cache. CBO is an object that is seen frequently throughout the DotNetNuke core. This object's primary function is to return the populated business object. This is done in several ways using different methods provided by CBO. Some methods are used to map data from an IDataReader to the properties of a business object. However, in this example, the Get CachedObject method handles the logic needed to determine if the object should be retrieved from the cache or from the database. If the object is not already cached, it will use the GetPortalCallback method passed to the method to retrieve the portal settings from the database. This method is located in the PortalController class (EntitiesPortalPortalController.vb) and is responsible for retrieving the portal information from the database. Dim portalID As Integer = DirectCast(cacheItemArgs.ParamList(0),Integer)Return CBO.FillObject(Of PortalInfo)(DataProvider.Instance _.GetPortal(portalID, Entities.Host.Host.ContentLocale.ToString)) This will fi ll the PortalInfo object (EntitiesPortalPortalInfo.vb), which as we mentioned, holds the portal information. This object in turn is returned to the GetCachedObject method. Once this is complete, the object is then cached to help prevent the need to call the database during the next request for the portal information. There is also a section of code (not shown) that verifi es whether the object was successfully stored in the cache and adds an entry to the event log if the item failed to be cached. ' if we retrieved a valid object and we are using cachingIf objObject IsNot Nothing AndAlso timeOut > 0 Then' save the object in the cacheDataCache.SetCache(cacheItemArgs.CacheKey, objObject, _cacheItemArgs.CacheDependency, Cache.NoAbsoluteExpiration, _TimeSpan.FromMinutes(timeOut), cacheItemArgs.CachePriority, _cacheItemArgs.CacheCallback)…End If After the portal settings are saved, the properties of the current tab information are retrieved and populated in the ActiveTab property. The current tab is retrieved by using the tabID that was originally passed to the constructor. This is handled by the VerifyPortalTab method and done by getting a list of all of the tabs for the current portal. Like the portal settings themselves, the tabs are saved in cache to boost performance. The calls to the caching provider, this time, are handled by the TabController (EntitiesTabsTabController.vb). In the last VerifyPortalTab method, the code will loop through all of the host and non-host tabs, returned by the TabController, for the site until the current tab is located. ' find the tab in the portalTabs collectionIf TabId <> Null.NullInteger ThenIf portalTabs.TryGetValue(TabId, objTab) Then'Check if Tab has been deleted (is in recycle bin)If Not (objTab.IsDeleted) ThenMe.ActiveTab = objTab.Clone()isVerified = TrueEnd IfEnd IfEnd If' find the tab in the hostTabs collectionIf Not isVerified AndAlso TabId <> Null.NullInteger ThenIf hostTabs.TryGetValue(TabId, objTab) Then'Check if Tab has been deleted (is in recycle bin)If Not (objTab.IsDeleted) ThenMe.ActiveTab = objTab.Clone()isVerified = TrueEnd IfEnd IfEnd If If the tab was not found in either of these collections, the code attempts to use the splash page, home page, or the fi rst page of the non-host pages. After the current tab is located, further handling of some of its properties is done back in the GetPortalSettings method. This includes formatting the path for the skin and default container used by the page, as well as collecting information on the modules placed on the page. Me.ActiveTab.SkinSrc = _SkinController.FormatSkinSrc(Me.ActiveTab.SkinSrc, Me)Me.ActiveTab.SkinPath = _SkinController.FormatSkinPath(Me.ActiveTab.SkinSrc)…For Each kvp As KeyValuePair(Of Integer, ModuleInfo) In _objModules.GetTabModules(Me.ActiveTab.TabID)' clone the module object _( to avoid creating an object reference to the data cache )Dim cloneModule As ModuleInfo = kvp.Value.Clone' set custom propertiesIf Null.IsNull(cloneModule.StartDate) ThencloneModule.StartDate = Date.MinValueEnd IfIf Null.IsNull(cloneModule.EndDate) ThencloneModule.EndDate = Date.MaxValueEnd If' containerIf cloneModule.ContainerSrc = "" ThencloneModule.ContainerSrc = Me.ActiveTab.ContainerSrcEnd IfcloneModule.ContainerSrc = _SkinController.FormatSkinSrc(cloneModule.ContainerSrc, Me)cloneModule.ContainerPath = _SkinController.FormatSkinPath(cloneModule.ContainerSrc)' process tab panesIf objPaneModules.ContainsKey(cloneModule.PaneName) = False ThenobjPaneModules.Add(cloneModule.PaneName, 0)End IfcloneModule.PaneModuleCount = 0If Not cloneModule.IsDeleted ThenobjPaneModules(cloneModule.PaneName) = _objPaneModules(cloneModule.PaneName) + 1cloneModule.PaneModuleIndex = _objPaneModules(cloneModule.PaneName) - 1End IfMe.ActiveTab.Modules.Add(cloneModule)Next We have now discussed some of the highlights of the PortalSettings object as well as how it is populated with the information it contains. In doing so, we also saw abrief example of the robust caching service provided by DotNetNuke. You will see the PortalSettings class referenced many times in the core DotNetNuke code, so gaining a good understanding of how this class works will help you to become more familiar with the DNN code base. You will also fi nd this object to be very helpful while building custom extensions for DotNetNuke. The caching provider itself is a large topic, and reaches beyond the scope of this article. However, simply understanding how to work with it in the ways shown in these examples should satisfy the needs of most developers. It is important to note that, you can get any type of object cached by DNN by passing in a key for your object to DataCache.SetCache method, together with the data, and some optional arguments. While fetching the object back from DataCache.GetCache, you pass in the same key, and check the result. A non-null (non-Nothing in VB) return value means you have fetched the object successfully from the cache, otherwise you would need to fetch it from the database.
Read more
  • 0
  • 0
  • 4138
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-biztalk-server-standard-message-exchange-patterns-and-types-service
Packt
06 Apr 2010
4 min read
Save for later

BizTalk Server: Standard Message Exchange Patterns and Types of Service

Packt
06 Apr 2010
4 min read
Identifying Standard Message Exchange Patterns When we talk about Message Exchange Patterns, or MEPs, we're considering the direction and timing of data between the client and service. How do I get into the bus and what are the implications of those choices? Let's discuss the four primary options. Request/Response services This is probably the pattern that's most familiar to you. We're all comfortable making a function call to a component and waiting for a response. When a service uses this pattern, it's frequently performing a remote procedure call where the caller accesses functionality on the distant service and is blocked until either a timeout occurs or until the receiver sends a response that is expected by the caller. As we'll see below, while this pattern may set developers at ease, it may encourage bad behavior. Nevertheless, the cases where request/response services make the most sense are fine-grained functions and mashup services. If you need a list of active contracts that a hospital has with your company, then a request/response operation fits best. The client application should wait until that response is received before moving on to the next portion of the application. Or, let's say my web portal is calling an aggregate service, which takes contact data from five different systems and mashes them up into a single data entity that is then returned to the caller. This data is being requested for immediate presentation to an end user, and thus it's logical to solicit information from a service and wait to draw the screen until the completed result is loaded. BizTalk Server 2009 has full support for both consuming and publishing services adhering to a request/response pattern. When exposing request/response operations through BizTalk orchestrations, the orchestration port's Communication Pattern is set to Request-Response and the Port direction of communication is equal to I'll be receiving a request and sending a response. Once this orchestration port is bound to a physical request/response receive port, BizTalk takes care of correlating the response message with the appropriate thread that made the request. This is significant because by default, BizTalk is a purely asynchronous messaging engine. Even when you configure BizTalk Server to behave in a request/response fashion, it's only putting a facade on the standard underlying plumbing. A synchronous BizTalk service interface actually sits on top of a sophisticated mechanism of correlating MessageBox communication to simulate a request/response pattern. When consuming request/response services from BizTalk from an orchestration, the orchestration port's Communication Pattern is set to Request-Response and the Port direction of communication is equal to I'll be sending a request and receiving a response. The corresponding physical send port uses a solicit-response pattern and allows the user to set up both pipelines and maps for the inbound and outbound messages. One concern with either publishing or consuming request/response services is the issue of blocking and timeouts. From a BizTalk perspective, this means that whenever you publish an orchestration as a request/response service, you should always verify that the logic residing between inbound and outbound transmissions will either complete or fail within a relatively brief amount of time. This dictates wrapping this logic inside an orchestration Scope shape with a preset timeout that is longer than the standard web service timeout interval. For consuming services, a request/response pattern forces the orchestration to block and wait for the response to be returned. If the service response isn't necessary for processing to continue, consider using a Parallel shape that isolates the service interaction pattern on a dedicated branch. This way, the execution of unrelated workflow steps can proceed even though the downstream service is yet to respond.
Read more
  • 0
  • 0
  • 3516

article-image-organizing-your-content-effectively-using-joomla-15-sequel
Packt
06 Apr 2010
5 min read
Save for later

Organizing your Content Effectively using Joomla 1.5- A Sequel

Packt
06 Apr 2010
5 min read
Time for action - move content from one category to another The Activities section contains some articles that you might want to move to the News section. Let's clean up the Activities - Meetings category and move anything topical into the News - General News category: Navigate to Content | Article Manager. From the list, select the items you want to move from the Meetings category to the General News category. In this example, we've selected two articles: Click on Move on the toolbar. You'll be taken to the Move Articles screen: In the Move to Section/Category list, select News/General News. At the far right-hand side, you can check which articles are being moved. Click on Save. In the Article Manager screen, the three articles are now part of the News section. You can check this by clicking on the News link on the frontend Main Menu. What just happened? You've stood the real life challenge of content management! Now, you're not only able to create a sound content structure for your website, but you also know how to improve on it. By adding a new container for all news items and moving existing news content there you've now made room for growth on the SRUP site. Have a go hero - moving entire categories Sometimes you might want to move an entire category and all its contents to another section. Try this out for yourself-it's not much different from moving articles. Imagine you'd like to move the Reviews category from the Ugly Paintings section to another section. In the Category Manager, select the category you want to move and click on the Move button. Select the section you want to move things to, and click on Save. It's just as straightforward to move the entire category including all of its article contents back again. This flexibility is great when you're setting up or rearranging your site. Renaming sections or categories As we've just seen, Joomla! allows you to easily rearrange your site structure and its contents. You can also rename sections and categories that already contain articles; no content will be lost. Time for action - rename a section On your client's website there's an Activities section. Your client wants to make it clear this section is not about activities organized by other art societies-it's only about SRUP. Could you please change the name of the section to SRUP Activities? It's a breeze. Navigate to Content | Section Manager and click on the title of the Activities section to open it for editing. In the Section: [Edit] screen, change the Title to SRUP Activities. In the Alias: field, remove the existing alias (remember, the Alias is Joomla!'s internal name for the article used when creating user-friendly URLs). Leave this box blank; Joomla! will fill it with srup-activities when you apply or save your changes. You can check that now by clicking on Apply. You'll notice the Alias box is filled out automatically. Click on Save. What just happened? By changing a section or category name, all of Joomla!'s internal references to the name are updated automatically. All articles and categories in the renamed section will reflect the changes you made. In the Article Manager, for example, all items that belonged to the Activities section are now updated to show they are in the SRUP Activities section. No manual labor here and more importantly, nothing is lost! On the frontend, the new section name shows up on the section overview page when the user clicks on the Activities link: Have a go hero - name and rename! Using appropriate, short, and descriptive labels for sections and categories (and for the menu links pointing to them) is really essential. After all, these are the words that guide your visitors to the content you want them to discover. It's a good idea to tweak these labels until you're perfectly happy with them. To modify the names of categories, navigate to the Category Manager; it's similar to changing section names. Maybe you would like to change menu link labels too, as these don't automatically change with the category or section name. Try to find short and appropriate menu link labels. To change menu link labels, navigate to the Main Menu, select any of the menu items and change what's in the Title field (that is, SRUP Activities). When changing Titles (of Sections/Categories/Menu Link Items) make sure to clear the contents of the Alias box. Joomla! will automatically create an Alias for the new Title. Changing section and category settings You've already created a good deal of sections and categories without altering any of the default settings. In some cases, however, you might want some more control over the section or category you're editing. In the table below you can see the options that are available in the Section/Category: [New] or Section/Category: [Edit] screen. Basically, you can customize these settings for two purposes: To determine whether a section or category is visible (and which user groups can see it) To add a short descriptive text whenever the section or category contents are displayed. We'll cover both the Section and Category edit screen in the overview next, as all settings and options are identical. The only difference is that when adding a category, Joomla! wants you to specify the section that holds the new category. This is what the Section: [New] and the Category: [New] screen look like:
Read more
  • 0
  • 0
  • 1582

article-image-installation-and-getting-started-firebug
Packt
05 Apr 2010
3 min read
Save for later

Installation and Getting Started with Firebug

Packt
05 Apr 2010
3 min read
What is Firebug? Firebug is a free, open source tool that is available as a Mozilla Firefox extension, and allows debugging, editing, and monitoring of any website's CSS, HTML, DOM, and JavaScript. It also allows performance analysis of a website. Furthermore, it has a JavaScript console for logging errors and watching values. Firebug has many other tools to enhance the productivity of today's web developer. Firebug integrates with Firefox to put a wealth of development tools at our fingertips while we browse a website. Firebug allows us to understand and analyze the complex interactions that take place between various elements of any web page when it is loaded by a browser. Firebug simply makes it easier to develop websites/applications. It is one of the best web development extensions for Firefox. Firebug provides all the tools that a web developer needs to analyze, debug, and monitor JavaScript, CSS, HTML, and AJAX. It also includes a debugger, error console, command line, and a variety of useful inspectors. Although Firebug allows us to make changes to the source code of our web page, the changes are made to the copy of the HTML code that has been sent to the browser by the server. Any changes to the code are made in the copy that is available with the browser. The changes don't get reflected in the code that is on the server. So, in order to ensure that the changes are permanent, corresponding changes have to be made in the code that resides on the server. The history of Firebug Firebug was initially developed by Joe Hewitt, one of the original Firefox creators, while working at Parakey Inc. Facebook purchased Parakey in July, 2007. Currently, the open source development and extension of Firebug is overseen by the Firebug Working Group. It has representation from Mozilla, Google, Yahoo, IBM, Facebook, and many other companies. Firebug 1.0 Beta was released in December 2006. Firebug usage has grown very fast since then. Approximately 1.3 million users have Firebug installed as of January 2009. The latest version of Firebug is 1.5. Today, Firebug has a very open and thriving community. Some individuals as well as some companies have developed very useful plugins on top of Firebug. The need for Firebug During the 90s, websites were mostly static HTML pages, JavaScript code was considered a hack, and there were no interactions between page components on the browser side. The situation is not the same anymore. Today's websites are a product of several distinct technologies and web developers must be proficient in all of them—HTML, CSS, JavaScript, DOM, and AJAX, among others. Complex interactions happen between various page components on the browser side. However, web browsers have always focused on the needs of the end users; as a result, web developers have long been deprived of a good tool on the client/browser side to help them develop and debug their code. Firebug fills this gap very nicely—it provides all the tools that today's web developer needs in order to be productive and efficient with code that runs in the browser. Firebug capabilities Firebug has a host of features that allow us to do the following (and much more!): Inspect and edit HTML Inspect and edit CSS and visualize CSS metrics Use a performance tuning application Profile and debug JavaScript Explore the DOM Analyze AJAX calls
Read more
  • 0
  • 0
  • 4306

article-image-managing-data-mysql
Packt
01 Apr 2010
8 min read
Save for later

Managing Data in MySQL

Packt
01 Apr 2010
8 min read
Exporting data to a simple CSV file While databases are a great tool to store and manage your data, you sometimes need to extract some of the data from your database to use it in another tool (a spreadsheet application being the most prominent example for this). In this recipe, we will show you how to utilize the respective MySQL commands for exporting data from a given table into a fi le that can easily be imported by other programs. Getting ready To step through this recipe, you will need a running MySQL database server and a working installation of a SQL client (like MySQL Query Browser or the mysql command line tool). You will also need to identify a suitable export target, which has to meet the following requirements: The MySQL server process must have write access to the target file The target file must not exist The export target file is located on the machine that runs your MySQL server, not on the client side! If you do not have file access to the MySQL server, you could instead use export functions of MySQL clients like MySQL Query Browser. In addition, a user with FILE privilege is needed (we will use an account named sample_install for the following steps; see also Chapter 8 Creating an installation user). Finally, we need some data to export. Throughout this recipe, we will assume that the data to export is stored in a table named table1 inside the database sample. As export target, we will use the file C:/target.csv (MySQL accepts slashes instead of backslashes in Windows path expressions). This is a file on the machine that runs the MySQL server instance, so in this example MySQL is assumed to be running on a Windows machine. To access the results from the client, you have to have access to the file (for example, using a fi le share or executing the MySQL client on the same machine as the server). How to do it... Connect to the database using the sample_install account. Issue the following SQL command: mysql> SELECT * FROM sample.table1 INTO OUTFILE 'C:/target.csv'FIELDS ENCLOSED BY '"' TERMINATED BY ';' ESCAPED BY '"' LINESTERMINATED BY 'rn'; Please note that when using a backslash instead of a slash in the target file's path, you have to use C:target.csv (double backslash for escaping) instead. If you do not give a path, but only a fi le name, the target fi le will be placed in the data directory of the currently selected schema of your MySQL server. How it works... In the previous SQL statement, a file C:/target.csv was created, which contains the content of the table sample.table1. The file contains a separate line for each row of the table, and each line is terminated by a sequence of a carriage return and a line feed character. This line ending was defined by the LINES TERMINATED BY 'rn' portion of the command. Each line contains the values of each column of the row. The values are separated by semicolons, as stated in the TERMINATED BY ';' clause. Every value is enclosed by a double quotation mark ("), which results from the FIELDS ENCLOSED BY '"' option. When writing the data to the target fi le, no character conversion takes place; the data is exported using the binary character set. This should be kept in mind especially when importing tables with different character sets for some of its values. You might wonder why we chose the semicolon instead of a comma as the field separator. This is simply because of a greatly improved Microsoft Excel compatibility (you can simply open the resulting files), without the need to import external data from the fi les. But you can, however, open these fi les in a different spreadsheet program (like OpenOffice.org Calc) as well. If you think the usage of semicolons is in contradiction to the notion of a CSV file, think of it as a Character Separated File. The use of double quotes to enclose single values prevents problems when field values contain semicolons (or generally the field separator character). These are not recognized as field separators if they are enclosed in double quotes. There's more... While the previous SELECT … INTO OUTFILE statement will work well in most cases, there are some circumstances in which you still might encounter problems. The following topics will show you how to handle some of those. Handling errors if the target fi le already exists If you try to execute the SELECT … INTO OUTFILE statement twice, an error File 'C:/target.csv' already exists occurs. This is due to a security feature in MySQL that makes sure that you cannot overwrite existing fi les using the SELECT … INTO OUTFILE statement. This makes perfect sense if you think about the consequences. If this were not the case, you could overwrite the MySQL data files using a simple SELECT because MySQL server needs write access to its data directories. As a result, you have to choose different target files for each export (or remove old files in advance). Unfortunately, it is not possible to use a non-constant file name (like a variable) in the SELECT … INTO OUTFILE export statement. If you wish to use different file names, for example, with a time stamp as part of the file name, you have to construct the statement inside a variable value before executing it:   mysql> SET @selInOutfileCmd := concat("SELECT * FROM sample.table1 INTOOUTFILE 'C:/target-", DATE_FORMAT(now(),'%Y-%m-%d_%H%i%s'), ".csv' FIELDSENCLOSED BY '"' TERMINATED BY ';' ESCAPED BY '"' LINES TERMINATED BY'rn';");mysql> PREPARE statement FROM @selInOutfileCmd;mysql> EXECUTE statement; The first SET statement constructs a string, which contains a SELECT statement. While it is not allowed to use variables for statements directly, you can construct a string that contains a statement and use variables for this. With the next two lines, you prepare a statement from the string and execute it. Handling NULL values Without further handling, NULL values in the data you export using the previous statement would show up as "N in the resulting file. This combination is not recognized, for example, by Microsoft Excel, which breaks the file (for typical usage). To prevent this, you need to replace NULL entries by appropriate values. Assuming that the table sample.table1 consists of a numeric column a and a character column b, you should use the following statement: mysql> SELECT IFNULL(a, 0), IFNULL(b, "NULL") FROM sample.table1 INTOOUTFILE 'C:/target.csv' FIELDS ENCLOSED BY '"' TERMINATED BY ';' ESCAPEDBY '"' LINES TERMINATED BY 'rn'; The downside to this approach is that you have to list all fi elds in which a NULL value might occur. Handling line breaks If you try to export values that contain the same character combination used for line termination in the SELECT … INTO OUTFILE statement, MySQL will try to escape the character combination with the characters defined by the ESCAPED BY clause. However, this will not always work the way it is intended. You will typically define rn as the line separators. With this constellation, values that contain a simple line break n will not cause problems, as they are exported without any conversion and can be imported to Microsoft Excel flawlessly. If your values happen to contain a combination of carriage return and line feed, the rn characters will be prepended with an escape character ("rn), but still the target file cannot be imported correctly. Therefore, you need to convert the full line breaks to simple line breaks: mysql> SELECT a, REPLACE(b, 'rn', 'n') FROM sample.table1 INTO OUTFILE'C:/target.csv' FIELDS ENCLOSED BY '"' TERMINATED BY ';' ESCAPED BY '"'LINES TERMINATED BY 'rn'; With this statement, you will export only line breaks n, which are typically accepted for import by other programs. Including headers For better understanding, you might want to include headers in your target fi le. You can do so by using a UNION construct: mysql> (SELECT 'Column a', 'Column b') UNION ALL (SELECT * FROM sample.table1 INTO OUTFILE 'C:/target.csv' FIELDS ENCLOSED BY '"' TERMINATED BY';' ESCAPED BY '"' LINES TERMINATED BY 'rn'); The resulting file will contain an additional first line with the given headers from the first SELECT clause.
Read more
  • 0
  • 0
  • 5928
article-image-rendering-web-pages-pdf-using-railo-open-source
Packt
01 Apr 2010
6 min read
Save for later

Rendering web pages to PDF using Railo Open Source

Packt
01 Apr 2010
6 min read
As a pre-requisite for this tutorial, you should be familiar with html, css and web technologies in general. You do not need to know any CFML (ColdFusion Markup Language). You should have an understanding of databases, particularly MySQL, which we will use in this example. Server environment For this tutorial, we are using a virtual machine (using VirtualBox) running Windows 2003 Server Standard, IIS, MySQL 5.1, and Railo 3.1. The code we will be writing is not platform specific. You can just as easily implement this on Linux or Mac OSX Server with MySQL and Apache. Website architecture Lets assume that we have the HTML layout code provided to us for our website, and that we need to make it “work” on the web server, pulling its page content from a MySQL database. In addition, we will add the capability for any page to render itself as a PDF for printing purposes. You will want to make sure you have done a few things first: Make sure Railo and MySQL are running on your server (or VM) Make sure you created a MySQL database, and a user that has permission to use your database For development (as opposed to production web servers), try running Railo Express, which runs in a terminal window. This allows you to see the templates it is running, and the full stack trace of errors when they occur. Setting up the Railo datasource The first thing we need to do is setup a Railo datasource. This named datasource will define our database credentials for our website. Open a web browser to the Railo Server Administrator, which is usually located at: http://your.server.com/railo-context/admin/server.cfm. Check the Railo documentation if you have trouble opening up the administrator. Enter your password to login. Once logged in, click on the Services / Datasource link in the left navigation. At the bottom of this page is where you can create a new datasource. Enter a datasource name (Letters and numbers only, no spaces, and start with a letter) and select MySQL as the database type. On the next screen, enter the MySQL server host name or ip address, and username and password for the user you created. All of the other settings can be kept with their default values. Scroll to the bottom and click on the “Create” button to complete the datasource configuration. Railo Administrator will test your connection, so you can confirm that it is setup properly. We created the datasource in the “server” context. When you deploy an application on a production server, you should create your datasources in the “web” context, so that it is only available to the website that needs it. Datasources created in the server context are accessible from any website on the same server. Setting up the website structure In the document root of your website (or in the directory you choose for this tutorial), you will need a couple of files. index.cfm – this is the default document, like index.html or default.htm header.cfm – this is the top portion of web pages, what appears above your page content. This is where you would put your html “design” code. footer.cfm – this is the bottom portion of your web pages, what shows up after your page content. This is where you would put your html “design” code. layout.css – the basic CSS layout for our pages styles.css – the CSS styles for your page content Let's look first at header.cfm: This file contains what you would expect to see at the top of a standard HTML web page, including head, title, meta tags, etc. There are a few different tags included in the content however. Any tags that begin with <cf…> are CFML language tags, that are processed by Railo and removed from the source code before the page is sent to your web browser. Just like PHP or ASP.net code, if somebody views the source of your web page, they won’t see your CFML code, but rather, they will see the html code, and any code that your CFML tags generate. <cfparam name="title" default="Untitled" /> This tag defines and sets a default value for a variable named “title.” This value can be overridden using a <cfset …> tag which we will see later. #title#</cfoutput> Any content inside <cfoutput>…</cfoutput> tags will be included in the output to your web browser. In this case, the title variable is written to the page output. As with all <cf..> tags, the <cfoutput> tags themselves will be removed from the web page output. Anything inside # characters will be evaluated as an expression. So if your code was <cfoutput>title</cfoutput>, then the literal word “title” would be included in your page output. When you put # characters around it, Railo will evaluate the expression and replace it with the result.</cfoutput></cf..> header.cfm also includes the two .css files we need for our layout and styles. These are standard css which should be familiar to you, and won’t be covered in this article. Let's next look at index.cfm <cfset title="Home Page"> This first tag sets a local variable called “title” and sets its value to “Home Page.” <cfinclude template="header.cfm"> This tag includes the file “header.cfm” into the current page, which means that any page output (the html, head, title, etc. tags) will be included in this page’s output. Notice that we set the local variable title in our page, and it gets used in the header.cfm file. Local variables are available to any pages that are included in the requested web page. The “Hello World” content is the main textual content of this web page, and can be any html or CFML generated content you want. After the main content, another <cfinclude…> tag includes footer.cfm, which includes the expected end of page tags such as </body> and </html> Take a look If you open your web browser and browse to index.cfm, you will see your basic web page layout, with a page title, and Hello World content. If you view the page source, you should see the combined content of the header.cfm, index.cfm and footer.cfm, with no <cf…> tags in the output, only pure HTML. You can easily organize and create static web pages like this, and like many other programming languages, structuring your website like this has many benefits. If you make a change to your header or footer, then all your pages inherit the change immediately. Likewise if you design a new layout or style for your site, applying it once to your header and footer then applies it to your entire website.
Read more
  • 0
  • 0
  • 11663

article-image-configuring-mysql
Packt
01 Apr 2010
14 min read
Save for later

Configuring MySQL

Packt
01 Apr 2010
14 min read
Let's get started. Setting up a fixed InnoDB tablespace When using the InnoDB storage engine of MySQL, the data is typically not stored in a per-database or per-table directory structure, but in several dedicated files, which collectively contain the so-called tablespace. By default (when installing MySQL using the configuration wizard) InnoDB is confi gured to have one small file to store data in, and this file grows as needed. While this is a very fl exible and economical confi guration to start with, this approach also has some drawbacks: there is no reserved space for your data, so you have to rely on free disk space every time your data grows. Also, if your database grows bigger, the file will grow to a size which makes it hard to handle—a dozen files of 1 GB each are typically easier to manage than one clumsy 12 GB file. Large data files might, for example, cause problems if you try to put those files into an archive for backup or data transmission purposes. Even if the 2 GB limit is not present any more for the current file systems, many compression programs still have problems dealing with large files. And finally, the constant adaptation of the file in InnoDB's default configuration size will cause a (small, but existent) performance hit if your database grows. The following recipe will show you how to define a fixed tablespace for your InnoDB installation, by which you can avoid these drawbacks of the InnoDB default configuration. Getting ready To install a fixed tablespace, you will have to reflect about some aspects: how much tablespace should be reserved for your database, and how to size the single data files which in sum constitute the tablespace. Note that once your database completely allocates your tablespace, you will run into table full errors (error code 1114) when trying to add new data to your database. Additionally, you have to make sure that your current InnoDB tablespace is completely empty. Ideally, you should set up the tablespace of a freshly installed MySQL instance, in which case this prerequisite is given. To check whether any InnoDB tables exist in your database, execute the following statement and delete the given tables until the result is empty: SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.tables WHERE engine="InnoDB"; If your database already contains data stored in InnoDB tables that you do not want to lose, you will have to create a backup of your database and recover the data from it when you are done with the recipe. Please refer to the chapter Backing Up and Restoring MySQL Data for further information on this. And finally, you have to make sure that the InnoDB data directory (as defined by the innodb_data_home_dir variable) features sufficient free disk space to store the InnoDB data files. For the following example, we will use a fixed tablespace with a size of 500 MB and a maximal file size of 200 MB. How to do it... Open the MySQL configuration file (my.ini or my.cnf) in a text editor. Identify the line starting with innodb_data_file_path in the [mysqld] section. If no such line exists, add the line to the file. Change the line innodb_data_file_path to read as follows: innodb_data_file_path=ibdata1:200M;ibdata2:200M;ibdata3:100M Save the changed configuration file. Shut down your database instance (if running). Delete previous InnoDB data files (typically called ibdata1, ibdata2, and so on) from the directory defined by the innodb_data_home_dir variable. Delete previous InnoDB logfiles (named ib_logfile0, ib_logfile1, so on) from the directory defined by the innodb_log_group_home_dir variable. If innodb_log_group_home_dir is not configured explicitly, it defaults to the datadir directory. Start your database. Wait for all data and log files to be created. Depending on the size of your tablespace and the speed of your disk system, creation of InnoDB data fi les can take a significant amount of time (several minutes is not an uncommon time for larger installations). During this initialization sequence, MySQL is started but it will not accept any requests. How it works... Steps 1 through 4—and particularly 3—cover the actual change to be made to the MySQL configuration, which is necessary to adapt the InnoDB tablespace settings. The value of the innodb_data_file_path variable consists of a list of data file definitions that are separated by semicolons. Each data file definition is constructed of a fi le name and a file size with a colon as a separator. The size can be expressed as a plain numeric value, which defines the size of the data file in bytes. If the numeric value has a K, M, or G postfix, the number is interpreted as Kilobytes, Megabytes, or Gigabytes respectively. The list length is not limited to the three entries of our example; if you want to split a large tablespace into relatively small files, the list can easily contain dozens of data file definitions. If your tablespace consists of more than 10 files, we propose naming the first nine files ibdata01 through ibdata09 (instead of ibdata1 and so forth; note the zero), so that the files are listed in a more consistent order when they are displayed in your file browser or command line interface. Step 5 is prerequisite to the steps following after it, as deletion of vital InnoDB files while the system is still running is obviously not a good idea. In step 6, old data files are deleted to prevent collision with the new files. If InnoDB detects an existing file whose size differs from the size defined in the innodb_data_file_path variable, it will not initialize successfully. Hence, this step ensures that new, properly saved files can be created during the next MySQL start. Note that deletion of the InnoDB data files is only suffi cient if all InnoDB tables were deleted previously (as discussed in the Getting ready section). Alternatively, you could delete all *.frm files for InnoDB tables from the MySQL data directory, but we do not encourage this approach (clean deletion using DROP TABLE statements should be preferred over manual intervention in MySQL data directories whenever possible). Step 7 is necessary to prevent InnoDB errors after the data files are created, as the InnoDB engine refuses to start if the log files are older than the tablespace files. With steps 8 and 9, the new settings take effect. When starting the database for the first time after changes being made to the InnoDB tablespace configuration, take a look at the MySQL error log to make sure the settings were accepted and no errors have occurred. The MySQL error log after the first start with the new settings will look similar to this:   InnoDB: The first specified data file E:MySQLInnoDBTestibdata1 didnot exist:InnoDB: a new database to be created!091115 21:35:56 InnoDB: Setting file E:MySQLInnoDBTestibdata1 sizeto 200 MBInnoDB: Database physically writes the file full: wait...InnoDB: Progress in MB: 100 200...InnoDB: Progress in MB: 100091115 21:36:19 InnoDB: Log file .ib_logfile0 did not exist: new tobe createdInnoDB: Setting log file .ib_logfile0 size to 24 MBInnoDB: Database physically writes the file full: wait......InnoDB: Doublewrite buffer not found: creating newInnoDB: Doublewrite buffer createdInnoDB: Creating foreign key constraint system tablesInnoDB: Foreign key constraint system tables created091115 21:36:22 InnoDB: Started; log sequence number 0 0091115 21:36:22 [Note] C:Program FilesMySQLMySQL Server 5.1binmysqld: ready for connections.Version: '5.1.31-community-log' socket: '' port: 3306 MySQLCommunity Server (GPL)   There's more... If you already use a fixed tablespace, and you want to increase the available space, you can simply append additional files to your fixed tablespace by adding additional data file definitions to the current innodb_data_file_path variable setting. If you simply append additional files, you do not have to empty your tablespace first, but you can change the confi guration and simply restart your database. Nevertheless, as with all changes to the confi guration, we strongly encourage creating a backup of your database first.   Setting up an auto-extending InnoDB tablespace The previous recipe demonstrates how to define a tablespace with a certain fixed size. While this provides maximum control and predictability, you have to block disk space based on the estimate of the maximum size required in the foreseeable future. As long as you store less data in your database than the reserved tablespace allows for, this basically means some disk space is wasted. This especially holds true if your setting does not allow for a separate file system exclusively for your MySQL instance, because then other applications compete for disk space as well. In these cases, a dynamic tablespace that starts with little space and grows as needed could be an alternative. The following recipe will show you how to achieve this. Getting ready When defining an auto-extending tablespace, you should first have an idea about the minimum tablespace requirements of your database, which will set the initial size of the tablespace. Furthermore, you have to decide whether you want to split your initial tablespace into files of a certain maximum size (for better file handling). If the above settings are identical to the current settings and you only want to make your tablespace grow automatically if necessary, you will be able to keep your data. Otherwise, you have to empty your current InnoDB tablespace completely (please refer to the previous recipe Setting up a fixed InnoDB tablespace for details). As with all major confi guration changes to your database, we strongly advise you to create a backup of your data first. If you have to empty your tablespace, you can use this backup to recover your data after the changes are completed. Again, please refer to the chapter Backing Up and Restoring MySQL Data for further information on this. And as before, you have to make sure that there is enough disk space available in the innodb_data_home_dir directory—not only for the initial database size, but also for the anticipated growth of your database. The recipe also requires you to shut down your database temporarily; so you have to make sure all clients are disconnected while performing the required steps to prevent conflicting access. As the recipe demands changes to your MySQL confi guration file (my.cnf or my.ini), you need write access to this file. For the following example, we will use an auto-extending tablespace with an initial size of 100 MB and a file size of 50 MB. How to do it... Open the MySQL configuration file (my.ini or my.cnf) in a text editor. Identify the line starting with innodb_data_file_path in the [mysqld] section. If no such line exists, add the line to the file. Change the line innodb_data_file_path to read as follows: innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend Note that no file defi nition except the last one must have the :autoextend option; you will run into errors otherwise. Save the changed confi guration file. Shut down your database instance (if running). Delete previous InnoDB data files (typically called ibdata1, ibdata2, and so on) from the directory defi ned by the innodb_data_home_dir variable. Delete previous InnoDB logfiles (named ib_logfile0, ib_logfile1, and so on) from the directory defined by the innodb_log_group_home_dir variable. If innodb_log_group_home_dir is not configured explicitly, it defaults to the datadir directory Start your database. Wait for all data and log files to be created. Depending on the size of your tablespace and the speed of your disk system, creation of InnoDB data files can take a signifi cant amount of time (several minutes is not an uncommon time for larger installations). During this initialization sequence, MySQL is started but will not accept any requests. When starting the database for the first time after changes being made to the InnoDB tablespace configuration, take a look at the MySQL error log to make sure the settings were accepted and no errors have occurred. How it works... The above steps are basically identical to the steps of the previous recipe Setting up a fixed InnoDB tablespace, the only difference being the definition of the innodb_data_file_path variable. In this recipe, we create two files of 50 MB size, the last one having an additional :autoextend property. If the innodb_data_file_path variable is not set explicitly, it defaults to the value ibdata1:10M:autoextend. As data gets inserted into the database, parts of the tablespace will be allocated. As soon as the 100 MB of initial tablespace is not sufficient any more, the file ibdata2 will become larger to match the additional tablespace requirements. Note that the :autoextend option causes the tablespace files to be extended automatically, but they are not automatically reduced in size again if the space requirements decrease. Please refer to the Decreasing InnoDB tablespace recipe for instructions on how to free unused tablespace. There's more... The recipe only covers the basic aspects of auto-extending tablespaces; the following sections provide insight into some more advanced topics. Making an existing tablespace auto-extensible If you already have a database with live data in place and you want to change your current fixed configuration to use the auto-extension feature, you can simply add the :autoextend option to the last file definition. Let us assume a current configuration like the following: innodb_data_file_path=ibdata1:50M;ibdata2:50M The respective configuration with auto-extension will look like this: innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend In this case, do not empty the InnoDB tablespace first, you can simply change the configuration file and restart your database, and you should be fine. As with all configuration changes, however, we strongly recommend to back up your database before editing these settings even in this case. Controlling the steps of tablespace extension The amount by which the size of the auto-extending tablespace file is increased is controlled by the innodb_autoextend_increment variable. The value of this variable defines the number of Megabytes by which the tablespace is enlarged. By default, 8 MB are added to the file if the current tablespace is no longer sufficient. Limiting the size of an auto-extending tablespace If you want to use an auto-extending tablespace, but also want to limit the maximum size your tablespace will grow to, you can add a maximum size for the auto-extended tablespace file by using the :autoextend:max:[size] option. The [size] portion is a placeholder for a size definition using the same notation as the size description for the tablespace file itself, which means a numeric value and an optional K, M, or G modifier (for sizes in Kilo-, Mega-, and Gigabytes). As an example, if you want to have a tiny initial tablespace of 10 MB, which is extended as needed, but with an upper limit of 2 GB, you would enter the following line to your MySQL configuration file: innodb_data_file_path=ibdata1:10M:autoextend:max:2G Note that if the maximum size is reached, you will run into errors when trying to add new data to your database. Adding a new auto-extending data file Imagine an auto-extending tablespace with an auto-extended file, which grew so large over time that you want to prevent the file from growing further and want to append a new auto-extending data file to the tablespace. You can do so using the following steps: Shut down your database instance. Look up the exact size of the auto-extended InnoDB data file (the last file in your current configuration). Put the exact size as the tablespace fi le size definition into the innodb_data_file_path configuration (number of bytes without any K, M, or G modifier), and add a new auto-extending data file. Restart your database. As an example, if your current confi guration reads ibdata1:10M:autoextend and the ibdata1 file has an actual size of 44,040,192 bytes, change configuration to innodb_data_file_path=ibdata1:44040192;ibdata2:10M:autoextend:max:2G.  
Read more
  • 0
  • 0
  • 4359

article-image-drupal-and-ubercart-2x-install-ready-made-drupal-theme
Packt
31 Mar 2010
5 min read
Save for later

Drupal and Ubercart 2.x: Install a Ready-made Drupal Theme

Packt
31 Mar 2010
5 min read
Install a ready-made Drupal theme We have to admit that Drupal was not famous for its plethora of available themes. Until recently, the Drupal community was focused on developing the backend, debugging the code, and creating new modules. The release of Drupal 6 made theming much easier and helped the theming community to grow. Now, there are not only thousands of Drupal themes, but also dozens of themes designed and customized especially for Ubercart. Basic principles when choosing a theme Choosing a theme for your online shop is not an easy task. Moreover, it can be even harder considering that you want to promote specific items from your catalog, you need to change first page items often, and you need to rapidly communicate offers and loyalty policies and other business-related stuff. Ubercart-specific themes mostly target the following special areas: Product catalog Shopping cart Product-specific views You should keep these layout regions in mind, while going through the following section on theme selection. Before you search for any kind of theme layout, provide your neurons with enough input to inspire you and help you decide. Perform a quick Google search for online shops in your target market to get some inspiration and track down sites that make you, as a customer, feel comfortable during product searching and navigation. If you decide to search for professional help, a list of existing sites will help you to communicate your preferences much more directly. What better place to search for inspiration and successful practices than Ubercart's live site repository! You will find good practices and see how mostly people like you (without any development background) have solved all the problems that might occur during your search for themes.http://www.ubercart.org/site Next we describe the main user interface components that you should keep in mind when deciding for your online shop: Number of columns: The number of columns depends on the block information you want to provide to your end customers. If you need widgets that display on every page, information about who bought what, and product or kit suggestions, go with three columns. You will find a plethora of two-column Drupal themes and many three-column Drupal themes, while some of them can alternate between two and three columns. Color scheme: From a design perspective, you should choose a color scheme that matches your company logo and business profile. For instance, if your store sells wooden toys, go with something more comic such as rounded corners, but if you are a consulting firm, you should go with something more professional. Many themes let you choose color schemes dynamically; however, always keep in mind that color is a rather easy modification from the CSS. You can get great color combination ideas from COLOURlovers online service (http://www.colourlovers.com/) that match your logo and business colors. Be careful though. If you choose a complex theme with rounded corners, lots of images, and multiple backgrounds, it may be difficult to modify it. Drupal version: Make sure the Drupal theme you choose is compatible with the version of Drupal you are running. Before using a Drupal theme, look up notes on the theme to see if there are any known bugs or problems with it. If you are not a programmer, you do not want a Drupal theme that has open issues. Extra features: Many Drupal themes expose a large set of configuration options to the end users. Various functionality such as post author's visibility or color scheme selection are welcome for managing the initial setup. Moreover, you can change appearance in non-invasive ways for your online marque. Regions available: We have discussed column layouts, but for the Drupal template engine to show its full capabilities and customization, you definitely need multiple regions. The more regions, the more choices you have for where to put blocks of content. Therefore, you can have space for customizing new affiliate ads for instance, or provide information about some special deals, or even configure your main online shop page, as we will see in the next section. Further customization and updates: When you choose your theme, don't just keep the functionality of version 1.0 in mind, but consider all of the future business plans for approaching your target market and raising sales figures. Make a three-year plan and try to visualize any future actions that should be taken into account from day one. Although you can change themes easily, you are better off choosing a more flexible theme ahead of time than having to change the theme as your website grows. Always bear in mind that the famous razor of Occam also applies to online shop theme design. Keep it simple and professional by choosing simple layouts, which allow ease of use for the end user and ease further customize designs and themes (changing colors, adding a custom image header, and so on). Before you start, clearly define your timeline, risks, total theme budget, and skills. Theming is usually 25-40% of the budget of an entire online shop project. Drupal's theming engine closely integrates with actual functionality and many features are encapsulated inside the theme itself. There are a number of different ways in which you can get yourself the best theme for your online store. We will go through all these approaches with useful comments on what options best suits your needs.
Read more
  • 0
  • 0
  • 2562
article-image-customizing-layout-themes-php-nuke
Packt
31 Mar 2010
23 min read
Save for later

Customizing Layout with Themes in PHP-Nuke

Packt
31 Mar 2010
23 min read
Creating a PHP-Nuke theme gives your site its own special look, distinguishing it from other PHP-Nuke-created sites and offers an effective outlet for your creative talents. Creating a theme requires some knowledge of HTML, confidence in working with CSS and PHP, but most important is some imagination and creativity! Unlike the tasks we have tackled in previous articles, where we have been working exclusively through a web browser to control and configure PHP-Nuke, working with themes is the start of a new era in your PHP-Nuke skills; editing the code files of PHP-Nuke itself. Fortunately, the design of PHP-Nuke means that our theme work won't be tampering with the inner workings of PHP-Nuke. However, becoming confident in handling the mixture of HTML and PHP code that is a PHP-Nuke theme will prepare you for the more advanced work ahead, when we really get to grips with PHP-Nuke at the code level. In this article, we will look at: Theme management Templates in themes Changing the page header Working with the stylesheet Changing blocks Changing the format of stories What Does a Theme Control? Despite the fact that we say 'themes control the look and feel of your site', a theme does not determine every aspect of the page output. PHP-Nuke is an incredibly versatile application, but it cannot produce every website imaginable. Appearance First of all, the appearance of the page can be controlled through the use of colors, fonts, font sizes, weights, and so on. This can either be done through the use of CSS styles or HTML. You can also add JavaScript for fancier effects, or even Flash animations, Java applets, or sounds—anything that you can add to a standard HTML page. Graphical aspects of the page such as the site banner, background images, and so on, are under the care of the theme. There are also some modules that allow their standard graphical icons to be overridden with images from a theme. Page Layout Roughly speaking, a PHP-Nuke page consists of three parts; the top bit, the bit in the middle, and the bit at the bottom! The top bit—the header—usually contains a site logo and such things as a horizontal navigation bar for going directly to important parts of your site. The bottom bit—the footer—contains the copyright message. In between the header and the footer, the output is usually divided into three columns. The left-hand column typically contains blocks, displayed one of top each other, the middle column contains the module output, and the right-hand column contains more blocks. The layout of these columns (their width for example) is controlled by the theme. You may have noticed that the right-hand column is generally only displayed on the homepage of a PHP-Nuke site; this too, is something that is controlled by the theme. The appearance of the blocks is controlled by the theme; PHP-Nuke provides the title of the block and its content, and the theme will generally 'frame' these to produce the familiar block look. The theme also determines how the description of stories appears on the homepage. In addition, the theme determines how the full text of the story, its extended text, is displayed. We've talked about how the theme controls the 'look' of things. The theme also allows you to add other site-related data to your page; for example the name of the site can appear, and the site slogan, and you can even add such things as the user's name with a friendly welcome message. Theme Management Basically, a theme is a folder that sits inside the themes folder in your PHP-Nuke installation. Different themes correspond to different folders in the themes folder, and adding or removing a theme is as straightforward as adding or removing the relevant folder from the themes folder. By default, you will find around 14 themes in a standard PHP-Nuke installation. DeepBlue is the default theme. Themes can be chosen in one of two ways: By the administrator: You can simply select the required theme from the General Site Info panel of the Site Preferences administration menu and save the changes. The theme selected by the administrator is the default theme for the site and will be seen by all users of the site, registered or unregistered. By the user: Users can override the default theme set by the administrator from the Themes option of the Your Account module. This sets a new, personal, theme that will be displayed to that user. Note that this isn't a theme especially customized for that user; it is just one chosen from the list of standard themes installed on your site. Unregistered visitors do not have an option to choose a theme; they have to become registered users. Theme File Structure Let's start with the default theme, DeepBlue. If you open up the DeepBlue folder within the themes folder in the root of your PHP-Nuke installation, you will find three folders and two files. The three folders are: forums: This folder contains the theme for the Forums module. This is not strictly a requirement of a PHP-Nuke theme, and not every PHP-Nuke theme has a forums theme. The Forums module (otherwise known as phpBB) has its own theme 'engine'. The purpose of including a theme for the forums is that you have consistency between the rest of your PHP-Nuke display and the phpBB display. images: This folder contains the image files used by your theme. These include the site logo, background images, and graphics for blocks among others. As mentioned earlier, within this folder can be other folders containing images to override the standard icons. style: This folder contains the CSS files for your theme. Usually, there is one CSS file in the style folder, style.css. Each theme will make use of its style.css file, and this is the file into which we will add our style definitions when the time comes. Of the two files, index.html is simply there to prevent people browsing to your themes folder and seeing what it contains; visiting this page in a browser simply produces a blank page. It is a very simple security measure. The themes.php file is a PHP code file, and is where all the action happens. This file must always exist within a theme folder. We will concentrate on this file later when we customize the theme. In other themes you will find more files; we will look at these later. Installing a New Theme Installing and uninstalling themes comes down to adding or removing folders from the themes folder, and whenever a list of available themes is presented, either in the Site Preferences menu or the Your Accounts module, PHP-Nuke refreshes this list by getting the names of the folders in the themes folder. You will find a huge range of themes on the Web. For example, there is a gallery of themes at: http://nukecops.com/modules.php?set_albumName=packs&op=modload&name=Gallery& file=index&include=view_album.php Many of these are themes written for older versions of PHP-Nuke, but most are still compatible with the newer releases. There is also a live demonstration of some themes at: http://www.portedmods.com/styles/ On this page you can select the new theme and see it applied immediately, before you download it. Removing an Existing Theme To remove a theme from your PHP-Nuke site you simply remove the corresponding folder from the themes folder, and it will no longer be available to PHP-Nuke. However, you should be careful when removing themes—what if somebody is actually using that theme? If a user has that theme selected as their personal theme, and you remove that theme, then that user's personal theme will revert to the default theme selected in Site Preferences. If you remove the site's default theme, then you will break your site! Deleting the site's default theme will produce either a blank screen or messages like the following when you attempt to view your site. Warning: head(themes/NonExistentTheme/theme.php)[function.head]: failed to create stream:No such file or directory in c:nukehtmlheader.php on line 31 The only people who can continue to use your site in this situation are those who have selected a personal theme for themselves—and only if that theme is still installed. To correct such a faux pas, make a copy of one of the other themes in your themes folder (unless you happen to have a copy of the theme you just deleted elsewhere), and rename it to the name of the theme you just deleted. In conclusion, removing themes should only be a problem if you somehow manage to remove your site's default theme. For users who have selected the theme you just removed, their theme will revert to the default theme and life goes on for them. A final caveat about the names of theme folders; do not use spaces in the names of the folders in the themes folder—this can lead to strange behavior when the list of themes is displayed in the drop-down menus for users to select from. From an Existing Theme to a New Theme We'll create a new theme for the Dinosaur Portal by making changes to an existing theme. This will not only make you feel like the theme master, but it will also serve to illustrate the nature of the theme-customization problem. We'll be making changes all over the place—adding and replacing things in HTML and PHP files—but it will be worth it. Another thing to bear in mind is that we're creating a completely different looking site without making any changes to the inner parts of PHP-Nuke. At this point, all we are changing is the theme definition. The theme for the Dinosaur Portal will have a warm, tropical feel to it to evoke the atmosphere of a steaming, tropical, prehistoric jungle, and will use lots of orange color on the page. First of all, we need a theme on which to conduct our experiments. We'll work on the 3D-Fantasy theme. Starting Off The first thing we will do is to create a new theme folder, which will be a copy of the 3D-Fantasy theme. Open up the themes folder in your file explorer, and create a copy of the 3D-Fantasy folder. Rename this copy as TheDinosaurPortal. Now log into your site as testuser, and from the Your Account module, select TheDinosaurPortal as the theme. Your site will immediately switch to this theme, but it will look exactly like 3D-Fantasy, because, at the moment, it is! You will also need some images from the code download for this article; you will find them in the SiteImages folder of this article's code. Replacing Traces of the Old Theme The theme that we are about to work on has many occurrences of 3D-Fantasy in a number of files, such as references to images. We will have to remove these first of all, or else our new theme will be looking in the wrong folder for images and other resources. Open each of the files below in your text editor, and replace every occurrence of 3D-Fantasy with TheDinosaurPortal in a text editor, we'll use Wordpad. "You can use the replace functionality of your editor to do this. For example, in Wordpad, select Edit | Replace; enter the text to be replaced, and then click on Replace All to replace all the occurrences in the open file. After making all the changes, save each file: blocks.html footer.html header.html story_home.html story_page.html theme.php tables.php Templates and PHP Files We've just encountered two types of file in the theme folder—PHP code files (theme.php and tables.php) and HTML files (blocks.html, footer.html, and so on). Before we go any further, we need to have a quick discussion of what roles these types of file play in the theme construction. PHP Files The PHP files do the main work of the theme. These files contain the definitions of some functions that handle the display of the page header and how an individual block or article is formatted, among other tasks. These functions are called from other parts of PHP-Nuke when required. We'll talk about them when they are required later in the article. Part of our customization work will be to make some changes to these functions and have them act in a different way when called. Historically, the code for a PHP-Nuke theme consisted of a single PHP file, theme.php. One major drawback of this was the difficulty you would have in editing this file in the 'design' view of an HTML editor. Instead of seeing the HTML that you wished to edit, you probably wouldn't see anything in the 'design' view of most HTML editors, since the HTML was inextricably intertwined with the PHP code. This made creating a new theme, or even editing an existing theme, not something for the faint-hearted—you had to be confident with your PHP coding to make sure you were changing the right places, and in the right way. The theme.php file consists of a number of functions that are called from other parts of PHP-Nuke when required. These functions are how the theme does its work. One of the neat appearances in recent versions of PHP-Nuke is the use of a 'mini-templating' engine for themes. Not all themes make use of this method (DeepBlue is one theme that doesn't), and that is one of the reasons we are working with 3D-Fantasy as our base theme, since it does follow the 'templating' model. Templates The HTML files that we modified above are the theme templates. They consist of HTML, without any PHP code. Each template is responsible for a particular part of the page, and is called into action by the functions of the theme when required. One advantage of using these templates is that they can be easily edited in visual HTML editors, such as Macromedia's Dreamweaver, without any PHP code to interfere with the page design. Another advantage of using these templates is to separate logic from presentation. The idea of a template is that it should determine how something is displayed (its presentation). The template makes use of some data supplied to it, but acquiring and choosing this data (the logic) is not done in the template. The template is processed or evaluated by the 'template engine', and output is generated. The template engine in this case is the theme.php file. To see how the template and PHP-Nuke 'communicate', let's look at an extract from the header.html file in the 3D-Fantasy folder: <a href="index.php"> <img src="themes/3D-Fantasy/images/logo.gif" border="0" alt="Welcome to $sitename" align="left"></a> The $sitename text (shown highlighted) is an example of what we'll call a placeholder. There is a correspondence between these placeholders and PHP variables that have the same name as the placeholder text. Themes that make use of this templating process more or less replace any text beginning with $ in the template by the value of the corresponding PHP variable. This means that you can make use of variables from PHP-Nuke itself in your themes; these could be the name of your site ($sitename), your site slogan, or even information about the user. In fact, you can add your own PHP code to create a new variable, which you can then display from within one of the templates. To complete the discussion, we will look at how the templates are processed in PHP-Nuke. The code below is a snippet from one of the themeheader() function in the theme.php file. This particular snippet is taken from the 3D-Fantasy theme. function themeheader(){ global $user, $banners, $sitename, $slogan, $cookie, $prefix, $anonymous, $db;... code continues ....$tmpl_file = "themes/3D-Fantasy/header.html";$thefile = implode("", file($tmpl_file));$thefile = addslashes($thefile);$thefile = "$r_file="".$thefile."";";eval($thefile);print $r_file;... code continues .... The processing starts with the line where the $tmpl_file variable is defined. This variable is set to the file name of the template to be processed, in this case header.html. The next line grabs the content of the file as a string. Let's suppose the header.html file contained the text You're welcomed to $sitename, thanks for coming!. Then, continuing in the code above, the $thefile variable would eventually hold this: $r_file = " You're welcomed to $sitename, thanks for coming!"; This looks very much like a PHP statement, and that is exactly what PHP-Nuke is attempting to create. The eval() function executes the statement; it defines the variable $r_file as above. This is equivalent to putting this line straight into the code: $r_file = " You're welcomed to $sitename, thanks for coming!"; If this line were in the PHP code, the value of the $sitename variable will be inserted into the string, and this is exactly how the placeholders in the templates are replaced with the values of the corresponding PHP variables. This means that the placeholders in templates can only use variables accessible at the point in the code where the template is processed with the eval() function. This means any parameters passed to the function at the time—global variables that have been announced with the global statement or any variables local to the function that have been defined before the line with the eval() function. This does mean that you will have to study the function processing the template to see what variables are available. In the examples in this article we'll look at the most relevant variables. The templates do not allow for any form of 'computation' within them; you cannot use loops or call PHP functions. You do your computations 'outside' the template in the theme.php file, and the results are 'pulled' into the template and displayed from there. Now that we're familiar with what we're going to be working with, let's get started. Changing the Page Header The first port of call will be creating a new version of the page header. We will make these customizations: Changing the site logo graphic Changing the layout of the page header Adding a welcome message to the user, and displaying the user's avatar Adding a drop-down list of topics to the header Creating a navigation bar Time For Action—Changing the Site Logo Graphic Grab the <>ilogo.gif file from the SiteImages folder in the code download. Copy it to the themes/TheDinosaurPortal/images folder, overwriting the existing logo.gif file. Refresh the page in your browser. The logo will have changed! What Just Happened? The logo.gif file in the images folder is the site logo. We replaced it with a new banner, and immediately the change came into effect. Time For Action—Changing the Site Header Layout In the theme folder is a file called header.html. Open up this file in a text editor, we'll use Wordpad. Replace all the code in this file with the following: <!-- Time For Action—Changing the Site Header Layout --><table border="0" cellspacing="0" cellpadding="6" width="100%" bgcolor="#FFCC33"> <tr valign="middle"> <td width="60%" align="right" rowspan="2"> <a href="index.php"><img src="themes/$GLOBALS[ThemeSel]/images/logo.gif" border="1" alt="Welcome to $sitename"> </a></td> <td width="40%" colspan="2"> <p align="center"><b>WELCOME TO $sitename!</b></td> </tr> <tr> <td width="20%">GAP</td> <td width="20%">GAP</td> </tr></table><!-- End of Time for Action -->$public_msg<br><table cellpadding="0" cellspacing="0" width="99%" border="0" align="center" bgcolor="#ffffff"><tr><td bgcolor="#ffffff" valign="top"> Save the header.html file. Refresh your browser. The site header now looks like this: What Just Happened? The header.html file is the template responsible for formatting the site header. Changing this file will change the format of your site header. We simply created a table that displays the site logo in the left-hand column, a welcome message in the right-hand column, and under that, two GAPs that we will add more to in a moment. We set the background color of the table to an orange color (#FFCC33). We used the $sitename placeholder to display the name of the site from the template. Note that everything after the line: <!-- End of Time for Action --> in our new header.html file is from the original file. (The characters here denote an HTML comment that is not displayed in the browser). This is because the end of the header.html file starts a new table that will continue in other templates. If we had removed these lines, the page output would have been broken. There was another interesting thing we used in the template, the $GLOBALS[ThemeSel] placeholder: <a href="index.php"><img src="themes/$GLOBALS[ThemeSel]/images/logo.gif" ThemeSel is a global variable that holds the name of the current theme—it's either the default site theme or the user's chosen theme. Although it's a global variable, using just $ThemeSel in the template would give a blank, this is because it has not been declared as global by the function in PHP-Nuke that consumes the header.html template. However, all the global variables can be accessed through the $GLOBALS array, and using $GLOBALS[ThemeSel] accesses this particular global variable. Note that this syntax is different from the way you may usually access elements of the $GLOBALS array in PHP. You might use $GLOBALS['ThemeSel'] or $GLOBALS["ThemeSel"]. Neither of these work in the template so we have to use the form without the ' or ". Time For Action—Fixing and Adding the Topics List Next we'll add the list of topics as a drop-down box to the page header. The visitor will be able to select one of the topics from the box, and then the list of stories from that topic will be displayed to them through the News module. Also, the current topic will be selected in the drop-down box to avoid confusion. This task involves fixing some bugs in the current version of the 3D-Fantasy theme. First of all, open the theme.php file and find the following line in the themeheader() function definition: $topics_list = "<select name="topic" onChange='submit()'>n"; Replace this line with these two lines: global $new_topic;$topics_list = "<select name="new_topic" onChange='submit()'>n"; If you move a few lines down in the themeheader() function, you will find this line: if ($topicid==$topic) { $sel = "selected "; } Replace $topic with $new_topic in this line to get: if ($topicid==$new_topic) { $sel = "selected "; } Save the theme.php file. Open the header.html file in your text editor, and where the second GAP is, make the modifications as shown below: <td width="20%">GAP</td> <td width="20%"><form action="modules.php?name=News&new_topic" method="post"> Select a Topic:<br>$topics_list</select></form></td></tr></table><!-- End of Time for Action --> Save the header.html file. Refresh your browser. You will see the new drop-down box in your page header: What just Happened? The themeheader() function is the function in theme.php responsible for processing the header.html template, and outputting the page header. The $topics_list variable has already been created for us in the themeheader() function, and can be used from the header.html template. It is a string of HTML that defines an HTML select drop-down list consisting of the topic titles. However, the first few steps require us to make a change to the $topics_list variable, correcting the name of the select element and also using the correct variable to ensure the current topic (if any) is selected in the drop-down box. The select element needs to have the name of new_topic, so that the News module is able to identify which topic we're after. This is all done with the changes to the theme.php file. First, we add the global statement to access the $new_topic variable, before correcting the name of the select element: global $new_topic;$topics_list = "<select name="new_topic" onChange='submit()'>n"; The next change we made is to make sure we are looking for the $new_topic variable, not the $topic variable, which isn't even defined: if ($topicid==$new_topic) { $sel = "selected "; } Now the $topics_list variable is corrected, all we have to do is add a placeholder for this variable to the header.html template, and some more HTML around it. We added the placeholder for $topics_list to display the drop-down list, and a message to go with it encouraging the reader to select a topic into one of the GAP table cells we created in the new-look header. The list of topics will be contained in a form tag, and when the user selects a topic, the form will be posted back to the server to the News module, and the stories in the selected topic will be displayed. (The extra HTML that handles submitting the form is contained with the $topics_list variable.) <form action="modules.php?name=News" method="post">Select a Topic:<br>$topics_list All that remains now is to close the select tag—the tag was opened in the $topics_list variable but not closed—and then close the form tag: </select></form> When the page is displayed, this is the HTML that PHP-Nuke produces for the topics drop-down list: <form action="modules.php?name=News&new_topic" method="post">Select a Topic:<br><select name="topic" onChange='submit()'><option value="">All Topics</option><option value="1">The Dinosaur Portal</option><option value="2">Dinosuar Hunting</option></select></form>
Read more
  • 0
  • 0
  • 6792

article-image-installation-and-configuration-microsoft-content-management-server-part-1
Packt
31 Mar 2010
10 min read
Save for later

Installation And Configuration of Microsoft Content Management Server: Part 1

Packt
31 Mar 2010
10 min read
In this first article of the series we walk you through the installation and configuration of MCMS 2002 Service Pack 2 (SP2), along with SQL Server 2005 and Visual Studio 2005 on a single developer workstation. In addition, we will cover the changes to the SP2 development environment and a number of tips for working within it. This article assumes you are already familiar with the steps necessary to install MCMS 2002 SP1a as detailed in depth in the previous book, Building Websites with Microsoft Content Management Server from Packt Publishing, January 2005 (ISBN 1-904811-16-7). There are two approaches to setting up a development environment for SP2: upgrading from a previous SP1a installation, or starting from scratch and building a fresh installation including SP2. We will cover both approaches in this article. For example, we will be using Windows XP Professional SP2 as our development workstation. However, where there are significant differences for a Windows Server 2003 SP1 machine, those will be noted. All examples assume the logged-on user is a local machine administrator. Overview of MCMS 2002 Service Pack 2 As with other Microsoft Service Packs, one major purpose of SP2 is to provide an integrated installation for a large number of previously released hotfixes. SP2 will now be a prerequisite for any future hotfix releases. While many customers will view SP2 as a regular Service Pack, it also offers support for the latest development platform and tools from Microsoft, namely SQL Server 2005, .NET Framework 2.0 and ASP.NET 2.0, and Visual Studio 2005: SQL Server 2005: MCMS databases can be hosted by SQL Server 2005, offering numerous advantages in security, deployment, and most significantly, performance. .NET Framework 2.0 and ASP.NET 2.0: MCMS applications can be hosted within the .NET Framework 2.0 runtime, and take advantage of v2.0 language features as well as security and performance improvements. In addition, many of the new features of ASP.NET 2.0 such as master pages, themes, navigation, and Membership Providers can be used. This provides numerous opportunities to both refine and refactor MCMS applications, and is the primary focus. Visual Studio 2005: MCMS applications can be developed using Visual Studio 2005. One of the greatest advantages here is the use of the new HTML-editing and designer features in VS.NET along with improved developer productivity. If you wish, you can continue to use SQL Server 2000 for your MCMS applications. However, we recommend upgrading to SQL Server 2005 and will use it throughout the examples in this book. There are numerous versions or Stock Keeping Units (SKUs) of Visual Studio 2005, all of which are supported with SP2. Throughout the examples in this book, we will be using Visual Studio 2005 Professional Edition. Unfortunately, SP2 is not a cumulative service pack and therefore requires an existing installation of SP1a. Likewise, there is no slipstreamed distribution of SP2. The SP2 distribution is suitable for all editions of MCMS. Mainly due to the extremely fast preparation and release of SP2 following the Release to Manufacturing (RTM) of .NET 2.0, Visual Studio 2005, and SQL Server 2005, the Microsoft installation information (KB906145) isn’t particularly well documented and is somewhat confusing. Rest assured that the guidance in this article has been verified and tested for both installation scenarios covered. Obtaining MCMS Service Pack 2 MCMS SP2 can be downloaded from the following locations: English:http://www.microsoft.com/downloads/details.aspx?FamilyId=3DE1E8F0-D660-4A2B-8B14-0FCE961E56FB&displaylang=en French:http://www.microsoft.com/downloads/details.aspx?FamilyId=3DE1E8F0-D660-4A2B-8B14-0FCE961E56FB&displaylang=fr German:http://www.microsoft.com/downloads/details.aspx?FamilyId=3DE1E8F0-D660-4A2B-8B14-0FCE961E56FB&displaylang=de Japanese:http://www.microsoft.com/downloads/details.aspx?FamilyId=3DE1E8F0-D660-4A2B-8B14-0FCE961E56FB&displaylang=ja Installation Approach We cover both an in-place upgrade to SP2 and a fresh installation in this chapter. Which approach you take is down to your specific requirements and your current, if any, MCMS installation. If you wish to perform a fresh install, skip ahead to the Fresh Installation of Microsoft Content Management Server 2002 Service Pack 2 section, later in this article Upgrading to Microsoft Content Management Server 2002 Service Pack 2 This section details the steps required to upgrade an existing installation of MCMS SP1a, which includes the Developer Tools for Visual Studio.NET 2003 component. The outline process for an upgrade is as follows: Install Visual Studio 2005. Install MCMS 2002 Service Pack 2. Configure the development environment. (Optional) Prepare the MCMS database for SQL Server 2005. (Optional) Upgrade SQL Server. (Optional) Install SQL Server 2005 Service Pack 1. We will perform all steps while logged on as a local machine administrator. Installing Visual Studio 2005 Visual Studio 2005 can be installed side by side with Visual Studio.NET 2003. Once we have completed the upgrade, we can remove Visual Studio.NET 2003 if we wish to only develop MCMS applications using SP2 and ASP.NET 2.0. Insert the Visual Studio 2005 DVD, and on the splash screen, click Install Visual Studio 2005. On the Welcome to the Microsoft Visual Studio 2005 installation wizard page, click Next. On the Start Page, select the I accept the terms of the License Agreement checkbox, enter your Product Key and Name, and click Next. On the Options Page, select the Custom radio button, enter your desired Product install path, and click Next. On the second Options page, select the Visual C# and Visual Web Developer checkboxes within the Language Tools section, and the Tools checkbox within the .NET Framework SDK section. Click Install. Feel free to install any additional features you may wish to use. The above selections are all that’s required to follow the examples in this book. Wait (or take a coffee break) while Visual Studio 2005 is installed. When the Finish Page appears, click Finish. From the Visual Studio 2005 Setup dialog, you can choose to install the Product Documentation (MSDN Library) if desired. From the Visual Studio 2005 Setup dialog, click Check for Visual Studio Service Releases to install any updates that may be available. Click Exit. Installing MCMS 2002 Service Pack 2 Next, we will install MCMS Service Pack 2. From the Start Menu, click Run. In the Open textbox, enter IISRESET /STOP and click OK. Wait while the IIS Services are stopped. Double-click the SP2 installation package. On the Welcome to Microsoft Content Management Server 2002 SP2 Installation Wizard page, click Next. Select the I accept the terms of this license agreement radio button, and click Next. On the ready to begin the installation page, click Next. Wait while Service Pack 2 is installed. During installation you may be prompted for the MCMS 2002 SP1a CD-ROM. Once The Installation Wizard has completed page, click Finish. If prompted, click Yes on the dialog to restart your computer, which will complete the installation. Otherwise, from the Start Menu, click Run. In the Open textbox, enter IISRESET /START and click OK to restart the IIS services. Stopping IIS prior to the installation of SP2 avoids potential problems with replacing locked files during the installation, and can prevent the requirement to reboot. Configuring the Development Environment Before continuing, a few additional steps are required to configure the development environment. We will: Configure the shortcut that opens Site Manager to bypass the Connect To dialog. Install the MCMS website and item templates in Visual Studio. Site Manager Shortcut During the installation of SP2 the Site Manager Start-menu shortcut will be overwritten. To configure Site Manager to bypass the Connect To dialog, take the following steps: Select Start | All Programs | Microsoft Content Management Server. Right-click the Site Manager shortcut and click Properties. In the Target textbox, replace"C:Program FilesMicrosoft Content Management ServerClientNRClient.exe" http:///NR/System/ClientUI/login.aspwith"C:Program FilesMicrosoft Content Management ServerClientNRClient.exe" http://localhost/NR/System/ClientUI/login.asp. Click OK. It is possible to configure many different Site Manager shortcuts pointing to different MCMS entry points. However, for this book we will only use the entry point on localhost, which is the only supported configuration for MCMS development. Visual Studio Templates The installation of MCMS Service Pack 2 automatically registers the MCMS developer tools such as MCMS Template Explorer in Visual Studio 2005. However, before we can create MCMS applications with Visual Studio, we need to make the website and item templates available. Select Start | All Programs | Microsoft Visual Studio 2005 | Visual Studio Tools | Visual Studio 2005 Command Prompt. Execute the following commands, replacing MCMS_INSTALL_PATH with the install location of MCMS (usually C:Program FilesMicrosoft Content Management Server) and PATH_TO_MY_DOCUMENTS_FOLDER with the location of your My Documents folder: xcopy "MCMS_INSTALL_PATHDevToolsNewProjectWizards80Visual WebDeveloper" "PATH_TO_MY_DOCUMENTS_FOLDERVisual Studio 2005TemplatesProjectTemplatesVisual Web Developer"/E xcopy "MCMS_INSTALL_PATHDevToolsNewItemWizards80Visual WebDeveloper" "PATH_TO_MY_DOCUMENTS_FOLDERVisual Studio 2005TemplatesItemTemplatesVisual Web Developer"/E Execute the following command to register the templates with VisualStudio 2005: devenv /setup Close the command prompt. This completes the steps to upgrade to SP2, and our environment is now ready for development! We can test our installation by viewing the version number in the SCA, connecting with Site Manager, or by using the Web Author. Of course, any existing MCMS web applications will at this time still be hosted by.NET Framework v1.1. It is not necessary at this stage to register ASP.NET as detailed in the Microsoft Installation Instructions (KB 906145). This registration was performed by the Visual Studio 2005 installer. Additionally it is unnecessary to configure IIS to use ASP.NET 2.0 using the Internet Information Services Snap-In, as Visual Studio 2005 automatically sets this option on each MCMS website application created.However, if you are installing on Windows Server 2003, you must configure the Virtual Website root and the MCMS Virtual Directory to use ASP.NET 2.0, as it is not possible to use two versions of ASP.NET within the same Application Pool. The ActiveX controls that are part of HtmlPlaceholderControl are updated with SP2. Therefore you will be prompted to install this control when first switching to edit mode.If you have pre-installed the controls using regsvr32 or Group Policy as detailed at http://download.microsoft.com/download/4/2/5/4250f79a-c3a1-4003-9272-2404e92bb76a/MCMS+2002+-+(complete)+FAQ.htm#51C0CE4B-FC57-454C-BAAE-12C09421B57B, you might also be prompted, and you will need to update your distribution for the controls. At this stage you can also choose to upgrade SQL Server or move forward. Preparing the MCMS Database for SQL Server 2005 Before upgrading our SQL Server installation to SQL Server 2005, we need to prepare the MCMS database so that it is compatible with SQL Server 2005. Request the following MCMS hotfix from Microsoft:http://support.microsoft.com/?kbid=913401. Run the hotfix executable to extract the files to a local folder, e.g. c:913401. Copy both of the files (_dca.ini and _sp1aTosp2upgrade.sql) to the MCMS SQL install folder (typically c:Program FilesMicrosoft Content Management ServerServerSetup FilesSQL Install). Overwrite the existing files. Delete the temporary folder. Select Start | Microsoft Content Management Server | Data Configuration Application. On the splash screen, click Next. In the Stop Service? dialog, click Yes. On the Select MCMS Database page, click Next. In the Upgrade Required dialog, click Yes. On the Upgrade Database page, click Next. In the Add an Administrator dialog, click No. On the Database Configuration Application page, uncheck the Launch the SCA Now checkbox and click Finish.
Read more
  • 0
  • 0
  • 2364
Modal Close icon
Modal Close icon