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

How-To Tutorials

7019 Articles
article-image-er-diagrams-domain-model-and-n-layer-architecture-aspnet-35-part1
Packt
20 Oct 2009
11 min read
Save for later

ER Diagrams, Domain Model, and N-Layer Architecture with ASP.NET 3.5 (part1)

Packt
20 Oct 2009
11 min read
Let us start with a 1-tier ASP.NET application configuration. Note that the application as a whole including database and client browser is three tier. We can call this 1-tier architecture a 3-tier architecture if we include the browser and database (if used). For the rest of this article we will ignore the database and browser as separate tiers so that we can focus on how to divide the main ASP.NET application layers logically, using the n-layer pattern to its best use. We will first try to separate the data access and logical code into their own separate layers and see how we can introduce flexibility and re-usability into our solution. We will understand this with a sample project. Before we go ahead into the technical details and code, we will first learn about two important terms: ER Diagram and Domain Model, and how they help us in getting a good understanding of the application we need to develop. Entity-Relationship Diagram Entity-Relationship diagrams, or ER diagrams in short, are graphical representations depicting relationships between different entities in a system. We humans understand and remember pictures or images more easily than textual information. When we first start to understand a project we need to see how different entities in the project relate to each other. ER diagrams help us achieve that goal by graphically describing the relationships. An entity can be thought of as an object in a system that can be identified uniquely. An entity can have attributes; an attribute is simply a property we can associate with an entity. For example, a Car entity can have the following attributes: EngineCapacity, NumberofGears, SeatingCapacity, Mileage, and so on. So attributes are basically fields holding data to indentify an entity. Attributes cannot exist without an entity. Let us understand ER diagrams in detail with a simple e-commerce example: a very basic Order Management System. We will be building a simple web based system to track customer's orders, and manage customers and products. To start with, let us list the basic entities for our simplified Order Management System (OMS): Customer: A person who can place Orders to buy Products. Order: An order placed by a Customer. There can be multiple Products bought by a Customer in one Order. Product: A Product is an object that can be purchased by a Customer. Category: Category of a Product. A Category can have multiple Products, and a Product can belong to many Categories. For example, a mixer-grinder can be under the Electronic Gadgets category as well as in Home Appliances. OrderLineItem: An Order can be for multiple Products. Each individual Product in an order will be encapsulated by an OrderLineItem. So an Order can have multiple OrderLineItems. Now, let us picture the relationship between the core business entities is defined using an Entity-Relationship diagram. Our ER diagram will show the relational associations between the entities from a database's perspective. So it is more of a relational model and will not show any of the object-oriented associations (for which we will use the Domain Model in the later sections of this article). In an ER diagram, we show entities using rectangular boxes, the relationships between entities using diamond boxes and attributes using oval boxes, as shown below: The purpose of using such shapes is to make the ER diagram clear and concise, depicting the relational model as closely as possible without using long sentences or text. So the Customer entity with some of the basic attributes can be depicted in an ER diagram as follows: Now, let us create an ER diagram for our Order Management System. For the sake of simplicity, we will not list the attributes of the entities involved. Here is how the ER diagram looks: The above ER diagram depicts the relationships between the OMS entities but is still incomplete as the relationships do not show how the entities are quantitatively related to each other. We will now look at how to quantify relationships using degree and cardinality. Degree and Cardinality of a Relationship The relationships in an ER diagram can also have a degree. A degree specifies the multiplicity of a relationship. In simpler terms, it refers to the number of entities involved in a relationship. All relationships in an OMS ER diagram have a degree of two, also called binary relationships. For example, in Customer-Order relationships only two entities are involved—Customer and Order; so it's a two degree relationship. Most relationships you come across would be binary. Another term associated with a relationship is cardinality. The cardinality of a relationship identifies the number of instances of entities involved in that particular relationship. For example, an Order can have multiple OrderLineItems, which means the cardinality of the relationship between Order and OrderLineItem is one-to-many. The three commonly-used cardinalities of a relationship are: One-to-one: Depicted as 1:1Example: One OrderLineItem can have only one Product; so the OrderLineItem and Product entities share a one-to-one relationship One-to-many: Depicted as 1:nExample: One customer can place multiple orders, so the Customer and Order entities share a one-to-many relationship Many-to-many: Depicted as n:mExample: One Product can be included in multiple Categories and one Category can contain multiple Products; therefore the Product and Category entities share a many-to-many relationship After adding the cardinality of the relationships to our ER diagram, here is how it will look: This basic ER diagrams tells us a lot about how the different entities in the system are related to each other, and can help new programmers to quickly understand the logic and the relationships of the system they are working on. Each entity will be a unique table in the database. OMS Project using 2-Layer We know that the default coding style in ASP.NET 2.0 already supports the 1-tier 1-layer style, with two sub-layers in the main UI layer as follows: Designer code files: ASPX markup files Code behind files: Files containing C# or VB.NET code Because both of these layers contain the UI code, we can include them as a part of the UI layer. These two layers help us to separate the markup and the code from each other. However, it is still not advisable to have logical code, such as data access or business logic, directly in these code-behind files. Now, one way to create an ASP.NET web application for our Order Management System (OMS) in just one layer is by using a DataSet (or DataReader) to fill the front-end UI elements directly in the code-behind classes. This will involve writing data access code in the UI layer (code-behind), and will tightly bind this UI layer with the data access logic, making the application rigid (inflexible), harder to maintain, and less scalable. In order to have greater flexibility, and to keep the UI layer completely independent of the data access and business logic code, we need to put these elements in separate files. So we will now try and introduce some loose-coupling by following a 2-layer approach this time. What we will do is, write all data access code in separate class files instead of using the code-behind files of the UI layer. This will make the UI layer independent of the data-access code. We are assuming that we do not have any specific business logic code at this point, or else we would have put that under another layer with its own namespace, making it a 3-layered architecture. We will examine this in the upcoming sections of this article. Sample Project Let us see how we can move from this 1-tier 1-layer style to a 1-tier 2-layer style. Using the ER diagram above as reference, we can create a 2-Layer architecture for our OMS with these layers: UI-layer with ASPX and code-behind classes Data access classes under a different namespace but in the same project So let's start with a new VS 2008 project. We will create a new ASP.NET Web Project in C#, and add a new web form, ProductList.aspx, which will simply display a list of all the products using a Repeater control. The purpose of this project is to show how we can logically break up the UI layer further by separating the data access code into another class file. The following is the ASPX markup of the ProductList page (unnecessary elements and tags have been removed to keep things simple): <asp:Repeater ID="prodRepeater" runat="server"> <ItemTemplate> Product Code: <%# Eval("Code")%> <br> Name: <%# Eval("Name")%> <br> Unit Price: $<%# Eval("UnitPrice")%> <br> </ItemTemplate></asp:Repeater> In this ASPX file, we only have a Repeater control, which we will bind with the data in the code-behind file. Here is the code in the ProductList.aspx.cs code-behind file: namespace OMS{public partial class _Default : System.Web.UI.Page { /// <summary> /// Page Load method /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { DataTable dt = DAL.GetAllProducts(); prodRepeater.DataSource = dt; prodRepeater.DataBind(); } }//end class}//end namespace Note that we don't have any data access code in the code-behind sample above. We are just calling the GetAllProducts() method, which has all of data access code wrapped in a different class named DAL. We can logically separate out the code, by using different namespaces to achieve code re-use and greater architectural flexibility. So we created a new class named DAL under a different namespace from the UI layer code files. Here is the DAL code: namespace OMS.Code{ public class DAL { /// <summary> /// Load all comments from the Access DB /// </summary> public static DataTable GetAllProducts() { string sCon = ConfigurationManager.ConnectionStrings[0].ConnectionString; using (SqlConnection cn = new SqlConnection(sCon)) { string sQuery = @"SELECT * FROM OMS_Product"; SqlCommand cmd = new SqlCommand(sQuery, cn); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); cn.Open(); da.Fill(ds); return ds.Tables[0]; } } }//end class}//end namespace So we have separated the data access code in a new logical layer, using a separate namespace, OMS.Code, and using a new class. Now, if we want to, we can re-use the same code in the other pages as well. Furthermore, methods to add and edit a product can be defined in this class and then used in the UI layer. This allows multiple developers to work on the DAL and UI layers simultaneously. Even though we have a logical separation of the code in this 2-layer sample architecture, we are still not using real Object Oriented Programming (OOP). All of the Object-Oriented Programming we have used so far has been the default structure the .NET framework has provided, such as the Page class, and so on. When a project grows big in size as well as complexity, using the 2-layer model discussed above can become cumbersome and cause scalability and flexibility issues. If the project grows in complexity, then we will be putting all of the business logic code in either the DAL or the UI layer. This business logic code includes business rules. For example, if the customer orders a certain number of products in one order, he gets a certain level of discount. If we code such business rules in the UI layer, then if the rules change we need to change the UI as well, which is not ideal, especially in cases where we can have multiple UIs for the same code, for example one normal web browser UI and another mobile-based UI. We also cannot put business logic code in the DAL layer because the DAL layer should only contain data access code which should not be mixed with any kind of business processing logic. In fact the DAL layer should be quite "dumb"–there should be no "logic" inside it because it is mostly a utility layer which only needs to put data in and pull data out from a data store. To make our applications more scalable and to reap the benefit of OOP, we need to create objects, and wrap business behavior in their methods. This is where the Domain Model comes into the picture.
Read more
  • 0
  • 0
  • 10197

article-image-soa-service-oriented-architecture
Packt
20 Oct 2009
17 min read
Save for later

SOA—Service Oriented Architecture

Packt
20 Oct 2009
17 min read
What is SOA? SOA is the acronym for Service Oriented Architecture. As it has come to be known, SOA is an architectural design pattern by which several guiding principles determine the nature of the design. Basically, SOA states that every component of a system should be a service, and the system should be composed of several loosely-coupled services. A service here means a unit of a program that serves a business process. "Loosely-coupled" here means that these services should be independent of each other, so that changing one of them should not affect any other services. SOA is not a specific technology, nor a specific language. It is just a blueprint, or a system design approach. It is an architecture model that aims to enhance the efficiency, agility, and productivity of an enterprise system. The key concepts of SOA are services, high interoperability and loose coupling. Several other architecture/technologies such as RPC, DCOM, and CORBA have existed for a long time, and attempted to address the client/server communication problems. The difference between SOA and these other approaches is that SOA is trying to address the problem from the client side, and not from the server side. It tries to decouple the client side from the server side, instead of bundling them, to make the client side application much easier to develop and maintain. This is exactly what happened when object-oriented programming (OOP) came into play 20 years ago. Prior to object-oriented programming, most designs were procedure-oriented, meaning the developer had to control the process of an application. Without OOP, in order to finish a block of work, the developer had to be aware of the sequence that the code would follow. This sequence was then hard-coded into the program, and any change to this sequence would result in a code change. With OOP, an object simply supplied certain operations; it was up to the caller of the object to decide the sequence of those operations. The caller could mash up all of the operations, and finish the job in whatever order needed. There was a paradigm shift from the object side to the caller side. This same paradigm shift is happening today. Without SOA, every application is a bundled, tightly coupled solution. The client-side application is often compiled and deployed along with the server-side applications, making it impossible to quickly change anything on the server side. DCOM and CORBA were on the right track to ease this problem by making the server-side components reside on remote machines. The client application could directly call a method on a remote object, without knowing that this object was actually far away, just like calling a method on a local object. However, the client-side applications continue to remain tightly coupled with these remote objects, and any change to the remote object will still result in a recompiling or redeploying of the client application. Now, with SOA, the remote objects are truly treated as remote objects. To the client applications, they are no longer objects; they are services. The client application is unaware of how the service is implemented, or of the signature that should be used when interacting with those services. The client application interacts with these services by exchanging messages. What a client application knows now is only the interfaces, or protocols of the services, such as the format of the messages to be passed in to the service, and the format of the expected returning messages from the service. Historically, there have been many other architectural design approaches, technologies, and methodologies to integrate existing applications. EAI (Enterprise Application Integration) is just one of them. Often, organizations have many different applications, such as order management systems, accounts receivable systems, and customer relationship management systems. Each application has been designed and developed by different people using different tools and technologies at different times, and to serve different purposes. However, between these applications, there are no standard common ways to communicate. EAI is the process of linking these applications and others in order to realize financial and operational competitive advantages. It may seem that SOA is just an extension of EAI. The similarity is that they are both designed to connect different pieces of applications in order to build an enterprise-level system for business. But fundamentally, they are quite different. EAI attempts to connect legacy applications without modifying any of the applications, while SOA is a fresh approach to solve the same problem. Why SOA? So why do we need SOA now? The answer is in one word—agility. Business requirements change frequently, as they always have. The IT department has to respond more quickly and cost-effectively to those changes. With a traditional architecture, all components are bundled together with each other. Thus, even a small change to one component will require a large number of other components to be recompiled and redeployed. Quality assurance (QA) effort is also huge for any code changes. The processes of gathering requirements, designing, development, QA, and deployment are too long for businesses to wait for, and become actual bottlenecks. To complicate matters further, some business processes are no longer static. Requirements change on an ad-hoc basis, and a business needs to be able to dynamically define its own processes whenever it wants. A business needs a system that is agile enough for its day-to-day work. This is very hard, if not impossible, with existing traditional infrastructure and systems. This is where SOA comes into play. SOA's basic unit is a service. These services are building blocks that business users can use to define their own processes. Services are designed and implemented so that they can serve different purposes or processes, and not just specific ones. No matter what new processes a business needs to build or what existing processes a business needs need to modify, the business users should always be able to use existing service blocks, in order to compete with others according to current marketing conditions. Also, if necessary, some new service blocks can be used. These services are also designed and implemented so that they are loosely coupled, and independent of one another. A change to one service does not affect any other service. Also, the deployment of a new service does not affect any existing service. This greatly eases release management and makes agility possible. For example, a GetBalance service can be designed to retrieve the balance for a loan. When a borrower calls in to query the status of a specific loan, this GetBalance service may be called by the application that is used by the customer service representatives. When a borrower makes a payment online, this service can also be called to get the balance of the loan, so that the borrower will know the balance of his or her loan after the payment. Yet in the payment posting process, this service can still be used to calculate the accrued interest for a loan, by multiplying the balance with the interest rate. Even further, a new process can be created by business users to utilize this service if a loan balance needs to be retrieved. The GetBalance service is developed and deployed independently from all of the above processes. Actually, the service exists without even knowing who the client will be or even how many clients there will be. All of the client applications communicate with this service through its interface, and its interface will remain stable once it is in production. If we have to change the implementation of this service, for example by fixing a bug, or changing an algorithm inside a method of the service, all of the client applications can still work without any change. When combined with the more mature Business Process Management (BPM) technology, SOA plays an even more important role in an organization's efforts to achieve agility. Business users can create and maintain processes within BPM, and through SOA they can plug a service into any of the processes. The front-end BPM application is loosely coupled to the back-end SOA system. This combination of BPM and SOA will give an organization much greater flexibility in order to achieve agility. How do we implement SOA? Now that we've established why SOA is needed by the business, the question becomes—how do we implement SOA? To implement SOA in an organization, three key elements have to be evaluated—people, process, and technology. Firstly, the people in the organization must be ready to adopt SOA. Secondly, the organization must know the processes that the SOA approach will include, including the definition, scope, and priority. Finally, the organization should choose the right technology to implement it. Note that people and processes take precedence over technology in an SOA implementation, but they are out of the scope of this article. In this article, we will assume people and processes are all ready for an organization to adopt SOA. Technically, there are many SOA approaches. At certain degrees, traditional technologies such as RPC, DCOM, CORBA, or some modern technologies such as IBM WebSphere MQ, Java RMI, and .NET Remoting could all be categorized as service-oriented, and can be used to implement SOA for one organization. However, all of these technologies have limitations, such as language or platform specifications, complexity of implementation, or the ability to support binary transports only. The most important shortcoming of these approaches is that the server-side applications are tightly coupled with the client-side applications, which is against the SOA principle. Today, with the emergence of web service technologies, SOA becomes a reality. Thanks to the dramatic increase in network bandwidth, and given the maturity of web service standards such as WS-Security, and WS-AtomicTransaction, an SOA back-end can now be implemented as a real system. SOA from different users' perspectives However, as we said earlier, SOA is not a technology, but only a style of architecture, or an approach to building software products. Different people view SOA in different ways. In fact, many companies now have their own definitions for SOA. Many companies claim they can offer an SOA solution, while they are really just trying to sell their products. The key point here is—SOA is not a solution. SOA alone can't solve any problem. It has to be implemented with a specific approach to become a real solution. You can't buy an SOA solution. You may be able to buy some kinds of products to help you realize your own SOA, but this SOA should be customized to your specific environment, for your specific needs. Even within the same organization, different players will think about SOA in quite different ways. What follows are just some examples of how different players in an organization judge the success of an SOA initiative using different criteria. [Gartner, Twelve Common SOA Mistakes and How to Avoid Them, Publication Date: 26 October 2007 ID Number: G00152446] To a programmer, SOA is a form of distributed computing in which the building blocks (services) may come from other applications or be offered to them. SOA increases the scope of a programmer's product and adds to his or her resources, while also closely resembling familiar modular software design principles. To a software architect, SOA translates to the disappearance of fences between applications. Architects turn to the design of business functions rather than to self-contained and isolated applications. The software architect becomes interested in collaboration with a business analyst to get a clear picture of the business functionality and scope of the application. SOA turns software architects into integration architects and business experts. For the Chief Investment Officers (CIOs), SOA is an investment in the future. Expensive in the short term, its long-term promises are lower costs, and greater flexibility in meeting new business requirements. Re-use is the primary benefit anticipated as a means to reduce the cost and time of new application development. For business analysts, SOA is the bridge between them and the IT organization. It carries the promise that IT designers will understand them better, because the services in SOA reflect the business functions in business process models. For CEOs, SOA is expected to help IT become more responsive to business needs and facilitate competitive business change. Complexities in SOA implementation Although SOA will make it possible for business parties to achieve agility, SOA itself is technically not simple to implement. In some cases, it even makes software development more complex than ever, because with SOA you are building for unknown problems. On one hand, you have to make sure that the SOA blocks you are building are useful blocks. On the other, you need a framework within which you can assemble those blocks to perform business activities. The technology issues associated with SOA are more challenging than vendors would like users to believe. Web services technology has turned SOA into an affordable proposition for most large organizations by providing a universally-accepted, standard foundation. However, web services play a technology role only for the SOA backplane, which is the software infrastructure that enables SOA-related interoperability and integration. The following figure shows the technical complexity of SOA. It has been taken from Gartner, Twelve Common SOA Mistakes and How to Avoid Them, Publication Date: 26 October 2007 ID Number: G00152446. As Gartner says, users must understand the complex world of middleware, and point-to-point web service connections only for small-scale, experimental SOA projects. If the number of services deployed grows to more than 20 or 30, then use a middleware-based intermediary—the SOA backplane. The SOA backplane could be an Enterprise Service Bus (ESB), a Message-Oriented Middleware (MOM), or an Object Request Broker (ORB). However, in this article, we will not cover it. We will build only point-to-point services using WCF. Web services There are many approaches to realizing SOA, but the most popular and practical one is—using web services. What is a web service? A web service is a software system designed to support interoperable machine-to-machine interaction over a network. A web service is typically hosted on a remote machine (provider), and called by a client application (consumer) over a network. After the provider of a web service publishes the service, the client can discover it and invoke it. The communications between a web service and a client application use XML messages. A web service is hosted within a web server and HTTP is used as the transport protocol between the server and the client applications. The following diagram shows the interaction of web services: Web services were invented to solve the interoperability problem between applications. In the early 90s, along with the LAN/WAN/Internet development, it became a big problem to integrate different applications. An application might have been developed using C++, or Java, and run on a Unix box, a Windows PC, or even a mainframe computer. There was no easy way for it to communicate with other applications. It was the development of XML that made it possible to share data between applications across hardware boundaries and networks, or even over the Internet. For example, a Windows application might need to display the price of a particular stock. With a web service, this application can make a request to a URL, and/or pass an XML string such as <QuoteRequest><GetPrice Symble='XYZ'/></QuoteRequest>. The requested URL is actually the Internet address of a web service, which, upon receiving the above quote request, gives a response, <QuoteResponse><QuotePrice Symble='XYZ'>51.22</QuotePrice></QuoteResponse/>. The Windows application then uses an XML parser to interpret the response package, and display the price on the screen. The reason it is called a web service is that it is designed to be hosted in a web server, such as Microsoft Internet Information Server, and called over the Internet, typically via the HTTP or HTTPS protocols. This is to ensure that a web service can be called by any application, using any programming language, and under any operating system, as long as there is an active Internet connection, and of course, an open HTTP/HTTPS port, which is true for almost every computer on the Internet. Each web service has a unique URL, and contains various methods. When calling a web service, you have to specify which method you want to call, and pass the required parameters to the web service method. Each web service method will also give a response package to tell the caller the execution results. Besides new applications being developed specifically as web services, legacy applications can also be wrapped up and exposed as web services. So, an IBM mainframe accounting system might be able to provide external customers with a link to check the balance of an account. Web service WSDL In order to be called by other applications, each web service has to supply a description of itself, so that other applications will know how to call it. This description is provided in a language called a WSDL. WSDL stands for Web Services Description Language. It is an XML format that defines and describes the functionalities of the web service, including the method names, parameter names, and types, and returning data types of the web service. For a Microsoft ASMX web service, you can get the WSDL by adding ?WSDL to the end of the web service URL, say http://localhost/MyService/MyService.asmx?WSDL. Web service proxy A client application calls a web service through a proxy. A web service proxy is a stub class between a web service and a client. It is normally auto-generated by a tool such as Visual Studio IDE, according to the WSDL of the web service. It can be re-used by any client application. The proxy contains stub methods mimicking all of methods of the web service so that a client application can call each method of the web service through these stub methods. It also contains other necessary information required by the client to call the web service such as custom exceptions, custom data and class types, and so on. The address of the web service can be embedded within the proxy class, or it can be placed inside a configuration file. A proxy class is always for a specific language. For each web service, there could be a proxy class for Java clients, a proxy class for C# clients, and yet another proxy class for COBOL clients. To call a web service from a client application, the proper proxy class first has to be added to the client project. Then, with an optional configuration file, the address of the web service can be defined. Within the client application, a web service object can be instantiated, and its methods can be called just as for any other normal method. SOAP There are many standards for web services. SOAP is one of them. SOAP was originally an acronym for Simple Object Access Protocol, and was designed by Microsoft. As this protocol became popular with the spread of web services, and its original meaning was misleading, the original acronym was dropped with version 1.2 of the standard. It is now merely a protocol, maintained by W3C. SOAP, now, is a protocol for exchanging XML-based messages over computer networks. It is widely-used by web services and has become its de-facto protocol. With SOAP, the client application can send a request in XML format to a server application, and the server application will send back a response in XML format. The transport for SOAP is normally HTTP / HTTPS, and the wide acceptance of HTTP is one of the reasons why SOAP is widely accepted today.
Read more
  • 0
  • 0
  • 4659

article-image-adding-interactive-course-material-moodle-19-part-3
Packt
20 Oct 2009
5 min read
Save for later

Adding Interactive Course Material in Moodle 1.9: Part 3

Packt
20 Oct 2009
5 min read
  Editing a Quiz Immediately after saving the Settings page, you are taken to the Editing Quiz page. This page is divided into five tabs. Each tab enables you to edit a different aspect of the quiz. This tab... Enables you to... Quiz Add questions to the quiz. Remove questions from the quiz. Arrange the questions in order. Create page breaks between questions. Assign a point value to each question. Assign a maximum point value to the quiz. Click into the editing page for each question. Questions Create a new question. Note that you must then add the new question to the quiz under the Quiz tab (see above). Also note that every question must belong to a category. Delete a question, not just from the quiz but from your site's question bank. Move a question from one category to another category. Click into the editing page for each question. Click into the editing page for each category. Categories Arrange the list of categories in order. Nest a category under another category (they become parent and subcategories). Publish a category, so that questions in that category can be used by other courses on the site. Delete a category (you must choose a new category to move the questions in the deleted category). Import Import questions from other learning systems. Import questions that were exported from Moodle. Export Export questions from Moodle, and save them in a variety of formats that Moodle and other learning systems can understand.       Create and Edit Question Categories Every question belongs to a category. You manage question categories under the Categories tab. There will always be a Default category. But before you create new questions, you might want to check to ensure that you have an appropriate category in which to put them. The categories which you can manage are listed on this page. To Add a New Category To add a new category, first select its Parent. If you select Top, the category will be a top-level category. Or, you can select any other category to which you have access, and then the new category will be a child of the selected category. In the Category field, enter the name for the new category. In the Category Info field, enter a description of the new category. The Publish field determines whether other courses can use the questions in this category. Click the Add button. To Edit a Category Next to the category, click the icon. The Edit categories page is displayed. You can edit the Parent, Category name, Category Info, and Publish setting. When you are finished, click the Update button. Your changes are saved and you are returned to the Categories page. Managing the Proliferation of Questions and Categories As the site administrator, you might want to monitor the creation of new question categories to ensure that they are logically named, don't have a lot of overlap, and are appropriate for the purpose of your site. As these question and their categories are shared among course creators, they can be a powerful tool for collaboration. Consider using the site-wide Teachers forum to notify your teachers, and course creators of new questions and categories. Create and Manage Questions You create and manage questions under the Questions tab. The collection of questions in your site is called the Question bank. As a teacher or the course creator, you have access to some or all the questions in the question bank. When you create questions, you add them to your site's question bank. When you create a quiz, you choose questions from the question bank for the quiz. Both these functions can be done on the same Editing Quiz page. Pay attention to which part of the page you are using—the one for creating new questions or the one for drawing question from the question bank. Display Questions from the Bank You can display questions from one category at a time. To select that category, use the Category drop-down list. If a question is deleted when it is still being used by a quiz, then it is not removed from the question bank. Instead, the question is hidden. The setting Also show old questions enables you to see questions that were deleted from the category. These deleted, or hidden, or old questions appear in the list with a blue box next to them. To keep your question bank clean, and to prevent teachers from using deleted questions, you can move all the deleted questions into a category called Deleted questions. Create the category Deleted questions and then use Also show old questions to show the deleted questions. Select them, and move them into Deleted questions. Move Questions between Categories To move a question into a category, you must have access to the target category. This means that the target category must be published, so that the teachers in all the courses can see it. Select the question(s) to move, select the category, and then click the Move to>> button: Create a Question To create a new question, from the Create new question drop-down list, select the type for the next question: This brings you to the editing page for the question: After you save the question, it is added to the list of questions in that category: Question Types The following chart explains the types of questions you can create, and gives some tips for using them.  
Read more
  • 0
  • 0
  • 1909

article-image-primitive-data-types-variables-and-operators-object-oriented-javascript
Packt
20 Oct 2009
10 min read
Save for later

Primitive Data Types, Variables, and Operators in Object-Oriented JavaScript

Packt
20 Oct 2009
10 min read
Let's get started. Variables Variables are used to store data. When writing programs, it is convenient to use variables instead of the actual data, as it's much easier to write pi instead of 3.141592653589793 especially when it happens several times inside your program. The data stored in a variable can be changed after it was initially assigned, hence the name "variable". Variables are also useful for storing data that is unknown to the programmer when the code is written, such as the result of later operations. There are two steps required in order to use a variable. You need to: Declare the variable Initialize it, that is, give it a value In order to declare a variable, you use the var statement, like this: var a;var thisIsAVariable;var _and_this_too;var mix12three; For the names of the variables, you can use any combination of letters, numbers, and the underscore character. However, you can't start with a number, which means that this is invalid: var 2three4five; To initialize a variable means to give it a value for the first (initial) time. You have two ways to do so: Declare the variable first, then initialize it, or Declare and initialize with a single statement An example of the latter is: var a = 1; Now the variable named a contains the value 1. You can declare (and optionally initialize) several variables with a single var statement; just separate the declarations with a comma: var v1, v2, v3 = 'hello', v4 = 4, v5; Variables are Case Sensitive Variable names are case-sensitive. You can verify this statement using the Firebug console. Try typing this, pressing Enter after each line: var case_matters = 'lower';var CASE_MATTERS = 'upper';case_mattersCASE_MATTERS To save keystrokes, when you enter the third line, you can only type ca and press the Tab key. The console will auto-complete the variable name to case_matters. Similarly, for the last line—type CA and press Tab. The end result is shown on the following figure. Throughout the rest of this article series, only the code for the examples will be given, instead of a screenshot: >>> var case_matters = 'lower';>>> var CASE_MATTERS = 'upper';>>> case_matters"lower">>> CASE_MATTERS"upper" The three consecutive greater-than signs (>>>) show the code that you type, the rest is the result, as printed in the console. Again, remember that when you see such code examples, you're strongly encouraged to type in the code yourself and experiment tweaking it a little here and there, so that you get a better feeling of how it works exactly. Operators Operators take one or two values (or variables), perform an operation, and return a value. Let's check out a simple example of using an operator, just to clarify the terminology. >>> 1 + 23 In this code: + is the operator The operation is addition The input values are 1 and 2 (the input values are also called operands) The result value is 3 Instead of using the values 1 and 2 directly in the operation, you can use variables. You can also use a variable to store the result of the operation, as the following example demonstrates: >>> var a = 1;>>> var b = 2;>>> a + 12>>> b + 24>>> a + b3>>> var c = a + b;>>> c3 The following table lists the basic arithmetic operators: Operator symbol Operation Example + Addition >>> 1 + 2 3 - Subtraction >>> 99.99 - 11 88.99 * Multiplication >>> 2 * 3 6 / Division >>> 6 / 4 1.5 % Modulo, the reminder of a division >>> 6 % 3 0 >>> 5 % 3 2 It's sometimes useful to test if a number is even or odd. Using the modulo operator it's easy. All odd numbers will return 1 when divided by 2, while all even numbers will return 0. >>> 4 % 2 0 >>> 5 % 2 1 ++ Increment a value by 1 Post-increment is when the input value is incremented after it's returned. >>> var a = 123; var b = a++; >>> b 123 >>> a 124 The opposite is pre-increment; the input value is first incremented by 1 and then returned. >>> var a = 123; var b = ++a; >>> b 124 >>> a 124 -- Decrement a value by 1 Post-decrement >>> var a = 123; var b = a--; >>> b 123 >>> a 122 Pre-decrement >>> var a = 123; var b = --a; >>> b 122 >>> a 122 When you type var a = 1; this is also an operation; it's the simple assignment operation and = is the simple assignment operator. There is also a family of operators that are a combination of an assignment and an arithmetic operator. These are called compound operators. They can make your code more compact. Let's see some of them with examples. >>> var a = 5;>>> a += 3;8 In this example a += 3; is just a shorter way of doing a = a + 3; >>> a -= 3;5 Here a -= 3; is the same as a = a - 3; Similarly: >>> a *= 2;10>>> a /= 5;2>>> a %= 2;0 In addition to the arithmetic and assignment operators discussed above, there are other types of operators, as you'll see later in this article series.   Primitive Data Types Any value that you use is of a certain type. In JavaScript, there are the following primitive data types: Number—this includes floating point numbers as well as integers, for example 1, 100, 3.14. String—any number of characters, for example "a", "one", "one 2 three". Boolean—can be either true or false. Undefined—when you try to access a variable that doesn't exist, you get the special value undefined. The same will happen when you have declared a variable, but not given it a value yet. JavaScript will initialize it behind the scenes, with the value undefined. Null—this is another special data type that can have only one value, the null value. It means no value, an empty value, nothing. The difference with undefined is that if a variable has a value null, it is still defined, it only happens that its value is nothing. You'll see some examples shortly. Any value that doesn't belong to one of the five primitive types listed above is an object. Even null is considered an object, which is a little awkward—having an object (something) that is actually nothing. The data types in JavaScript the data types are either: Primitive (the five types listed above), or Non-primitive (objects) Finding out the Value Type —the typeof Operator If you want to know the data type of a variable or a value, you can use the special typeof operator. This operator returns a string that represents the data type. The return values of using typeof can be one of the following—"number", "string", "boolean", "undefined", "object", or "function". In the next few sections, you'll see typeof in action using examples of each of the five primitive data types. Numbers The simplest number is an integer. If you assign 1 to a variable and then use the typeof operator, it will return the string "number". In the following example you can also see that the second time we set a variable's value, we don't need the var statement. >>> var n = 1;>>> typeof n;"number">>> n = 1234;>>> typeof n;"number" Numbers can also be floating point (decimals): >>> var n2 = 1.23;>>> typeof n;"number" You can call typeof directly on the value, without assigning it to a variable first: >>> typeof 123;"number" Octal and Hexadecimal Numbers When a number starts with a 0, it's considered an octal number. For example, the octal 0377 is the decimal 255. >>> var n3 = 0377;>>> typeof n3;"number">>> n3;255 The last line in the example above prints the decimal representation of the octal value. While you may not be very familiar with octal numbers, you've probably used hexadecimal values to define, for example, colors in CSS stylesheets. In CSS, you have several options to define a color, two of them being: Using decimal values to specify the amount of R (red), G (green) and B (blue) ranging from 0 to 255. For example rgb(0, 0, 0) is black and rgb(255, 0, 0) is red (maximum amount of red and no green or blue). Using hexadecimals, specifying two characters for each R, G and B. For example, #000000 is black and #ff0000 is red. This is because ff is the hexadecimal for 255. In JavaScript, you put 0x before a hexadecimal value (also called hex for short). >>> var n4 = 0x00;>>> typeof n4;"number">>> n4;0>>> var n5 = 0xff;>>> typeof n5;"number">>> n5;255 Exponent Literals 1e1 (can also be written as 1e+1 or 1E1 or 1E+1) represents the number one with one zero after it, or in other words 10. Similarly, 2e+3 means the number 2 with 3 zeros after it, or 2000. >>> 1e110>>> 1e+110>>> 2e+32000>>> typeof 2e+3;"number" 2e+3 means moving the decimal point 3 digits to the right of the number 2. There's also 2e-3 meaning you move the decimal point 3 digits to the left of the number 2. >>> 2e-30.002>>> 123.456E-30.123456>>> typeof 2e-3"number" Infinity There is a special value in JavaScript called Infinity. It represents a number too big for JavaScript to handle. Infinity is indeed a number, as typing typeof Infinity in the console will confirm. You can also quickly check that a number with 308 zeros is ok, but 309 zeros is too much. To be precise, the biggest number JavaScript can handle is 1.7976931348623157e+308 while the smallest is 5e-324. >>> InfinityInfinity>>> typeof Infinity"number">>> 1e309Infinity>>> 1e3081e+308 Dividing by 0 will give you infinity. >>> var a = 6 / 0;>>> aInfinity Infinity is the biggest number (or rather a little bigger than the biggest), but how about the smallest? It's infinity with a minus sign in front of it, minus infinity. >>> var i = -Infinity;>>> i-Infinity>>> typeof i"number" Does this mean you can have something that's exactly twice as big as Infinity—from 0 up to infinity and then from 0 down to minus infinity? Well, this is purely for amusement and there's no practical value to it. When you sum infinity and minus infinity, you don't get 0, but something that is called NaN (Not A Number). >>> Infinity - InfinityNaN>>> -Infinity + InfinityNaN Any other arithmetic operation with Infinity as one of the operands will give you Infinity: >>> Infinity - 20Infinity>>> -Infinity * 3-Infinity>>> Infinity / 2Infinity>>> Infinity - 99999999999999999Infinity NaN What was this NaN you saw in the example above? It turns out that despite its name, "Not A Number", NaN is a special value that is also a number. >>> typeof NaN"number">>> var a = NaN;>>> aNaN You get NaN when you try to perform an operation that assumes numbers but the operation fails. For example, if you try to multiply 10 by the character "f", the result is NaN, because "f" is obviously not a valid operand for a multiplication. >>> var a = 10 * "f";>>> aNaN NaN is contagious, so if you have even only one NaN in your arithmetic operation, the whole result goes down the drain. >>> 1 + 2 + NaNNaN
Read more
  • 0
  • 0
  • 4091

article-image-buttons-menus-and-toolbars-ext-js
Packt
20 Oct 2009
5 min read
Save for later

Buttons, Menus, and Toolbars in Ext JS

Packt
20 Oct 2009
5 min read
The unsung heroes of every application are the simple things like buttons, menus, and toolbars. In this article by Shea Frederick, Steve 'Cutter' Blades, and Colin Ramsay, we will cover how to add these items to our applications. Our example will contain a few different types of buttons, both with and without menus. A button can simply be an icon, or text, or both. Toolbars also have some mechanical elements such as spacers and dividers that can help to organize the buttons on your toolbars items. We will also cover how to make these elements react to user interaction. A toolbar for every occasion Just about every Ext component—panels, windows, grids can accept a toolbar on either the top or the bottom. The option is also available to render the toolbar standalone into any DOM element in our document. The toolbar is an extremely flexible and useful component that will no doubt be used in every application. Ext.Toolbar: The main container for the buttons Ext.Button: The primary handler for button creation and interaction Ext.menu: A menu Toolbars Our first toolbar is going to be rendered standalone in the body of our document. We will add one of each of the main button types, so we can experiment with each: Button—tbbutton: This is the standard button that we are all familiar with. Split Button—tbsplit: A split button is where you have a default button action and an optional menu. These are used in cases where you need to have many options in the same category as your button, of which there is a most commonly used default option. Menu—tbbutton+menu: A menu is just a button with the menu config filled in with options. Ext.onReady(function(){ new Ext.Toolbar({ renderTo: document.body, items: [{ xtype: 'tbbutton', text: 'Button' },{ xtype: 'tbbutton', text: 'Menu Button', menu: [{ text: 'Better' },{ text: 'Good' },{ text: 'Best' }] },{ xtype: 'tbsplit', text: 'Split Button', menu: [{ text: 'Item One' },{ text: 'Item Two' },{ text: 'Item Three' }] }] });}); As usual, everything is inside our onReady event handler. The items config holds all of our toolbars elements—I say elements and not buttons because the toolbar can accept many different types of Ext components including form fields—which we will be implementing later on in this article. The default xtype for each element in the items config is tbbutton. We can leave out the xtype config element if tbbutton is the type we want, but I like to include it just to help me keep track. The button Creating a button is fairly straightforward; the main config option is the text that is displayed on the button. We can also add an icon to be used alongside the text if we want to. Here is a stripped-down button: { xtype: 'tbbutton', text: 'Button'} Menu A menu is just a button with the menu config populated—it's that simple. The menu items work along the same principles as the buttons. They can have icons, classes, and handlers assigned to them. The menu items could also be grouped together to form a set of option buttons, but first let's create a standard menu. This is the config for a typical menu config: { xtype: 'tbbutton', text: 'Button', menu: [{ text: 'Better' },{ text: 'Good' },{ text: 'Best' }]} As we can see, once the menu array config is populated, the menu comes to life. To group these menu items together, we would need to set the group config and the boolean checked value for each item: menu: [{ text: 'Better', checked: true, group: 'quality'}, { text: 'Good', checked: false, group: 'quality'}, { text: 'Best', checked: false, group: 'quality'}] Split button The split button sounds like a complex component, but it's just like a button and a menu combined, with a slight twist. By using this type of button, you get to use the functionality of a button while adding the option to select an item from the attached menu. Clicking the left portion of the button that contains the text triggers the button action. However, clicking the right side of the button, which contains a small down arrow, triggers the menu. { xtype: 'tbsplit', text: 'Split Button', menu: [{ text: 'Item One' },{ text: 'Item Two' },{ text: 'Item Three' }]} Toolbar item alignment, dividers, and spacers By default, every toolbar aligns elements to the leftmost side. There is no alignment config for a toolbar, so if we want to align all of the toolbar buttons to the rightmost side, we need to add a fill as the first item in the toolbar. If we want to have items split up between both the left and right sides, we can also use a fill: { xtype: 'tbfill'} Pop this little guy in a tool-bar wherever you want to add space and he will push items on either side of the fill to the ends of the tool bar, as shown below: We also have elements that can add space or vertical dividers, like the one used between the Menu Button and the Split Button. The spacer adds a few pixels of empty space that can be used to space out buttons, or move elements away from the edge of the toolbar: { xtype: 'tbspacer'} A divider can be added in the same way: { xtype: 'tbseparator'} Shortcuts Ext has many shortcuts that can be used to make coding faster. Shortcuts are a character or two that can be used in place of a configuration object. For example, consider the standard toolbar filler configuration: { xtype: 'tbfill'} The shortcut for a toolbar filler is a hyphen and a greater than symbol: '->' Not all of these shortcuts are documented. So be adventurous, poke around the source code, and see what you can find. Here is a list of the commonly-used shortcuts:
Read more
  • 0
  • 0
  • 7376

article-image-creating-convincing-images-blender-internal-renderer-part1
Packt
20 Oct 2009
9 min read
Save for later

Creating Convincing Images with Blender Internal Renderer-part1

Packt
20 Oct 2009
9 min read
Throughout the years that have passed since the emergence of Computer Graphics, many aspiring artists tried convincingly to recreate the real world through works of applied art, some of which include oil painting, charcoal painting, matte painting, and even the most basic ones like pastel and/or crayon drawings has already made it through the artistic universe of realism. Albeit the fact that recreating the real world is like reinventing the wheel (which some artists might argue with), it is not an easy task to involve yourself into. It takes a lot of practice, perseverance, and personality to make it through.  But one lesson I have learned from the art world is to consciously and subconsciously observe the world around you. Pay attention to details. Observe how a plant behaves at different environmental conditions, look how a paper's texture is changed when wet, or probably observe how water in a river distorts the underlying objects. These are just some of the things that you can observe around you, and there are a million more or even an infinite number of things you can observe in your lifetime. In the advent of 3D as part of the numerous studies involved in Computer Graphics, a lot of effort has been made into developing tools and applications that emulate real-world environment.  It has become an unstated norm that the more realistic looking an image is, the greater the impact it has on viewers.  That, in turn, is partly true, but the real essence into creating stunning images is to know how it would look beautiful amidst the criteria that are present.  It is not a general requirement that all your images must look hyper realistic, you just have to know and judge how it would look good, after all that's what CG is all about.  And believe it or not, cheating the eye is an essential tool of the trade. In 3D rendering context, there are a number of ways on how to achieve realism in your scenes, but intuitively, the use of external renderers and advanced raytracers does help a lot in the setup and makes the creation process a bit lighter as compared to manually setting up lights, shaders, etc.  But that comes at a rendering time tradeoff.  Unfortunately though, I won't be taking you to the steps on how to setup your scenes for use in external renderers, but instead I'll walk you through the steps on how to achieve slightly similar effects as to that of externals with the use of the native renderer or the internal renderer as some might call it. Hopefully in this short article, I can describe to you numerous ways on how to achieve good-looking and realistic images with some nifty tools, workarounds from within Blender and use the Blender Internal Renderer to achieve these effects. So, let's all get a cup of tea, a comfortable couch, and hop in! On a nutshell, what makes an image look real? Shading, Materials, Shadows, Textures, Transparency, Reflection, Refraction, Highlights, Contrast, Color Balance, DoF, Lens Effects, Geometry (bevels), Subtlety, Environment, Staging, Composite Nodes, Story.. Before Anything Else... Beyond anything that will be discussed here, nothing beats a properly planned and well-imagined scene.  I cannot stress enough how important it is to begin everything with deep and careful planning.  Be it just a ball on a table or a flying scaled bear with a head of a tarsier and legs that of a mouse (?), it is very vital to plan beforehand.  Believe me, once you've planned everything right, you're almost done with your work (which I didn't believe then until I did give it a try).  And of course, with your touch of artistic flavors, a simple scene could just be the grandest one that history has ever seen. This article, by any means, does not technically teach you how to model subjects for your scene nor does it detail the concepts behind lighting (which is an article on its own and probably beyond my knowledge) nor does it teach you “the way” to do things but instead it will lead you through a process by which you will be able to understand your scene better and the concepts behind. I would also be leading you through a series of steps using the same scene we've setup from the beginning and hopefully by the end of the day, we could achieve something that comprises what has been discussed here so far. I have blabbered too much already, haven't I? Yeah.  Ok, on to the real thing. Before you begin the proceeding steps, it is a must (it really really is) to go grab your copy of Blender over at http://www.blender.org/download/get-blender/. The version I used for this tutorial is 2.49a (which should be the latest one being offered at Blender.org [as of this writing]). Scene Setup With every historical and memorable piece, it is a vital part of your 3d journey to setup something on your scene.  I couldn't imagine how a 3D artist could pass on a work with a blank animated scene, hyper minimal I might say. To start off, fire up Blender or your favorite 3D App for that matter and get your scene ready with your models, objects, subjects, or whatever you call them, just get them there inside your scene so we could have something to look at for now, won't we? On the image below (finally, a graphic one!), you could see a sample scene I've setup and a quick render of the said scene. The first image shows my scene with the model, two spheres, a plane, a lamp, and a camera. The second image shows the rendered version.   You'll notice that the image looks dull and lifeless, that is because it lacks the proper visual elements necessary for creating a convincing scene.  The current setup is all set to default, with the objects having no material data but just the premade ones set by Blender and the light’s settings set as they were by default. Shading and Materials To address some issues, we need to identify first what needs to be corrected.  The first thing we might want to do is to add some initial materials to the objects we have just so we could clearly distinguish their roles in the scene and to add some life to the somewhat dry set we have here.  To do so, select one object at a time and add a material. Let’s first select the main character of the scene (or any subject you wish for that matter) by clicking RMB (Right Mouse Button) on the character object, then under the Buttons Window, select Shading (F5), then click the Material Buttons tab, and click on “Add New” to add a new material to our object. Adding a New Material After doing so, more options will show up and this is where the real fun begins. The only thing we’ll be doing for now is to add some basic color and shading to our objects just so we could deviate from the standard gray default.  You’ll notice on the image below that I’ve edited quite a few options.  That’s what we only want for now, let’s leave the other settings as they are and we’ll get back to it as soon as we need to. Character Initial Material Settings   Big Sphere Initial Material Settings Small sphere Initial Material Settings   Ground Initial Material Settings If we do a test render now, here’s how it will look like: Render With Colors Still not so convincing, but somehow we managed to add a level of variety to our scene as compared to the initial render we’ve made.  Looking at the latest render we did, you’ll notice that the character with the two spheres still seem to be floating in space, creating no interaction whatsoever with the ground plane below it. Another thing would be the lack of diffuse color on some parts of the objects, thus creating a pitch black color which, as in this case, doesn’t seem to look good at all since we’re trying to achieve a well-lit, natural environment as much as possible. A quick and easy solution to this issue would be to enable Ambient Occlusion under the World Settings tab. This will tell Blender to create a fake global illumination effect as though you have added a bunch of lights to create the occlusion.  This would be a case similar to adding a dome of spot lights, with each light having a low energy level, creating a subtle AO effect. But for the purposes of this article, we’d be settling for Ambient Occlusion since it is faster to setup and eliminates the additional need for further tweaking. We access the AO (Ambient Occlusion) menu via the World Buttons tab under Shading (F5) menu then clicking the Amb Occ subtab.  Activate Ambient Occlusion then click on Use Falloff and edit the default strength of 1.00 to 0.70, doing so will create further diffusion on darker areas that have been hidden from the occlusion process.  Next would be to click Pixel Cache, I don’t know much technically what this does but what I know from experience is this speeds up the occlusion calculation.   Ambient Occlusion Settings Below, you’ll see the effects of AO as applied to the scene.  Notice the subtle diffusion of color and shadows and the interaction of the objects and the plane ground through the occlusion process.  So far we’ve only used a single lamp as fill light, but later on we’ll be adding further light sources to create a better effect. Render with Ambient Occlusion Whew, we’ve been doing something lately, haven’t we? So far what we did was to create a scene and a render image that will give us a better view of what it’s going to look like.  Next stop, we’ll be creating a base light setup to further create shadows and better looking diffusion. Soon we go!
Read more
  • 0
  • 0
  • 5440
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-delicious-tagometer-widget
Packt
20 Oct 2009
10 min read
Save for later

Delicious Tagometer Widget

Packt
20 Oct 2009
10 min read
Background Concept Delicious was founded by Joshua Schachter in 2003 and acquired by Yahoo in 2005. This website was formerly used to run in the domain http://del.icio.us hence known as del.icio.us. Now, this domain redirects to the domain http://delicious.com. This website got redesigned in July 2008 and the Delicious 2.0 went live with new domain, design and name. Delicious is probably one of the largest social bookmarking website in the WWW world for discovering, sharing and storing the interesting and useful URL on the Internet. When saving the URL, user can enter tags for the URL which is quite useful when you’ve to search the particular URL from many bookmarks. The number of saves of a particular URL in Delicious is one of the measurements for checking popularity of that URL. Delicious Tagometer As the name specifies, Delicious Tagometer is a badge which displays the tags as well count of the users who have saved the particular URL. Tagometer gets displayed in the web page which contains the code given below: <script src="http://static.delicious.com/js/blogbadge.js"></script> This is the new URL of the Tagometer badge from the Delicious. The URL for the Tagometer used to be different in the del.icio.us domain in past. For more information on future updates, you can check http://delicious.com/help. The delicious Tagometer looks as shown: As you can easily guess, the above Tagometer is placed on a web page whose URL has not yet been saved in Delicious. Now let’s take a look at the Tagometer which is placed on a web page whose URL is saved by many users of Delicious. In the above widget, the text “bookmark this on Delicious" is the hyperlink for saving the URL in delicious. To save an URL in Delicious, you have to provide the URL and give a Title on the http://delicious.com/save page. After clicking on the “bookmark this on Delicious” hyperlink on the Delicious Tagometer widget you can see the image of the web page on delicious. The Delicious Tagometer widget also shows the list of tags which are used by the users of Delicious to save the URL. Each of these tags link to a tag specific page of Delicious. For example, an URL saved with tag JavaScript can be found on the page http://delicious.com/tag/javascript. And, the number is linked to the URL specific page on Delicious. For example, if you wish to view the users and their notes on the saves of the URL- http://digg.com, then the URL of delicious will be http://delicious.com/url/926a9b7a561a3f650ff41eef0c8ed45d The last part “926a9b7a561a3f650ff41eef0c8ed45d” is the md5 hash of the URL http://digg.com. The md5 is a one way hashing algorithm which converts a given string to a 32 character long string known as md5 digest. This hashed string can’t be reversed back into original string.  The md5 function protects and ensures data integrity of Delicious Data Feeds. Delicious data feeds are read-only web feeds containing bookmark information and other information which can be used third party websites. These feeds are available into two different format: RSS and JSON. Among the various data feeds on the Delicious, let’s look at the details of the data feed which contains summary information of a URL. According to Delicious feed information page, these data feed for URL information can be retrieved via following call, http://feeds.delicious.com/v2/json/urlinfo/{url md5} It clearly specifies summary of URL can be retrieved in the json format only from Delicious. To get the summary about a URL, You can provide the actual URL in the url parameter of the above URL. Alternatively, you can provide md5() hash of the url in the hash parameter in the above URL. Now, let’s look at feed URLs which can be used to access the summary of the http://digg.com from Delicious: http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url=http://digg.com OR http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&hash=926a9b7a561a3f650ff41eef0c8ed45d From the above URLs, it is clear that md5 hash of the string "http://digg.com" is 926a9b7a561a3f650ff41eef0c8ed45d When JSON is used as the format of data returned form Delicious feed then you must specify the JavaScript callback function to handle the JSON data. Now, let look at the JSON data which is returned from any of the above URL of Delicious feed. displayTotalSaves([{"hash":"926a9b7a561a3f650ff41eef0c8ed45d","title":"digg", "url":"http://digg.com/","total_posts":51436,"top_tags":{"news":23581, "digg":10771,"technology":10713,"blog":8628,"web2.0":7800, "tech":6459,"social":5436,"daily":5173,"community":4477,"links":2512}}]) As you can see clearly, the above JSON data contains hash of URL, the URL itself, total no of saves in Delicious in total_posts variable. Along with them, different tags including number of times that tag is used by different users of Delicious for saving the URL  http://digg.com. If the URL is not saved in Delicious then data returned from Delicious feed will be like this : displayTotalSaves([]) Now, having understod the information returned above, let’s see how to create Delicious widget step by step. Creating Delicious Tagometer Widget Our Delicious Tagometer widget looks very similar to actual Delicious Tagometer widget but has different format and texts. In the Tagometer badge provided by delicious, there is no option for specifying a particular URL whose summary is to be displayed. It automatically displays the details of the URL of the web page containing the code. While in our custom widget, you can also specify the URL explicitly in the badge which is an optional parameter. For creating this widget, we will use JavaScript, CSS, XHTML and Delicious’s data feed in JSON format. The above image is of the Delicious widget which we’re going to make and you can see clearly that the provided URL is not yet saved on Delicious. Now, let’s look at the Custom Delicious Tagometer which we can see for a URL saved on the delicious. The above badge of delicious is displayed for the URL: http://yahoo.com. Writing Code for Delicious First of all, let’s start looking at the JavaScript code for handling the parameters-url and title of the web page, when it is not provided. If these parameters are not defined explicitly then url and title of the web page using the widget is provided for saving the bookmark. if(typeof delicious_widget_url!='undefined') delicious_widget_url=encodeURIComponent(delicious_widget_url);else delicious_widget_url=encodeURIComponent(document.location);if(typeof delicious_widget_title!='undefined') delicious_widget_title=encodeURIComponent(delicious_widget_title);else delicious_widget_title=encodeURIComponent(document.title); As can be seen from the above code, if the variable delicious_widget_url is not defined already then the URL of the current document encoded with encodeURIComponent() function is assigned to this variable. If delicious_widget_url variable is already defined then it is encoded with encodeURIComponent() function and assigned to the same variable. The typeof JavaScript operator can be used for checking the type of variable and also serves a very useful purpose of checking whether the variable or function is already defined or not. For example, the statement: typeof xyz==’function’ returns true if the function xyz is already defined. Similarly, if the variable delicious_widget_title is not defined then document.title, which contains title of current web page, is encoded with encodeURIComponent() function and assigned to the delicious_widget_title variable . Next, a variable del_rand_number is defined for handling multiple instances of the widget. var del_rand_number=Math.floor(Math.random()*1000); The Math.random() function returns random values between 0 to 1 and when multiplied by 1000 results in a random number between 1 to 1000. Since this random number is a  floating point number hence floor() function of JavaScript Math Object is used for converting it to the greatest whole number which is less than or equal to generated random number. The Math object of JavaScript has three different functions which can be used to convert a floating point number to whole number:Math.floor(float_val) – converts to greatest integer less than or equal to float_val.Math.ceil(float_val) – converts to smallest integer grater than or equal to float_val.Math.round(float_val) – converts to nearest integer. If the decimal portion of float_val is greater than or equal to .5 then the resulting integer is the next whole number otherwise resulting number is rounded to the nearest integer less than float_val. After that, now using above random number let’s define a variable which holds the “id” of the element in widget for displaying total no. of saves and tags. var del_saved_id="delicious-saved-"+del_rand_number; Now, let’s look at the initWidget() function for initializing the widget. function initWidget(){ //write the elements needed for widget writeWidgetTexts(); //now attach the stylesheet to the document var delCss=document.createElement("link"); delCss.setAttribute("rel", "stylesheet"); delCss.setAttribute("type", "text/css"); delCss.setAttribute("href", "http://yourserver.com/delicious/delicious.css"); document.getElementsByTagName("head")[0].appendChild(delCss); //now call the script of delicious var delScript = document.createElement("script"); delScript.setAttribute("type", "text/javascript"); delScript.setAttribute("src", "http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url="+delicious_widget_url); //alert(delicious_widget_url); document.getElementsByTagName("head").item(0).appendChild(delScript); } At the start of the above code, the function writeWidgetTexts(); is called for writing the content of widget. The functions createElement() and setAttribute() are DOM manipulation function for creating a element and adding attribute to the element respectively. So, the next four statements of the above function create link element and sets various attributes for attaching CSS document to the page using widget. Once link element is created and various attribute is assigned to it the next step is to append it to the document using widget, which is done with appendChild() function in the next line of above function. getElementsByTagName() is a DOM function for accessing the document by the name of tag. Unlike getElementById() which access single element in the document, getElementsByTagName() can access multiple elements of DOM with the help of index. For example, document.getElementsByTagName("div")[0] or document.getElementsByTagName("div").item(0) refers to the first division element of the document Similarly, script element is created for getting JSON feed from Delicious. The call back JavaScript function displayTotalSaves() is used for handling JSON data returned from Delicious.
Read more
  • 0
  • 0
  • 1757

article-image-building-web-service-driven-application-flash-drupal
Packt
20 Oct 2009
6 min read
Save for later

Building a Web Service-driven Application with Flash in Drupal

Packt
20 Oct 2009
6 min read
So, let's take a step-by-step approach on how to accomplish this on the Flash side, which as far as I am concerned, is the fun side! Click here to access all the codes used in this article. Step 1: Creating our Flash application With our chapter2 project open, we can shift our focus to the Actions panel within the Flash IDE. Although working with the Actions panel is great for small applications, we will eventually build onto this Flash application, which might make it impractical to keep all of our ActionScript code within the Actions panel. Because of this, we will first need to create a separate ActionScript file that will serve as our main entry point for our Flash application. This will allow us to easily expand our application and add to the functionality without modifying the Actions panel for every addition we make. Step 2: Creating a main.as ActionScript file For this step, we will simply create an empty file next to our chapter2.fla file called main.as. After you have created this new file, we will then need to reference it within our Actions panel. To do this, we will use the include keyword in ActionScript to include this file as the main entry point for our application. So, shifting our focus back to the chapter2.fla file, we will then place the following code within the Actions panel: include "main.as";stop(); Now that we are referencing the main.as file for any of the ActionScript functionality, we will no longer need to worry about the Actions panel and add any new functionality directly to the main.as file. Now, for the following sections, we will use this main.as file to place all of our ActionScript code that will connect and extract information from our Drupal system, and then populate that information in a TextField that we will create later. So, let's jump right in and write some code that connects us with our Drupal system. Step 3: Connecting to Drupal For this step, we will first need to open up our empty main.as file so that we can add custom functionality to our Flash application. With this file open in our Flash IDE, our first task will be to connect with Drupal. Connecting to Drupal will require us to make a remote call to our Drupal installation, and then handle its response correctly. This will require the use of asynchronous programming techniques along with some standard remoting classes built into the ActionScript 3 library. I will spend some time here discussing the class used by ActionScript 3 to achieve remote communication. This class is called NetConnection. Using the NetConnection class The NetConnection class in ActionScript 3 is specifically used to achieve remote procedure calls within a Flash application. Luckily, this class is pretty straight forward and does not have a huge learning curve on understanding how to utilize it for communicating with Drupal. Using this class requires that we first create an instance of this class as an object, and then initialize that object with the proper settings for our communication. But let's tackle the creation first, which will look something like this in our main.as file: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection(); Now, you probably noticed that I decided to name my instance of this net connection drupal. The reason for this is to make it very clear that any place in our Flash application where we would like to interact with Drupal, we will do so by simply using our drupal NetConnection object. But before we use this connection, we must first specify what type of connection we will be using. In any NetConnection object, we can do this by providing a value for the variable objectEncoding . This variable lets the connection know how to structure the XML format when communicating back and forth between Flash and Drupal. Currently, there are only two types of encoding to choose from: AMF0 or AMF3. AMF0 is used for ActionScript versions less than 3, while AMF3 is used for ActionScript 3. ActionScript 1 and 2 are much less efficient than version 3, so it is highly recommended to use ActionScript 3 over 1 or 2. Since we are using ActionScript 3, we will need to use the AMF3 format, and we can provide this as follows: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3; Now that we have an instance ready to go, our first task will be to connect to the Drupal gateway that we set up in the previous section. Connecting to a remote gateway Connecting to a remote gateway can be performed using the connect command on our drupal NetConnection object. But in order for us to connect, we must first determine the correct gateway URL to pass to this function. We can find this by going back to our Drupal installation and navigating to Administer | Services. In the Browse section, you will see a link to the servers available for remote procedure calls as shown in the following screenshot: For every listed server, we can click on each link to verify that the server is ready for communication. Let's do this by clicking on the link for AMFPHP, which should then bring up a page to let us know that our AMFPHP gateway is installed properly. We can also use this page to determine our AMFPHP gateway location, since it is the URL of this page. By observing the path of this page, we can add our AMFPHP server to our main.as file by combining the base URL of our site and then adding the AMFPHP services gateway to that base. // Declare our baseURL and gateway string.var baseURL:String = "http://localhost/drupal6";var gateway:String = baseURL + "/services/amfphp";// Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3;// Connect to the Drupal gatewaydrupal.connect( gateway ); It is important to note that the connect routine is synchronous, which means that once this function is called, we can immediately start using that connection. However, any remote procedure call that we make afterwards, will be asynchronous, and will need to be handled as such. The function that can be used to make these remote procedure calls to Drupal is called call.
Read more
  • 0
  • 0
  • 2319

article-image-skinners-toolkit-plone-3-theming-part-2
Packt
20 Oct 2009
4 min read
Save for later

Skinner's Toolkit for Plone 3 Theming (Part 2)

Packt
20 Oct 2009
4 min read
(For more resources on Plone, see here.) Text editors The last key piece to successfully skinning a site is to choose a text editor or CSS editor that matches your needs and plays well with Plone. We are not talking about a word processor here, like Microsoft Word or Pages; rather, a text editor is a type of program used for editing plain text files. Text editors are often provided with operating systems or software development packages, and can be used to change configuration files and programming language source code. We'll look at a few of the more popular text editors that are appropriate for Plone development and theming. TextMate TextMate is a combination of text editor and programming tool that is exclusively for the Mac, and can be found at http://macromates.com. One of the key joys of working with TextMate is that it lets you open up an entire file structure at once to make navigation between related files easier. For Plone, this is essential. Your average file structure will look something like this: Rather than opening the entire buildouts folder, or even the plonetheme.copperriver folder, generally you only want to open the structure closest to the files you need in order to keep performance snappy—in this case, mybuildout[rockaway]/src/plonetheme.copperriver/plonetheme/copperriver/: As you can see, it opens the entire project in a clean interface with an easily navigable structure. Without this feature, skinning for Plone would be much more time-consuming. TextMate also offers numerous programmer-related tools: You can open two files at once (or more), and using the diff option you can compare the files easily Subversion (svn) support Ability to search and replace in a project Regular expression search and replace (grep) Auto-indent for common actions such as pasting text Auto-completion of brackets and other characters Clipboard history Foldable code blocks Support for more than 50 languages Numerous key combinations (for example, Apple + T opens a search window that makes it easy to locate a file) Themable syntax highlight colors Visual bookmarks to jump between places in a file Copy/paste of columns of text Bundles And much, much more The Bundle feature is one of the more interesting aspects of the tool. If you look at the HTML bundle, for example, it shows a list of common actions that you might wish to perform in a given document, and on the right, the code that spawns that action, and the hot-key that activates it. There's even a Zope/Plone TextMate support bundle found at http://plone.org/products/textmate-support that was developed by some of Plone's core developers. It enhances TextMate's already existing support for Python, XML, (X)HTML, CSS, and Restructured Text by adding features aimed specifically at the modern day Zope and Plone developer. For the geeks in the audience, the bundle's features include: Doctest support (restructured text with inline Python syntax and auto-indent of python code), pdb support (for debugging), ZCML support (no more looking up directives with our handy and exhaustive snippets), and a ZPT syntax that marries the best of both worlds (XML strictness with the goodness of TextMate's HTML support). This bundle plus TextMate's other capabilities make switching to developing for Plone on a Mac a good idea any day! As well as assigning a single key equivalent to a bundle item, it is possible to assign a tab trigger to the item. This is a sequence of text that you enter in the document and follow it by pressing the tab key. This will remove the sequence entered and then execute the bundle item. TextMate is full of hot-keys and features in general, yet it's surprisingly compact. Thankfully, the documentation is thorough. TextMate is a dream for themers and programmers alike. For those who are still new at CSS, another tool might be a good place to start, but for power users, TextMate is the primary tool of choice.
Read more
  • 0
  • 0
  • 3034

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

Modifying an Existing Theme in Drupal 6: Part 1

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

Integrating ZK with Other Frameworks

Packt
20 Oct 2009
7 min read
Integration with the Spring Framework Spring is one of the most complete lightweight containers, which provides centralized, automated configuration, and wiring of your application objects. It improves your application's testability and scalability by allowing software components to be first developed and tested in isolation, then scaled up for deployment in any environment. This approach is called the POJO (Plain Old Java Object) approach and is gaining popularity because of its flexibility. So, with all these advantages, it's no wonder that Spring is one of the most used frameworks. Spring provides many nice features: however, it works mainly in the back end. Here ZK may provide support in the view layer. The benefit from this pairing is the flexible and maturity of Spring together with the easy and speed of ZK. Specify a Java class in the use attribute of a window ZUL page and the world of Spring will be yours. A sample ZUL looks like: <?xml version="1.0" encoding="UTF-8"?> <p:window xsi_schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul " border="normal" title="Hello!" use="com.myfoo.myapp.HelloController"> Thank you for using our Hello World Application. </p:window> The HelloController points directly to a Java class where you can use Spring features easily. Normally, if a Java Controller is used for a ZUL page it becomes necessary sooner or later to call a Spring bean. Usually in Spring you would use the applicationContext like: ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDAO userDAO = (UserDAO) ctx.getBean("userDAO"); Then the userDAO is usable for any further access. In ZK there is a helper class SpringUtil. It wrapps the applicationContext and simplifies the code to: UserDAO userDAO = (UserDAO) SpringUtil.getBean("userDAO"); Pretty easy, isn't it? Let us examine an example. Assume we have a small web application that gets flight data from a flight table. The web.xml file looks like: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xsi_schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>IRT-FLIGHTSAMPLE</display-name> <filter> <filter-name>hibernateFilter</filter-name> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name> hibernateFilter </filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-jdbc.xml ,classpath:applicationContext-dao.xml ,classpath:applicationContext-service.xml ,classpath:applicationContext.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <session-config> <!-- Default to 30 minute session timeouts --> <session-timeout>30</session-timeout> </session-config> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> <servlet> <description> <![CDATA[The servlet loads the DSP pages.]]> </description> <servlet-name>dspLoader</servlet-name> <servlet-class> org.zkoss.web.servlet.dsp.InterpreterServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>dspLoader</servlet-name> <url-pattern>*.dsp</url-pattern> </servlet-mapping> <!-- ZK --> <listener> <description> Used to cleanup when a session is destroyed </description> <display-name>ZK Session Cleaner</display-name> <listener-class> org.zkoss.zk.ui.http.HttpSessionListener </listener-class> </listener> <servlet> <description>ZK loader for ZUML pages</description> <servlet-name>zkLoader</servlet-name> <servlet-class> org.zkoss.zk.ui.http.DHtmlLayoutServlet </servlet-class> <!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It must be the same as <url-pattern> for the update engine. --> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zul</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zhtml</url-pattern> </servlet-mapping> <servlet> <description>The asynchronous update engine for ZK </description> <servlet-name>auEngine</servlet-name> <servlet-class> org.zkoss.zk.au.http.DHtmlUpdateServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>auEngine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> <welcome-file-list id="WelcomeFileList"> <welcome-file>index.zul</welcome-file> </welcome-file-list> </web-app> Furthermore let's have a small ZUL page that has the interface to retrieve and show flight data: <?xml version="1.0" encoding="UTF-8"?> <p:window xsi_schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul " id="query" use="com.myfoo.controller.SampleController"> <p:grid> <p:rows> <p:row> Airline Code: <p:textbox id="airlinecode"/> </p:row> <p:row> Flightnumber: <p:textbox id="flightnumber"/> </p:row> <p:row> Flightdate: <p:datebox id="flightdate"/> </p:row> <p:row> <p:button label="Search" id="search"/> <p:separator width="5px"/> </p:row> </p:rows> </p:grid> <p:listbox width="100%" id="resultlist" mold="paging" rows="21" style="font-size: x-small;"> <p:listhead sizable="true"> <p:listheader label="Airline Code" sort="auto" style="font-size: x-small;"/> <p:listheader label="Flightnumber" sort="auto" style="font-size: x-small;"/> <p:listheader label="Flightdate" sort="auto" style="font-size: x-small;"/> <p:listheader label="Destination" sort="auto" style="font-size: x-small;"/> </p:listhead> </p:listbox> </p:window> As you can see, the use attribute of the ZUL page is the link to the SampleController. The SampleController handles and controls the objects. Let's have a short look at the SampleController sample code: public class SampleController extends Window { private Listbox resultlist; private Textbox airlinecode; private Textbox flightnumber; private Datebox flightdate; private Button search; /** * Initialize the page */ public void onCreate() { // Components resultlist = (Listbox) this.getPage().getFellow("query").getFellow("resultlist"); airlinecode = (Textbox) this.getPage().getFellow("query").getFellow("airlinecode"); flightnumber = (Textbox) this.getPage().getFellow("query").getFellow("flightnumber"); flightdate = (Datebox) this.getPage().getFellow("query").getFellow("flightdate"); search = (Button) this.getPage().getFellow("query").getFellow("search"); search.addEventListener("onClick", new EventListener() { public void onEvent(Event event) throws Exception { performSearch(); } }); } /** * Execute the search and fill the list */ private void performSearch() { //(1) List<Flight> flightlist = ((FlightService) SpringUtil.getBean("flightService")). getFlightBySearch(airlinecode.getValue(), flightnumber.getValue(), flightdate.getValue(),""); resultlist.getItems().clear(); for (Flight aFlightlist : flightlist) { // add flights to list } } } /* (1)-shows the integration of the Spring Bean*/ Just for completion the context file for Spring is listed here with the bean that is called. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction. interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="remove*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="flightService" parent="txProxyTemplate"> <property name="target"> <bean class="com.myfoo.services.impl.FlightServiceImpl"> <property name="flightDAO"> <ref bean="flightDao"/> </property> </bean> </property> </bean> </beans> In short we have learned how to use Spring with ZK and about the configurations. We have seen that the integration is quite smooth and also powerful.
Read more
  • 0
  • 0
  • 2521

article-image-implementing-workflow-alfresco-3
Packt
20 Oct 2009
5 min read
Save for later

Implementing Workflow in Alfresco 3

Packt
20 Oct 2009
5 min read
Workflow is the automation of a business process, during which documents are passed from one participant to another for action, according to a set of procedural rules. Every Content Management System implementation has its own workflow requirements. For some companies, workflow could be a simple approval process. For some companies, it could be a complex business process management system. Workflow provides ownership and control over the content and processes. Introduction to the Alfresco workflow process Alfresco includes two types of out of the box workflow. The first is the Simple Workflow, which is content-oriented, and the other is the Advanced Workflow, which is task-oriented. The Simple Workflow process in Alfresco involves the movement of documents through various spaces.A content item is moved or copied to a new space at which point a new workflow instance is attached, which is based on the workflow definition of the space. A workflow definition is unaware of other related workflow definitions. The Advanced Workflow process is task-oriented, where you create a task, attach documents that are to be reviewed, and assign it to appropriate reviewers. The same robust workflow capabilities are available in Document Management (DM), Records Management (RM), Web Content Management (WCM), and throughout our applications, which includes Alfresco Share. You can use the out of the box features provided by both types of workflow, or you can create your own custom advanced workflow, according to the business processes of your organization. Simple Workflow Consider a purchase order that moves through various departments for authorization and eventual purchase. To implement Simple Workflow for this in Alfresco, you will create spaces for each department and allow documents to move through various department spaces. Each department space is secured, only allowing the users of that department to edit the document and to move it to the next departmental space in the workflow process. The workflow process is so flexible that you could introduce new steps for approval into the operation without changing any code. Out of the box features Simple Workflow is implemented as an aspect that can be attached to any document in a space through the use of business rules. Workflow can also be invoked on individual content items as actions. Workflow has two steps. One is for approval while the other one is for rejection. You can refer to the upcoming image, where workflow is defined for the documents in a space called Review Space. The users belonging to the Review Space can act upon the document. If they choose to Reject, then the document moves to a space called Rejected Space. If they choose to Approve, then the document moves to a space called Approved Space. You can define the names of the spaces and the users on the spaces, according to your business requirements. The following figure gives a graphical view of the Approved Space and the Rejected Space: Define and use Simple Workflow The process to define and use Simple Workflow in Alfresco is as follows: Identify spaces and set security on those spaces Define your workflow process Add workflow to content in those spaces, accordingly Select the email template and the people to send email notifications to Test the workflow process Let us define and use a Simple Workflow process to review and approve the engineering documents on your intranet. Go to the Company Home > Intranet > Engineering Department space and create a space named ProjectA by using an existing Software Engineering Project space template. Identify spaces and security If you go to the Company Home > Intranet > Engineering Department > ProjectA > Documentation space, then you will notice the following sub-spaces: Samples: This space is for storing sample project documents. Set the security on this space in such a way that only the managers can edit the documents. Drafts: This space contains initial drafts and documents of ProjectA that are being edited. Set the security in such a way that only a few selected users (such as Engineer1, Engineer2— as shown in the upcoming image) can add or edit the documents in this space. Pending Approval: This space contains all of the documents that are under review. Set the security in such a way that only the Project Manager of ProjectA can edit these documents. Published: This space contains all of the documents that are Approved and visible to others. Nobody should edit the documents while they are in the Published space. If you need to edit a document, then you need to Retract it to the Drafts space and follow the workflow process, as shown in the following image:    Defining the workflow process Now that you have identified the spaces, the next step is to define your workflow process. We will add workflow to all of the documents in the Drafts space. When a user selects the Approve action called Submit for Approval on a document, then the document moves from the Drafts space to the Pending Approval space. We will add workflow to all of the documents in the Pending Approval space. When a user selects the Approve action called Approved on a document, then the document moves from the Pending Approval space to the Published space. Similarly, when a user selects the Reject action called Re-submit on a document, then it moves from the Pending Approval space to the Drafts space. We will add workflow to all of the documents in the Published space. When a user selects the Reject action called Retract on a document, then it moves from the Published space to the Drafts space. You can have review steps and workflow action names according to your business's requirements.
Read more
  • 0
  • 0
  • 2474

article-image-date-and-calendar-module-drupal-5-part-1
Packt
20 Oct 2009
5 min read
Save for later

Date and Calendar Module in Drupal 5: Part 1

Packt
20 Oct 2009
5 min read
Recipe 33: Understanding Date formats Drupal dates are typically stored in one of two ways. Core Drupal dates—including Node: Created Time, and Node: Updated Time—are stored as Unix timestamps. Contributed module date fields can be stored as either a timestamp or a format known as ISO. Neither style is particularly friendly to human readers, so both field types are usually formatted before users see them. This recipe offers a tour of places in Drupal where dates can be formatted and information on how to customize the formats. What's that Lucky Day?The Unix timestamp 1234567890 fell on Friday the 13th, in February, 2009. This timestamp marks 1,234,567,890 seconds since January 1, 1970. The same date/time combination would be stored in a date field in ISO format as 2009-02-13T23:31:30+00:0. ISO is an abbreviation for the International Organization for Standardization Opening the browser windows side-by-side will help you understand date formatting. In the left window, open YOURSITE.com/admin/settings/ date-time to view the settings page for date and time. In the right window, open the API page of code that defines these system date time settings at http://api.drupal.org/api/function/system_date_time_settings/5. Compare each item in the $datemedium array, for instance, with the associated Medium date format drop-down. a – am/pm D – Day, Mon through Sun d – Date, 01 to 31 (with leading zeroes) F – Month, January through December (mnemonic, F = Full name) g – Hours, 1 through 12 H – Hours, 00 through 23 i – Minutes, 00 to 59 j – Date, 1 to 31 (No leading zeroes) l – Sunday through Saturday m – Month, 01 through 12 M – Month, Jan through Dec s – Seconds, 00 through 59 (with leading zeroes) S – Month Suffix, st, nd, rd, or th. Works well with j Y – Year, Examples: 1999 or 2011 Below is the list of codes for many commonly used date and time formats. A more comprehensive list appears at http://us.php.net/date. Explore Drupal places where these codes may be used. The first four locations in the table below are available in the Drupal administrative interface. The last three involve editing files on the server—these edits are completely optional. Location Details CCK field setup Custom Input formats admin/content/types/story/add_field   After the field widget is specified admin/content/types/<CONTENTTYPE>/fields/field_<FIELDNAME> Near the top of the page.   Near the bottom of the page:   Formatting Fields in Views. admin/build/views/<VIEW_NAME>/edit CCK Date fields are set via the Options drop-down in the Fields fieldset.   Custom date formats for core fields, such as Node: Created Time are set via handler and options from elements.   Default Date and Time settings admin/settings/date-time Set the default time zone, Short, Medium, and Long date formats, and the first day of the week.   Post Settings This may be one of the harder-to-find settings in Drupal, enabling the Post settings to be turned-off for specified content types. (An example of a post setting would be: Submitted by admin on Sun, 10/12/2008 - 4:55pm. The setting is found on the right-hand side of this URL: admin/build/themes/settings Use the following mouse click trail to get to this URL: Administer | Site Building | Themes | Configure (Click on the Configure tab at the top of the page. If you click on the Configure link in the Operations column, you will still need to click the Configure tab at the top to get to the global settings.)   Variable overrides in settings.php You may override variables at the bottom of the /sites/default/settings.php file. Remove the appropriate pound signs to enable the $conf array, and add a setting as shown below. Note that this is a quick way to modify the post settings format, which draws from the medium date variable. $conf = array( #   'site_name' => 'My Drupal site', #   'theme_default' => 'minnelli', #   'anonymous' => 'Visitor', 'date_format_medium' => 'l F d, Y'  ); *.tpl.php files Examples: node-story.tpl.php <?php print format_date($node->created, 'custom', 'F Y'); ?> comment.tpl.php <?php echo t('On ') . format_date($comment->timestamp,   'custom'  , 'F jS, Y'); ?> <?php echo theme('username',   $comment) . t(' says:'); ?> template.php Redefine $variables['submitted'] Example from blommor01 theme:   $vars['submitted'] =  t('!user - <abbr class="created"   title="!microdate">!date</abbr>', array(    '!user' => theme('username', $vars['node']),    '!date' => format_date($vars['node']->created),    '!microdate' => format_date($vars['node']->   created,'custom', "Y-m-dTH:i:sO")   )); Recipe notes Note that when using the PHP date codes, additional characters may be added, including commas, spaces, and letters. In the template.php example, a backslash was used to show that the letter 'T' will be printed, rather than the formatted return values. Below are more examples of added characters: F j, Y, g:i a // August 27, 2010, 5:16 pmm.d.y // 08.27.10 You may occasionally find that an online date converter comes in handy. http://www.timestampconverterer.com/ (this URL includes the word "converter" followed by another "er"). http://www.coryking.com/date-converter.php
Read more
  • 0
  • 0
  • 2719
article-image-mastering-phpmyadmin-4-editions-5-years
Packt
20 Oct 2009
4 min read
Save for later

Mastering phpMyAdmin: 4 Editions in 5 years

Packt
20 Oct 2009
4 min read
Among the daily deluge of spam, sometimes there is a real email – and sometimes even an important one. I received such an email at the end of October 2003 from Louay Fatoohi, presenting himself as the Editorial Director of a new publishing company, Packt Publishing. He was asking if I would be interested in writing a book about phpMyAdmin (which is a web interface for the MySQL database). At this time, our software product was already popular with about 150,000 downloads per month, but the lack of serious and complete user documentation held it back. This translated into many requests from users about how to accomplish some tasks with the software. Moreover, the small team of five active developers (all volunteers) was using all its free time for planning and coding new features so we did not see how to improve the documentation with volunteer work only. I did not know Mr Fatoohi but his email (and the following ones) looked serious so I committed myself to this project. I noticed that producing a clear book outline was very important. I already had in mind that each chapter should focus on a specific task or group of similar tasks. In the next days, a few iterations of the outline were done to balance the chapter lengths. Receiving a paper contract from England was new for me – in fact the whole process felt new to me as this was my first book. Writing for others is challenging and dealing with the comments of reviewers and editors can be a humbling experience; I had to defend some ideas I had put in the book but gladly accepted suggestions for improvement or clarification. It took about three months, working over the weekends (I have a day job) to write the first edition, Mastering phpMyAdmin for Effective MySQL Management, which was published in April 2004. Since this manual covers the complete interface, I was in fact testing the whole software, finding bugs along the way, which forced me to fix them in order to produce correct screenshots! Needless to say, I was very proud of being the first published author for this company. Meanwhile, an interface redesign was taking place in phpMyAdmin for version 2.6.0; this meant that many screenshots in the book would no longer reflect the upcoming version of the software. The decision was made by Packt to publish a book update. During the summer of 2004, I already knew what the new version would look like so I started preparing this update. The new version of the software was released at the end of September and the book update (bearing the same ISBN as the first edition) somewhere in October! In June 2005 we organized the first phpMyAdmin team meeting in Germany during the LinuxTag event where we demoed our software. I was happy to meet Mr Fatoohi, Damian Carvill and other representatives from Packt who had a booth there too. I found the whole team very dynamic and very much readers-oriented. I know that publishing is a business but they understand that quality is important; they also respect me as an author (especially about schedules). Over the years, translations of the book were published, directly by Packt or via other publishers. I wrote the French version, while two phpMyAdmin developers did the German one. Versions in Czech, Italian and Spanish were also born and they are all proudly displayed in my house near the workstation. Meanwhile, phpMyAdmin’s march was continuing, with an average of 250,000 downloads per month. It should be noted that many users do not need to download it directly because host providers install the software for them, or Linux distributors include it on their DVD, this is why we cannot know exactly the number of users. The development team changed a bit but new features were appearing so I guess Packt Publishing resigned itself about the need to update this title from time to time. This is why I took to my pencil again – rather my keyboard – to produce the October 2006 edition, Mastering phpMyAdmin 2.8 which covered a new setup mechanism. In March 2008, Mastering phpMyAdmin 2.11 was published, followed by Mastering phpMyAdmin 3.1 in March 2009. My family is now accustomed to my new habit of taking a few weeks per year to produce the new update. I would like to express my wholeheartedly gratitude to Packt Publishing for their support into this ongoing project. --Marc Delisle
Read more
  • 0
  • 0
  • 4612

article-image-creating-convincing-images-blender-internal-renderer-part2
Packt
20 Oct 2009
9 min read
Save for later

Creating Convincing Images with Blender Internal Renderer-part2

Packt
20 Oct 2009
9 min read
Textures In your journey as a 3d artist, you might have encountered several (if not all) astounding works of art.  And through close inspection, you’ll notice that we barely see them without textures.  That is because textures are one of the most important aspect of 3d, but still, this doesn’t apply to all.  But adding textures to your characters, props, environment, etc. will greatly add to the aesthetic factor of your image that you wouldn’t believe it would. There are a number of ways to add texture to your objects in 3D such as UV mapping techniques, projections, 2D painting, etc.  All of these depend entirely on what kind of render are you trying to achieve.  But for the sake of this article, we’ll try to achieve some nice looking textures without having to worry about the complex tasks involved with it.  And with this, we’ll be using the ever famous and useful procedural textures to create seamless and continuously looking texture mapped over the surface of our models. More information about Procedural Textures can be found on http://www.blender.org/development/release-logs/blender-233/procedural-textures/. Now let’s add some textures, shall we? Let’s select the character model in our scene then go to the Texture tab on the rightmost part of the Material Buttons window and click Add New to add a new texture. Adding a New Texture After having added a new texture, additional windows appear allowing us to further modify how the currently added texture will affect our material.  Name this first texture as “bump” and the mapping options can be seen below. Bump Texture Mapping Settings   Bump Texture Settings Add another texture below the “bump” texture and call it “stain”.  The settings can be seen below. Stain Texture Mapping Settings   Stain Texture Settings We could have added more overlaying textures, but this will do for now just so we could see how the textures have affected our material so far.  Rendering now will only lead us to the image below. Dirtier And Better :) This time might be a good idea to change our framing and staging so we could look at it at a better perspective.  Changing the camera angle and increasing the ground plane’s scale and some adjustments on the spheres, I achieved something like this: New Camera Angle For an even better interaction from within the scene, we will adjust some material settings to simulate hard and reflective surfaces.  It’s a little unfair to give our main character some good materials while neglecting the other stuff we have.  So let’s just get on, and add some decent materials as replacement to the initial materials that both the spheres have had before. Go on and select the larger sphere and edit the current material we have so it would match that of the settings as seen in the image below. You’ll notice I added a Color Ramp to each of the materials, this is to slightly give the color a color transition as would be seen in the natural world, in addition to the current diffuse it already has. The vital part of the shading process of the Spheres is the reflectivity and mirror options as you can see in the following table:     Ray Mirror Freshnel Green Sphere 0.12 0.76 Blue Sphere 0.21 0.99     Green Sphere Material Settings   Blue Sphere Material Settings Our render would now look like this: Reflections to Simulate Mirror Effect and Smoothness To nearly finalize this part, we now deal with adding a texture to the world and varying the colors that would affect the Occlusion effect. To do so, let’s first change the Horizon and Zenith color of our World and change the Ambient Occlusion diffuse energy to the color we’ve just set by changing from “Plain” to “Sky Color”, as seen below. World Settings Rendering now will lead us to: New World Settings Render Notice the subtle difference between the previous render and the latest one where the slight bluish hue is more distinguishable. And then lastly, since we've already added some decent reflective material over to our spheres, it would be best if we can also see some environment being reflected over, to add to the already existent character as one of the objects being reflected. To do this, we're going to add a texture to our World.  This is one nifty tool in simulating an environment since we don't have to do the hard work in manually creating the objects that are going to be reflected.  Not only does it save us a lot of time but also the ease by which we can alter these environment is already a big advantage that we have at our hands. So to do this, let's go ahead and go to our Shading (F5) and select World Buttons.  Scroll to the far left side and you'll see tabs labeled “Texture and Input” and “Map To”, both of these tabs are essential in setting up our World texture so pay close attention to them. Below is an image that further shows you what we need to set up (sorry for the sudden theme change). World Texture You might have already guessed what we should do next, if not, I'll continue on.  After heading over to the “Texture and Input” and “Map To” tabs, let's first focus on what's active by default, that is, “Texture and Input”.  In this part, we'll only need a few things to get started.  First is to click “Add New” to add a new texture datablock to our blender scene, after which, let's edit the name of our texture and name it “environment”, then change the coordinates from “View” to “AngMap” to use a 360 degree angular coordinate, you'll see why in awhile. Adding a World Texture After applying these initial settings, we'll go ahead and proceed to the actual texturing process, which, as far as the World is concerned is just a very quick process.  I suppose you're still on the same Buttons window that we're on last time.  Click on the Texture button or press F6 on your function keys. Bam! Another set of Windows.  You'll see here that the texture we named “environment” awhile back is now reflected over to one of the texture slots, just like what we previously did with texturing the character we have.  But this time, instead of choosing procedural textures like Clouds, Voronoi, Noise, etc., we'll now be dealing with an image texture, as in our case, an HDRi (High Dynamic Range Image).  Our purpose in using an HDR image is to simulate the wide range of intensity levels (brightness and darkness) that is seen in reality and apply these settings over to our world, thus reflected upon by our objects.  As in our case, we'll be using high dynamic range images as light probes which are oriented 360 degrees and that's the very reason why we chose “AngMap” as our World texture coordinate. More info about HDRi can be seen at http://en.wikipedia.org/wiki/High_dynamic_range_imaging and you can download Light Probe Images over at Paul Debevec's collection at http://www.debevec.org/Probes.  Save your downloaded light probe images somewhere you can easily identify them with.  I couldn't stress enough how file organization can greatly help you in your career.  You could just imagine how frustrating it is to find assets among a thousand you already have, without properly placing them in their right places, this counts for every project you have as well . So to open up our Light Probe Image as texture to our World, click the drop down menu and choose “Image” as your texture type.  This tells Blender to use an image instead of the default procedural textures.  Then head to the far right side to locate the Image tab with a Load button on it.  Let's skip the Map Image tab for now. Image as Texture Type Loading an Image Texture Browse over at your downloaded HDR image (which should have an extension of .hdr) and confirm.  Now that the image is loaded, let's leave the default settings as they are since we wouldn't be using them that much.  You'll see on the far left Preview just how wonderful looking our image is.  But rendering your scene right now would yield to nothing but the same previous render we've had.  So if you're itching to get this image right at our scene (which I am too), go back to your World Settings and head over to the “Map To” tab just beside “Texture and Input” then deselect “Blend” and select “Hori” instead.  Kabam! Now we're all set! World Texture Mapping options And now, the moment we've all been eagerly waiting for, the Render! Yup, go ahead and render and it would (luckily) look like the image below. Render with HDRi Environment Then finally, on the next and last part of this article, we'll look on how we can even further add realism to our scene by simulating camera lenses and further enhancing the tone of the image with Composite Nodes.  
Read more
  • 0
  • 0
  • 4082
Modal Close icon
Modal Close icon