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

How-To Tutorials

7018 Articles
article-image-what-openlayers
Packt
13 May 2013
4 min read
Save for later

What is OpenLayers?

Packt
13 May 2013
4 min read
(For more resources related to this topic, see here.) As Christopher Schmidt, one of the main project developers, wrote on the OpenLayers users mailing list: OpenLayers is not designed to be usable out of the box. It is a library designed to help you to build applications, so it's your job as an OpenLayers user to build the box. Don't be scared! Building the box could be very easy and fun! The only two things you actually need to write your code and see it up and running are a text editor and a common web browser. With these tools you can create your Hello World web map, even without downloading anything and writing no more than a basic HTML template and a dozen line of JavaScript code. Going forward, step-by-step, you will realize that OpenLayers is not only easy to learn but also very powerful. So, whether you want to embed a simple web map in your website or you want to develop an advanced mash-up application by importing spatial data from different sources and in different formats, OpenLayers will probably prove to be a very good choice. The strengths of OpenLayers are many and reside, first of all, in its compliance with the Open Geospatial Consortium ( OGC ) standards, making it capable to work together with all major and most common spatial data servers. This means you can connect your client application to web services spread as WMS, WFS, or GeoRSS, add data from a bunch of raster and vector file formats such as GeoJSON and GML, and organize them in layers to create your original web mapping applications. From what has been said until now, it is clear that OpenLayers is incredibly flexible in reading spatial data, but another very important characteristic is that it is also very effective in helping you in the process of optimizing the performances of your web maps by easily defining the strategies with which spatial data are requested and (for vectors) imported on the client side. FastMap and OpenLayers make it possible to obtain them! As we already said at the beginning, web maps created with OpenLayers are interactive, so users can (and want to) do more than simply looking at your creation. To build this interactivity, OpenLayers provides you with a variety of controls that you can make available to your users. Tools to pan, zoom, or query the map give users the possibility to actually explore the content of the map and the spatial data displayed on it. We could say that controls bring maps to life and you will learn how to take advantage from them in a few easy steps. Fast loading and interactivity are important, but in many cases a crucial aspect in the process of developing a web map is to make it instantly readable. Isn't it useful to build web maps if the users they are dedicated to need to spend too much time before understanding what they are looking at? Fortunately, OpenLayers comes with a wide range of possibilities to styling features in vector layers. You can choose between different vector features, rendering strategies, and customize every aspect of their graphics to make your maps expressive, actually "talking" and—why not?—cool! Finally, as you probably remember, OpenLayers is pure JavaScript, and JavaScript is also the language of a lot of fantastic Rich Internet Application ( RIA) frameworks. Mixing OpenLayers and one of these frameworks opens a wide range of possibilities to obtain very advanced and attractive web mapping applications Resources for Article : Further resources on this subject: Getting Started with OpenLayers [Article] OpenLayers: Overview of Vector Layer [Article] Getting Started with OpenStreetMap [Article]
Read more
  • 0
  • 0
  • 3511

article-image-working-home-page-components-and-custom-links
Packt
10 May 2013
6 min read
Save for later

Working with Home Page Components and Custom Links

Packt
10 May 2013
6 min read
(For more resources related to this topic, see here.) Creating a Personal Setup link using the standard Custom Links on the sidebar All users need to change their personal settings, from time to time, in the Salesforce CRM application. They may, for example, wish to edit their user information, change their password, or you may need them to grant login access to administrators, plus many other reasons. Accessing the Personal Setup area is done by users clicking on their name, looking for the Setup link in the drop-down list, clicking on the Setup link, and then finally clicking on the Personal Setup link in the sidebar. All this takes time and can often be a challenge for less-experienced users of the application. By providing a direct shortcut link in the sidebar, all users will be able to access their Personal Setup area with a single click, and save their time and efforts. How to do it... Carry out the following steps to create a Personal Setup link in the sidebar: Navigate to the home page components' setup page by going to Your Name | Setup | Customize | Home | Home Page Components. Locate the Custom Links row within the Standard Components section. Click on Edit. Within the Custom Links page you can enter a maximum of 15 links. Enter Personal Setup in the 1. Bookmark field. Enter /ui/setup/Setup?setupid=PersonalSetup in the corresponding URL field, as shown in the following screenshot: Click on Save. We now need to add the standard Custom Links component to a home page layout (if it has not been already added). Navigate to the home page components setup page by going to Your Name | Setup | Customize | Home | Home Page Layouts. Determine which home page layout to place the component on and click on Edit. Here we are editing the home page layout named DE Default, as shown in the following screenshot: We will be presented with the Step 1. Select the components to show page. Check the Custom Links checkbox in the Select Narrow Components to Show section, as shown in the following screenshot: Click on Next. Move Custom Links to the top position in the Narrow (Left) Column using the Arrange the component on your home page section, as shown in the following screenshot: Click on Save. How it works... The link appears in the sidebar within the standard Custom Links section, as shown in the following screenshot: When the link is clicked, the user is immediately presented with their Personal Setup page. There's more... Clicking on the link displays the Personal Setup page in the same window and is useful when there is no requirement for the link to open up in a new browser window. The following screenshot shows the result of clicking on the Personal Setup Custom Link: See also The Using Custom Links to open Training in a new window from the sidebar recipe in this article. Using Custom Links to open Training in a new window from the sidebar In the Salesforce CRM application, there are various options for help and training. Accessing the training area is done by the users by clicking on the Help link at the top of the page (which then opens in a new browser window). Users then need to look for the Training tab within the new page and then click on the tab. All this takes a little time and can often be a challenge for less-experienced users of the application. By providing a direct shortcut link in the sidebar, all users will be able to open Training automatically in a new window with a single click, thus saving time and effort. How to do it... Carry out the following steps to create a link in the sidebar to open Training in a new window: Navigate to the Custom Links home page by going to Your Name | Setup | Customize | Home | Custom Links. Click on New. Enter the label of the Custom Link in the Label field. Here, type the text Training. Accept the default name of the Custom Link in the Name field, Training. Leave the Protected Component checkbox unchecked. The Protected Component option is used by developers to mark the Custom Link as protected in managed packages. This then allows the developer to delete the link in any future releases of the managed package without worrying about causing package installations to fail. Enter the following description in the Description field: This a link to Salesforce Training. Choose the Display in new window option from the Behavior picklist. Choose the URL option from the Content Source picklist. Enter /help/doc/user_ed.jsp?loc=training into the source section as shown in the following screenshot: Ensure the selection Unicode (UTF-8) is set in the Link Encoding picklist. Click on Save. We now need to create a custom home page component to house this custom link. The alert displayed in the following screenshot reminds us of that: Click on OK. Now navigate to the home page components setup page by going to Your Name | Setup | Customize | Home | Home Page Components. Click on New. Click on Next (on the Understanding Custom Components splash screen, if shown). The Next button is found on the Understanding Custom Components splash screen (this page is only shown if the Don't show this page again checkbox has not previously been checked) as in the following screenshot: Here, we will be presented with the Step 1. New Custom Components page. Enter the name of the Custom Component in the Name field. Enter the text Custom Links (in New Window). Select the Links option from the Type options list as shown in the following screenshot: Click on Next. Now add the Training link to the list of Custom Links to show as shown in the following screenshot: Click on Save We have created our Training link's custom home page component but we are not finished yet. We now need to add the custom home page component to a home page layout. Navigate to the home page components setup page by going to Your Name | Setup | Customize | Home | Home Page Layouts. Determine which home page layout to place the component on and click on Edit. Here we are editing the home page layout named DE Default, as shown in the following screenshot: We will be presented with the Step 1. Select the components to show page. Check the Custom Links (in New Window) checkbox in the Select Narrow Components to Show section as shown in the following screenshot: Click on Next. Move Custom Links (in New Window) to the top position in Narrow (Left) Column using the Arrange the component on your home page. section, as shown in the following screenshot: Click on Save. How it works... Clicking on the Training link opens a new smaller browser window with the Salesforce Training page directly accessed and loaded alongside the main Salesforce CRM application windows. Users can switch back to the main application when they want and simply close the Training window when they are finished viewing it. You can see what this looks like in the following screenshot: See also The Creating a Personal Setup link using the standard Custom Links on the sidebar recipe in this article.
Read more
  • 0
  • 0
  • 4320

article-image-tips-and-tricks
Packt
09 May 2013
7 min read
Save for later

Tips and Tricks

Packt
09 May 2013
7 min read
(For more resources related to this topic, see here.) Adding more template files to your theme Let's say our site needed to display posts from a specific category differently from the rest of the site, or we needed the home page to work differently, or maybe we wanted to have more control over how search results or 404 pages were displayed. With template files, we can do all that. A search.php file for search results WordPress handles search results pretty well already. Let's see what's displayed in our theme if we try to search for example post (Note that we've now added a Search widgetto the right-hand side footer widget area to make this possible): As you can see, it' s using our index.php template file, so the heading reads This Month:.We'd rather make it more obvious that these are search results. Now let's see what happens if we search for something that can't be found: Again, the heading isn't great. Our theme gives the user a message telling them what's happened (which is coded into index.php as we'll see), but we could beef that up a bit,for example by adding a list of the most recent posts. Time for action – creating a search.php template file Let's create our search.php file and add some code to get it working in the way we'dlike it to: In your theme folder, make a copy of index.php and call it search.php. Find the following code near the top of the file: <h2 class="thisMonth embossed" style="color:#fff;">This Month:</h2> Edit the contents of the h2 element so the line of code now reads: <h2 class="thisMonth embossed" style="color:#fff;">Searchresults:</h2> Find the loop. This will begin with: <?php if (have_posts()) :?><?php while (have_posts()) : the_post();?> The first section of the loop displays any posts found by the search, leave this as itis. The second section of the loop specifies what happens if no search results are found. It's in the following lines of code: <?php else : ?><h2 class="center">Not Found</h2><p class="center">Sorry, but you are looking for somethingthat isn't here.</p><?php get_search_form(); ?><?php endif; ?> Underneath the line that reads <?php get_search_form(); ?> and before <?php endif; ?>, add the following lines of code: <?php endif; ?>, add the following lines of code:<h3>Latest articles:</h3><?php $query = new WP_Query( array ( 'post_type' => 'post', 'post_count' => '5' ) );while ( $query->have_posts() ) : $query->the_post(); ?><ul><li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li></ul><?php endwhile; ?> Save your search.php file and try searching for something which isn't included in the site. What just happened? We created a new template file called search.php, which will be used to display theresults of a site search. We then edited the heading to make it clearer, and added somecode to display the latest posts if the search had no results. We actually did something pretty advanced, we added a second loop inside our original loop. Let's have a look at the code we added after the search form: The function $query = new WP_Query() runs a new query on the database, based on the WordPress WP_Query function, which is the function you should use when running a loop inside the main loop. We gave WP_Query the following parameters: 'post_type' => 'post' – this ensures that the query will only look for posts, not for any other kind of content. 'post_count' => '5' – this tells WordPress how many posts to show. Five, in this case. We then output the title of each post with the php the_title() tag whichwe've already used higher up in the loop to display post titles. We wrapped this in a link inside a list item. The link uses the_permalink() to link to the blog post whose title is displayed. This is very similar to the main loop. Finally, we added endwhile() to stop this loop. This doesn't replace theendwhile() at the end of our main loop, which is higher up in the file. For more on WP_Query and how to use it to create multiple loops, see http://codex.wordpress.org/Class_Reference/ WP_Query. Let's have a look at what our users will see when they do a search now. First,a successful search: Next, an unsuccessful search: So that's how we set up a template file for search results. Our search page is only displayingtwo posts because that's all we have on our site. If there were more than five, it would justdisplay the five most recent. Now let's set one up to display some pages differently. Creating a custom page template In many themes, all pages will need the same basic layout and content, with the same sidebarsand footer and the same styling. But sometimes you may need some pages to look different. For example, you might want to use different sidebars in different pages, or you might wanta different layout. Here we'll look at the second of those two options. Time for action – creating a custom page template Imagine that you have some pages containing a lot of content which you want to displayacross the full width of the page, without the sidebar getting in the way. The way to handlethis is to create a page template which doesn't include the sidebar, and then select thatpage template when you're creating or editing those pages. Let's try it out. In the same folder as your other theme files, make a copy of your page.php file and call it page-no-sidebar.php. At the very top of the file, above the line reading <?php get_header(); ?>,insert the following code: <?php/*Template Name: Full width page without sidebar*/?> Find the following line of code: <div class="content left two-thirds"> Edit it so it reads: <div class="content left full"> Now find the line that reads <?php get_sidebar(); ?> and delete it. Save your file. What just happened? We created a new template file called page-no-sidebar.php, and edited it to displaycontent differently from our default page template: We edited the classes for our .content div, using the object-oriented approach to styling used by the layout-core.css file. This will apply styling for the .fullclass to this div, so that it displays a full width instead of two-thirds of its containing element. We removed the line calling the get_sidebar include, so that it won't be displayed on any pages using this template. The lines we added at the top are essential for WordPress to pick up on our page templateand make it available in the WordPress admin. Page editors will see a drop-down list of pagetemplates available, and the name we defined in the template is what they'll see in that list,as shown in the following screenshot: As you can see, in the Page Attributes box to the right-hand side, a new select box has appeared called Template. Our new page template is listed in that select box, along withDefault Template, which is page.php. Now we can try it out by assigning this template to a page and seeing how it looks.
Read more
  • 0
  • 0
  • 9830

article-image-cloud-enabling-your-apps
Packt
08 May 2013
7 min read
Save for later

Cloud-enabling Your Apps

Packt
08 May 2013
7 min read
(For more resources related to this topic, see here.) Which cloud services can you use with Titanium? Here is a comparison of the services offered by three cloud-based providers who have been proven to work with Titanium: Appcelerator Cloud Services Parse StackMob Customizable storage Yes Yes Yes Push notifications Yes Yes Yes E-mail Yes No No Photos Yes Yes Yes Link with Facebook/Twitter account Yes Yes Yes User accounts Yes Yes Yes The services offered by these three leading contenders are very similar. The main difference is the cost. Which is the best one for you? It depends on your requirements; you will have to do the cost/benefit analysis to work out the best solution for you. Do you need more functionality than this? No problem, look around for other PaaS providers. The PaaS service offered by RedHat has been proven to integrate with Titanium and offers far more flexibility. There is an example of a Titanium app developed with RedHat Openshift at https://openshift.redhat.com/community/blogs/developing-mobile-appsfor-the-cloud-with-titanium-studio-and-the-openshift-paas It doesn't stop there; new providers are coming along almost every month with new and grand ideas for web and mobile integration. My advice would be to take the long view. Draw up a list of what you require initially for your app and what you realistically want in the next year. Check this list against the cloud providers. Can they satisfy all your needs at a workable cost? They should do; they should be flexible enough to cover your plans. You should not need to split your solution between providers. Clouds are everywhere Cloud-based services offer more than just storage. Appcelerator Cloud Services Appcelerator Cloud Services ( ACS) is well integrated into Titanium. The API includes commands for controlling ACS cloud objects. In the first example in this article we are going to add commentary functionality to the simple forex app. Forex commentary is an ideal example of the benefits of cloud-based storage where your data is available across all devices. First, let's cover some foreground to the requirements. First, let's cover some foreground to the requirements. The currency markets are open 24 hours a day, 5 days a week and trading opportunities can present themselves at any point. You will not be in front of your computer all of the time so you will need to be able to access and add commentary when you are on your phone or at home on your PC. This is where the power of the cloud really starts to hit home. We already know that you can create apps for a variety of devices using Appcelerator. This is good; we can access our app from most phones, but now using the cloud we can also access our commentary from anywhere. So, comments written on the train about the EURUSD rate can be seen later when at home looking at the PC. When we are creating forex commentary, we will store the following: The currency pair (that is EURUSD) ‹ The rate (the current exchange rate) The commentary (what we think about the exchange rate) We will also store the date and time of the commentary. This is done automatically by ACS. All objects include the date they were created. ACS allows you to store key value pairs (which is the same as Ti.App.Properties), that is AllowUserToSendEmails: True, or custom objects. We have several attributes to our commentary post so a key value pair will not suffice. Instead we will be using a custom object. We are going to add a screen that will be called when a user selects a currency. From this screen a user can enter commentary on the currency. Time for action – creating ACS custom objects Perform the following steps to create ACS custom objects: Enable ACS in your existing app. Go to tiapp.xml and click on the Enable... button on the Cloud Services section. Your project will gain a new Ti.Cloud module and the ACS authentication keys will be shown: Go to the cloud website, https://my.appcelerator.com/apps, find your app, and select Manage ACS. Select Development from the selection buttons at the top. You need to define a user so your app can log in to ACS. From the App Management tab select Users from the list on the right. If you have not already created a suitable user, do it now. We will split the functionality in this article over two files. The first file will be called forexCommentary.js and will contain the cloud functionality, and the second file called forexCommentaryView.js will contain the layout code. Create the two new files. Before we can do anything with ACS, we need to log in. Create an init function in forexCommentary.js which will log in the forex user created previously: function init(_args) { if (!Cloud.sessionId) { Cloud.Users.login({ login: 'forex', password: 'forex' }, function (e) { if (e.success) { _args.success({user : e.users[0]}); } else { _args.error({error: e.error}); } }); } This is not a secure login, it's not important for this example. If you need greater security, use the Ti.Cloud.Users. secureLogin functionality. Create another function to create a new commentary object on ACS. The function will accept a parameter containing the attribute's pair, rate, and commentary and create a new custom object from these. The first highlighted section shows how easy it is to define a custom object. The second highlighted section shows the custom object being passed to the success callback when the storage request completes: function addCommentary(_args) { // create a new currency commentary Cloud.Objects.create({ classname: className, fields: { pair: _args.pair, rate: _args.rate, comment: _args.commentary } }, function (e) { if (e.success) { _args.success(e.forexCommentary[0]); } else { _args.error({error: e.error}); } }); } Now to the layout. This will be a simple form with a text area where the commentary can be added. The exchange rate and currency pair will be provided from the app's front screen. Create a TextArea object and add it to the window. Note keyboardType of Ti.UI.KEYBOARD_ASCII which will force a full ASCII layout keyboard to be displayed and returnKeyType of Ti.UI.RETURNKEY_DONE which will add a done key used in the next step: var commentary = Ti.UI.createTextArea({ borderWidth:2, borderColour:'blue', borderRadius:5, keyboardType: Ti.UI.KEYBOARD_ASCII, returnKeyType: Ti.UI.RETURNKEY_DONE, textAlign: 'left', hintText: 'Enter your thoughts on '+thePair, width: '90%', height : 150 }); mainVw.add(commentary); Now add an event listener which will listen for the done key being pressed and when triggered will call the function to store the commentary with ACS: commentary.addEventListener('return', function(e) {forex.addCommentary({ pair: thePair, rate: theRate, commentary: e.value}) }); Finally add the call to log in the ACS user when the window is first opened: var forex = require('forexCommentary'); forex.init(); Run the app and enter some commentary. What just happened? You created functions to send a custom defined object to the server. Commentary entered on the phone is almost immediately available for viewing on the Appcelerator console (https://my.appcelerator.com/apps) and therefore available to be viewed by all other devices and formats. Uploading pictures Suppose you want to upload a picture, or a screenshot? This next example will show how easy it is to upload a picture to ACS.
Read more
  • 0
  • 0
  • 3695

article-image-overview-complex-event-processing
Packt
07 May 2013
11 min read
Save for later

An Overview of Complex Event Processing

Packt
07 May 2013
11 min read
(For more resources related to this topic, see here.) What is event processing? In the world around us, every second of every minute of every hour, the human brain is bombarded with a limitless number of things that happen either at the same time or sequentially, or in a totally and seemingly erratic way that may not make sense immediately but as more of these things happen, we can start to understand their relevance and importance. For example, we hear cheering in the distance, we see balloons flying in the air, music starts to play, police cars and trucks appear pulling brightly covered trailers with puppets and people waving on them, followed by ambulances, and today's date is July 4th. Individually, these events could mean anything, but together? It's probably an Independence Day Carnival Parade! Our brain can easily determine this fact in the blink of an eye" and while not overly simple to define in computing terms, we could describe a "Parade Event Pattern" as follows: One (or more) police cars + followed/preceded by, or adjacent to + one (or more) carnival trucks + followed/preceded by, or adjacent to + one (or more waving people) + followed/preceded by, or adjacent to + one (or more emergency vehicles) + where music can be heard + and today's date is 4th July Your brain is not restricted to sending information and just waiting until there is a response, or forced into following a series of fixed steps to get something done. As with this example, it is able to take the events happening now, their relevance to additional external factors such as today's anniversary date and understand a "parade" event pattern. So as you learn more about Complex Event Processing, we focus on how this technology can take continuously flowing, never-ending information, from a potentially unlimited number of different places, and immediately understand how it relates to things happening right now and in the very near future, commonly known as Real-Time Situation Awareness. Relating this to a business in computing terms The problem now in the world of computers is the proliferation of data. Information arrives from many different systems, in vast quantities, at different times, at different speeds, some of importance now to certain other systems, people or processes, and some stored for later recovery and determination. Why the proliferation now? There are many issues involved, but here are just a few major ones: The cost of computer power and sophisticated environmental sensor devices has become less expensive Networking capacities increase and become more intelligent The many different functional computing silos (finance systems, manufacturing systems, sales systems, and so on) are broken down, rewritten, enabling processes that can span more and more business demands New computer solution demands expand beyond the enterprise to include partners, customers so more and more data sources and other inputs are brought online Computing technology architectures such as Service Orientated Architecture (SOA) becomes increasingly successful, resulting in an ever more elaborate ecosystem of re-usable services A Big Data explosion, a term now used widely for information that arrives in high volumes, with extreme velocity, and in a wide variety of mostly unstructured formats emanating from social media sites, cell phones, and many other sources A growing demand from businesses that expect their Information Technology (IT) teams to respond to market situations much more effectively in real time As we evolve and the complexity of these systems "pour" more and more huge volumes of information at computer applications, we are reaching a "tipping point" where traditional point-to-point or request-reply-based solutions of the world break down and become unmaintainable and not extendable. A company business can be influenced instantaneously from things (events) that can happen, not only in the "cozy" understandable world within its own environment but also from activities (events) from beyond, such as from "the Internet of things"—realtime sensor device that can measure and report on a multitude of situations, including "the impending danger from a sudden rise in temperature in a food storage facility" or "the global positioning system location of a shipping container which is having an unauthorized opening with movement detection sensed from within". Immediate impact to a company's business can also come appear "out of nowhere" emanating from a change in global business conditions indicated from the everexpanding social media outlets, for example, Twitter, instant messaging, and so on. Millions of people at the same time can all comment on the poor condition of a new product, highlighting an immediate need to change a product design. This will inevitably affect profits and will probably significantly affect the value of the business. So companies are now inevitably being manipulated by a wide range of both understood and misunderstood events. In the past, probably going back over 15 years ago, business applications have had to conform to the methodologies, structure, and interfaces from the then available computing technologies (such as databases) where information must be inserted and statically placed. Only after this can users then analyze and respond. Traditional JEE Application Servers were generally implemented, expecting a client application to send an initial request and will then only process that request through, in most cases a significant amount of logic code, before it can respond back to the client. While these technologies enable, and will continue to provide benefit in more batch-orientated, less real-time approaches, newer lower latency and faster in-memory middleware products are now available. Event-Driven (Architecture) based systems are intrinsically smarter, or better "equipped" to handle these types of situations, processing an entire business infrastructure as events that can be immediately interpreted and handled, spanning across the many departmental "silos" such as finance, manufacturing, and sales. These types of systems are also context aware and execute when they detect changes in the environment or business world, rather than occurring on a predefined (nightly) schedule or requiring someone to initiate an execution. As the problems associated with Big Data grow substantially over the coming years in terms of the capture, management, and the ability to process the information within a tolerable amount of time, Event-Driven technologies (specifically Complex Event Processing) can provide Fast Data capabilities to apply a greater level of "intelligence" and decisioning to the originating data streams much closer to the "point of occurrence". So the benefits of an Event-Driven technology approach is to turn that proliferation of data into real-time knowledge by firstly representing events (things that happen from anywhere) in standard ways, providing an ability to factor out events, route events, filter events, aggregate events, and correlate events intelligently, so that in most cases fragmented events can be evolved into holistic, solid, understandable business events, enabling the business to better view, control, and adapt to situations relatively instantaneously. Use case: A solution for customer problems So how are Complex Event Processing Platforms used now to solve business problems? Certainly over the past few years, this technology is being used across most, if not all, of the different types of industries. The financial services capital markets companies are using this technology for real-time algorithmic trading and real-time risk management types of solutions. As the stock markets stream their endless financial instrument data with values which can instantly fluctuate, there is an ever growing need to effectively handle this huge volume of information, understand its impact and potential risk, and then react as quickly as possible. The better the capability to evaluate and predict the consequences of the information, and the quicker the ability to respond to the results of this analysis, the more successful the business and the more money that can be made with less exposure to business risks and threats. This type of real-time trading information can be usually visualized using heat maps and scatter charts. In the Electricity industry, customers are using the Complex Event Processing (CEP) platform for many new types of applications, which include Smart Meter, Smart Grid, and outage detection monitoring solutions. Sophisticated Demand Response (DR) solutions bring together system operators and the power generation companies, who contract with energy management and monitoring companies to provide energy usage load reduction services on demand. These technology companies that are using CEP-based applications contract with commercial and industrial businesses that are large consumers of energy, whom agree to curtail energy usage on demand. Streaming event devices are installed at client locations to measure energy usage and, in some cases, proactively control the load using continuous energy demand and usage data at minute or, even second, intervals. The generated profit revenue received from system operators is then passed back to the clients, relative to the number of associated load reduction dispatches. Handling real-time events has a long history in the telecommunications industry, such as those generated by the various devices on the network, events from mobile phones, or perhaps streaming Call Detail Record (CDR) events indicating the time of calls made and whether some of these calls failed. Complex Event Processing platforms provide the technology for many new applications and solutions in this domain. As in other industries, Event-Driven platforms have a broad base of possible implementations. Some businesses have created powerful network management and monitoring solutions, which can detect hardware failure-related events continuing over certain time periods, or situations where equipment has not been issuing events for some time and in these circumstances alert messages are distributed and escalated. In the context of an enterprise-level mobile telecommunication IT infrastructure, there are many different applications coming from many different suppliers. When the overall performance is not immediately meeting expectations, it's not easy to identify which component is the offending issue in the supply chain. Therefore these next-generation management and monitoring applications (based on Complex Event Processing) provide the capabilities to show the complete, holistic "picture", providing full visibility to the situation of a business through flexibility and fully integrated features, enabling agility for the infrastructure to react quickly to changing scenarios, and providing full operability enabled by a solution designed to meet business needs. A very powerful capability of Complex Event Processing platforms which is being leveraged in the Transportation, Telecommunications, and Public Sector domain is real-time integrated spatial analysis. A business can use this technology in applications where there is the need to monitor the movements of its assets and resources. Using, for example, GPS (global positioning systems) the movement patterns of someone, or something can be tracked in real time as it passes through boundary points (such as security checkpoints in an airport) to identify its route and, to some extent, predict where this person or object may subsequently move next. Also, this capability can be used to analyze a current position and its relationship to geofenced areas. A geofenced area being the definition of a geographical shape (polygon) defined or declared by a series of spatial coordinates. When a resource gets near, inside, or enters and exits the geofenced area, various actions can be immediately performed, such as a warning message of an imminent exposure to a dangerous natural disaster, or offering a big discount on a second coffee at the person's current location or soon to be, position, based on his or her current movement pattern. First Responder emergency services solutions can use integrated spatial technologies to not only monitor a fire or hundreds of simultaneous fires, but also dynamically track the movement on the fire, affected by weather conditions (wind) or igniting hazardous materials. These types of systems can evaluate immediately the relevance, importance, and applicability of all of the related assets (fire engines, police vehicles, and so on) close to these areas. For example, if a fireman does not move in certain number of seconds when close to a fire, this could indicate a serious life threatening situation. There are many other types of business solution implementations using Complex Event Processing platforms that range from online retail monitoring systems, real-time data center infrastructure management, fleet vehicle transportation monitoring, traffic flow monitoring with variable toll charging and speed control, oil fields and rig monitoring/automation, and a host of real-time sensing device opportunities, where these devices can monitor the environment inside shipping containers, or air pollution situations. The scope and different type of applications that can now benefit from using Complex Event Processing technologies are evolving just as quickly as the world is changing, with a growi ng need to predict and pre-empt and in, some cases, prevent situations from even happening.
Read more
  • 0
  • 0
  • 3438

Packt
07 May 2013
6 min read
Save for later

Using Debug Perspective – setting breakpoints

Packt
07 May 2013
6 min read
(For more resources related to this topic, see here.) In this article we will learn why breakpoints are important, how to set them up, and how to navigate through the code using the Step Into, Step Over, and Step Return breakpoint manipulation options. Let's practice setting up a breakpoint on our sample program. How to do it... I am sure you are aware that in Java, the first method that is executed is the main() method. Our Employee class has its own main() method, so let's set up a breakpoint in it. If you are on Windows and If your project has more than one class, and the main() method is located in a different class from the one you are about to debug, go to the icon and select Debug | Debug Configurations.... Select the class you are about to debug in the left menu and set the Main class option to the class that has the main() method. To set up a breakpoint Go to the main() method of the Employee class. Find andrew.setNumber(123) (on line 110). Right-click on the line number (if you don't see the line number, click on the left margin of the Employee tab and choose Show Line Numbers as shown in the following screenshot). Got to line 110, right-click on the margin again, and click on Toggle Breakpoint. If your breakpoint is successfully set up, you will see the icon right near the line number of the method you wanted to set the breakpoint to. (In our case right near line number 110.) Another way to set a breakpoint is to double-click on the gray field near the line number. To unset the breakpoint, just double-click on it again. Now let's run the debugger by clicking on the icon. If you are asked to switch to Debug Perspective, click Yes. After running the debugger you should see that your program has highlighted the line with the breakpoint, as shown in the following screenshot: This means that the program has stopped executing before line 110 and is waiting for your actions. Before we proceed with exploring how Step Into/ Step Over works, let's take a look at the Variables view. Right now there are two lines: args that represents arguments passed to the main() method and andrew. Expand andrew and you will see the current state of all the class variables as shown in the following screenshot: We will keep on watching this view as it will change when we go through our class. Let's learn how to navigate through the debugger. We navigate with the help of the Step Into/Step Over buttons. Let's see how it works. At this point we are standing at line 110 and there are four options that we can choose. We can Step Into, Step Over, Go to Next breakpoint, or Go Back. Step Into means that we go inside the method and explore its functionality. Let's try it right now. In the top menu there are two buttons: . The first button is responsible for Step Into (F5) and the second one for Step Over (F6). Click on the Step Into (F5) icon. Now you are taken to the setNumber() method. If you take a look at the Variables view, there are two lines now: this, which relates to the class variables, and _number, which is a variable of the local method. Your position is at the if statement evaluating if the number is between certain limits (at line 46). Click on the Step Into (F5) icon again. As there is no method to Step Into, the pointer moves one line down; now it's on number = _number. This line assigns local variables to the class variable. Click on the Step Into (F5) icon again. Right now the pointer should be at line 49. Now let's look at the Variables view again. If you expand this, you will see that the number is highlighted in yellow. This is because the variables have changed their values. See the following screenshot:   This highlighting is very useful, as it allows you to see what variables have changed their values right after it has happened. Before we use Step Into one last time in this exercise, let's also take a look at the Debug view. Sometimes, when the project is big, it is very hard to determine what is the hierarchical structure of the classes and methods, which you are in at the moment. In our case the Debug view shows that we are in the setNumber(int) method on line 49, and if we look below this line, we see that we came here from the main() method on line 110. See the following screenshot: If at any time you want to return back to the calling method (in our case it is the main() method) use Step Return (F7) . Click on the Step Into (F5) icon. As we have reached the end of the setNumber() method, Step Into makes it return back to the main() method, and the pointer points to the next line (line 111 in our case). Also, the Debug view no longer shows setNumber() in its hierarchy. Now, let's consider the situation when you don't want to step into the method but you want to go directly to the next method. In this situation we use Step Over (F6). Note that when you use Step Over, the method is still called but the debugger does not walk you through it. Let's step over the setAge() method. Clicking on Step Over (F6), you might see that you were not prompted inside the setAge() method, but directly to line 112. Take a look at the Variables view. You will see that age is set to 28 (that is what the setAge() method does), despite you not walking through this method. The last two controls that I want to mention in this recipe are Resume (F8) , which allows you to continue running your application until it next faces the breakpoint or the end of the program, and Terminate (Ctrl + F2), which stops the debugging process. Summary This article helped you to learn what a breakpoint is. You also learned how to set breakpoints and how to navigate through the debugger using Step Into, Step Over, and Step Return breakpoint manipulation options. Resources for Article : Further resources on this subject: Android Application Testing: Getting Started [Article] JBoss RichFaces 3.3 Supplemental Installation [Article] JBoss AS plug-in and the Eclipse Web Tools Platform [Article]
Read more
  • 0
  • 0
  • 6347
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-validating-and-using-model-data
Packt
07 May 2013
14 min read
Save for later

Validating and Using the Model Data

Packt
07 May 2013
14 min read
(For more resources related to this topic, see here.) Declarative validation It's easy to set up declarative validation for an entity object to validate the data that is passed through the metadata file. Declarative validation is the validation added for an attribute or an entity object to fulfill a particular business validation. It is called declarative validation because we don't write any code to achieve the validation as all the business validations are achieved declaratively. The entity object holds the business rules that are defined to fulfill specific business needs such as a range check for an attribute value or to check if the attribute value provided by the user is a valid value from the list defined. The rules are incorporated to maintain a standard way to validate the data. Knowing the lifecycle of an entity object It is important to know the lifecycle of an entity object before knowing the validation that is applied to an entity object. The following diagram depicts the lifecycle of an entity: When a new row is created using an entity object, the status of the entity is set to NEW. When an entity is initialized with some values, the status is changed from NEW to INITIALIZED. At this time, the entity is marked invalid or dirty; this means that the state of the entity is changed from the value that was previously checked with the database value. The status of an entity is changed to UNMODIFIED, and the entity is marked valid after applying validation rules and committing to the database. When the value of an unmodified entity is changed, the status is changed to MODIFIED and the entity is marked dirty again. The modified entity again goes to an UNMODIFIED state when it is saved to the database. When an entity is removed from the database, the status is changed to DELETED. When the value is committed, the status changes to DEAD. Types of validation Validation rules are applied to an entity to make sure that only valid values are committed to the database and to prevent any invalid data from getting saved to the database. In ADF, we use validation rules for the entity object to make sure the row is valid all the time. There are three types of validation rules that can be set for the entity objects; they are as follows: Entity-level validation Attribute-level validation Transaction-level validation Entity-level validation As we know, an entity represents a row in the database table. Entity-level validation is the business rule that is added to the database row. For example, the validation rule that has to be applied to a row is termed as entity-level validation. There are two unique declarative validators that will be available only for entity-level validation—Collection and UniqueKey. The following diagram explains that entity-level validations are applied on a single row in the EMP table. The validated row is highlighted in bold. Attribute-level validation Attribute-level validations are applied to attributes. Business logic mostly involves specific validations to compare different attribute values or to restrict the attributes to a specific range. These kinds of validations are done in attribute-level validation. Some of the declarative validators available in ADF are Compare, Length, and Range. The Precision and Mandatory attribute validations are added, by default, to the attributes from the column definition in the underlying database table. We can only set the display message for the validation. The following diagram explains that the validation is happening on the attributes in the second row: There can be any number of validations defined on a single attribute or on multiple attributes in an entity. In the diagram, Empno has a validation that is different from the validation defined for Ename. Validation for the Job attribute is different from that for the Sal attribute. Similarly, we can define validations for attributes in the entity object. Transaction-level validation Transaction-level validations are done after all entity-level validations are completed. If you want to add any kind of validation at the end of the process, you can defer the validation to the transaction level to ensure that the validation is performed only once. Built-in declarative validators ADF Business Components includes some built-in validators to support and apply validations for entity objects. The following screenshot explains how a declarative validation will show up in the Overview tab: The Business Rules section for the EmpEO.xml file will list all the validations for the EmpEO entity. In the previous screenshot, we will see that the there are no entity-level validators defined and some of the attribute-level validations are listed in the Attributes folder. Collection validator A Collection validator is available only for entity-level validation. To perform operations such as average, min, max, count, and sum for the collection of rows, we use the collection validator. Collection validators are compared to the GROUP BY operation in an SQL query with a validation. The aggregate functions, such as count, sum, min, and max are added to validate the entity row. The validator is operated against the literal value, expression, query result, and so on. You must have the association accessor to add a collection validation. Time for action – adding a collection validator for the DeptEO file Now, we will add a Collection validator to DeptEO.xml for adding a count validation rule. Imagine a business rule that says that the number of employees added to department number 10 should be more than five. In this case, you will have a count operation for the employees added to department number 10 and show a message if the count is less than 5 for a particular department. We will break this action into the following three parts: Adding a declarative validation: In this case, the number of employees added to the department should be greater than five Specifying the execution rule: In our case, the execution of this validation should be fired only for department number 10 Displaying the error message: We have to show an error message to the user stating that the number of employees added to the department is less than five Adding the validation Following are the steps to add the validation: Go to the Business Rules section of DeptEO.xml. You will find the Business Rules section in the Overview tab. Select Entity Validators and click on the + button. You may right-click on the Entity Validators folder and then select New Validator to add a validator. Select Collection as Rule Type and move on to the Rule Definition tab. In this section, select Count for the Operation field; Accessor is the association accessor that gets added through a composition association relationship. Only the composition association accessor will be listed in the Accessor drop-down menu. Select the accessor for EmpEO listed in the dropdown, with Empno as the value for Attribute. In order to create a composition association accessor, you will have to create an association between DeptEO.xml and EmpEO.xml based on the Deptno attribute with cardinality of 1 to *. The Composition Association option has to be selected to enable a composition relationship between the two entities. The value of the Operator option should be selected as Greater Than. Compare with will be a literal value, which is 5 that can be entered in the Enter Literal Value section below. Specifying the execution rule Following are the steps to specify the execution: Now to set the execution rule, we will move to the Validation Execution tab. In the Conditional Execution section, add Deptno = '10' as the value for Conditional Execution Expression. In the Triggering Attribute section, select the Execute only if one of the Selected Attributes has been changed checkbox. Move the Empno attribute to the Selected Attributes list. This will make sure that the validation is fired only if the Empno attribute is changed: Displaying the error message Following are the steps to display the error message: Go to the Failure Handling section and select the Error option for Validation Failure Severity. In the Failure Message section, enter the following text: Please enter more than 5 Employees You can add the message stored in a resource bundle to Failure Message by clicking on the magnifying glass icon. What just happened? We have added a collection validation for our EmpEO.xml object. Every time a new employee is added to the department, the validation rule fires as we have selected Empno as our triggering attribute. The rule is also validated against the condition that we have provided to check if the department number is 10. If the department number is 10, the count for that department is calculated. When the user is ready to commit the data to the database, the rule is validated to check if the count is greater than 5. If the number of employees added is less than 5, the error message is displayed to the user. When we add a collection validator, the EmpEO.xml file gets updated with appropriate entries. The following entries get added for the aforementioned validation in the EmpEO.xml file: <validation:CollectionValidationBean Name="EmpEO_Rule_0" ResId= "com.empdirectory.model.entity.EmpEO_Rule_0" OnAttribute="Empno" OperandType="LITERAL" Inverse="false" CompareType="GREATERTHAN" CompareValue="5" Operation="count"> <validation:OnCondition> <![CDATA[Deptno = '10']]> </validation:OnCondition> </validation:CollectionValidationBean> <ResourceBundle> <PropertiesBundle PropertiesFile= "com.empdirectory.model.ModelBundle"/> </ResourceBundle> The error message that is added in the Failure Handling section is automatically added to the resource bundle. The Compare validator The Compare validator is used to compare the current attribute value with other values. The attribute value can be compared against the literal value, query result, expression, view object attribute, and so on. The operators supported are equal, not-equal, less-than, greater-than, less-than or equal to, and greater-than or equal to. The Key Exists validator This validator is used to check if the key value exists for an entity object. The key value can be a primary key, foreign key, or an alternate key. The Key Exists validator is used to find the key from the entity cache, and if the key is not found, the value is determined from the database. Because of this reason, the Key Exists validator is considered to give better performance. For example, when an employee is assigned to a department deptNo 50 and you want to make sure that deptNo 50 already exists in the DEPT table. The Length validator This validator is used to check the string length of an attribute value. The comparison is based on the character or byte length. The List validator This validator is used to create a validation for the attribute in a list. The operators included in this validation are In and NotIn. These two operators help the validation rule check if an attribute value is in a list. The Method validator Sometimes, we would like to add our own validation with some extra logic coded in our Java class file. For this purpose, ADF provides a declarative validator to map the validation rule against a method in the entity-implementation class. The implementation class is generated in the Java section of the entity object. We need to create and select a method to handle method validation. The method is named as validateXXX(), and the returned value will be of the Boolean type. The Range validator This validator is used to add a rule to validate a range for the attribute value. The operators included are Between and NotBetween. The range will have a minimum and maximum value that can be entered for the attribute. The Regular Expression validator For example, let us consider that we have a validation rule to check if the e-mail ID provided by the user is in the correct format. For the e-mail validation, we have some common rules such as the following: The e-mail ID should start with a string and end with the @ character The e-mail ID's last character cannot be the dot (.) character Two @ characters are not allowed within an e-mail ID For this purpose, ADF provides a declarative Regular Expression validator. We can use the regex pattern to check the value of the attribute. The e-mail address and the US phone number pattern is provided by default: Email: [A-Z0-9._%+-]+@[A-Z0-,9.-]+.[A-Z]{2,4} Phone Number (US): [0-9]{3}-?[0-9]{3}-?[0-9]{4} You should select the required pattern and then click on the Use Pattern button to use it. Matches and NotMatches are the two operators that are included with this validator. The Script validator If we want to include an expression and validate the business rule, the Script validator is the best choice. ADF supports Groovy expressions to provide Script validation for an attribute. The UniqueKey validator This validator is available for use only for entity-level validation. To check for uniqueness in the record, we would be using this validator. If we have a primary key defined for the entity object, the Uniqueness Check Definition section will list the primary keys defined to check for uniqueness, as shown in the following screenshot: If we have to perform a uniqueness check against any attribute other than the primary key attributes, we will have to create an alternate key for the entity object. Time for action – creating an alternate key for DeptEO Currently, the DeptEO.xml file has Deptno as the primary key. We would add business validation that states that there should not be a way to create a duplicate of the department name that is already available. The following steps show how to create an alternate key: Go to the General section of the DeptEO.xml file and expand the Alternate Keys section. Alternate keys are keys that are not part of the primary key. Click on the little + icon to add a new alternate key. Move the Dname attribute from the Available list to the Selected list and click on the OK button. What just happened? We have created an alternate key against the Dname attribute to prepare for a unique check validation for the department name. When the alternate key is added to an entity object, we will see the AltKey attribute listed in the Alternate Key section of the General tab. In the DeptEO.xml file, you will find the following code that gets added for the alternate key definition: <Key Name="AltKey" AltKey="true"> <DesignTime> <Attr Name="_isUnique" Value="true"/> <Attr Name="_DBObjectName" Value="HR.DEPT"/> </DesignTime> <AttrArray Name="Attributes"> <Item Value= "com.empdirectory.model.entity.DeptEO.Dname"/> </AttrArray> </Key> Have a go hero – compare the attributes For the first time, we have learned about the validations in ADF. So it's time for you to create your own validation for the EmpEO and DeptEO entity objects. Add validations for the following business scenarios: Continue with the creation of the uniqueness check for the department name in the DeptEO.xml file. The salary of the employees should not be greater than 1000. Display the following message if otherwise: Please enter Salary less than 1000. Display the message invalid date if the employee's hire date is after 10-10-2001. The length of the characters entered for Dname of DeptEO.xml should not be greater than 10. The location of a department can only be NEWYORK, CALIFORNIA, or CHICAGO. The department name should always be entered in uppercase. If the user enters a value in lowercase, display a message. The salary of an employee with the MANAGER job role should be between 800 and 1000. Display an error message if the value is not in this range. The employee name should always start with an uppercase letter and should end with any character other than special characters such as :, ;, and _. After creating all the validations, check the code and tags generated in the entity's XML file for each of the aforementioned validations.
Read more
  • 0
  • 0
  • 7654

article-image-converting-tables-graphs-advanced
Packt
06 May 2013
7 min read
Save for later

Converting tables into graphs (Advanced)

Packt
06 May 2013
7 min read
(For more resources related to this topic, see here.) Getting ready We maintained the same structure for our table, however this time we do not use this example and load it via AJAX. So the markup looks as follows: <table id="dynamicTable" class="table"> <thead> <tr> <th>Reviews</th> <th>Top</th> <th>Rolling Stones</th> <th>Rock Hard</th> <th>Kerrang</th> </tr> </thead> <tbody> <tr> <th>Ac/Dc</th> <td>10</td> <td>9</td> <td>8</td> <td>9</td> </tr> <tr> <th>Queen</th> <td>9</td> <td>6</td> <td>8</td> <td>5</td> </tr> <tr> <th>Whitesnake</th> <td>8</td> <td>9</td> <td>8</td> <td>6</td> </tr> <tr> <th>Deep Purple</th> <td>10</td> <td>6</td> <td>9</td> <td>8</td> </tr> <tr> <th>Black Sabbath</th> <td>10</td> <td>5</td> <td>7</td> <td>8</td> </tr> </tbody> </table> How to do it... Let's see what we need to do: Add a div right on the top of our table with an ID called graph: <div id="graph"></div> We will use a jQuery Plugin called Highcharts, which can be downloaded for free from http://www.highcharts.com/products/highcharts. Add the following script to the bottom of our document: <script src = "highcharts.js"></script> Add a simple script to initialize the graph as follows: var chart; Highcharts.visualize = function(table, options) { // the data series options.series = []; var l= options.series.length; options.series[l] = { name: $('thead th:eq('+(l+1)+')', table).text(), data: [] }; $('tbody tr', table).each( function(i) { var tr = this; var th = $('th', tr).text(); var td = parseFloat($('td', tr).text()); options.series[0].data.push({name:th,y:td}); }); chart = new Highcharts.Chart(options); } // On document ready, call visualize on the datatable. $(document).ready(function() { var table = document.getElementById('dynamicTable'), options = { chart: { renderTo: 'graph', defaultSeriesType: 'pie' }, title: { text: 'Review Notes from Metal Mags' }, plotOptions: { pie: { allowPointSelect: true, cursor: 'pointer', dataLabels: { enabled: false }, showInLegend: true } }, tooltip: { pointFormat: 'Total: <b>{point.percentage}%</ b>', percentageDecimals: 1 } }; Highcharts.visualize(table, options); }); Many people choose to hide the div with the table in smaller devices and show only the graph. Once they've optimized our table and depending on the amount of data, there is no problem. It also shows that the choice is yours. Now when we look at the browser, we can view both the table and the graph as shown in the following screenshot: Browser screenshot at 320px. Highcharts plugins have an excellent quality in all browsers and works with SVG, they are compatible with iPad, iPhone, and IE 6. How it works... The plugin can generate the table using only a single data array, but by our intuition and step-by-step description of its uses, we have created the following code to generate the graph starting from a table previously created. We create the graph using the id#= dynamicTable function, where we read its contents through the following function: $('tbody tr', table).each( function(i) { var tr = this; var th = $('th', tr).text(); var td = parseFloat($('td', tr).text()); options.series[0].data.push({name:th,y:td}); }); In the plugin settings, we set the div graph to receive the graph after it is rendered by the script. We also add a pie type and a title for our graph. options = { chart: { renderTo: 'graph', defaultSeriesType: 'pie' }, title: { text: 'Review Notes from Metal Mags' }, There's more... We can hide the table using media query so that only the graph appears. Remember that it just hides the fact and does not prevent it from being loaded by the browser; however we still need it to build the graph. For this, just apply display none to the table inside the breakpoint: @media only screen and (max-width: 768px) { .table { display: none; } } Browser screenshot at 320px, without the table Merging data – numbers and text (Advanced) We introduce an alternative based on CSS3 for dealing with tables containing text and numbers. Getting ready Tables are used for different purposes, we will see an example where our data is not a data table. (Code Example: Chapter07_Codes_1 ) Browser screenshot at 1024px Although our table did not have many columns, showing it on a small screen is not easy. Hence we will progressively show the change in the table by subtracting the width of the screen. How to do it... Note that we have removed the .table class so this time apply the style directly in the table tags, see the following steps: Let's use a simple table structure as we saw before. Add some CSS3 to make some magic with our selectors. Set our breakpoints to two sizes. <table> <thead> <tr> <th>CONTACT</th> <th scope="col">Manager</th> <th scope="col">Label</th> <th scope="col">Phone</th> </tr> </thead> <tbody> <tr> <th scope="row">Black Sabbath</th> <td>Richard Both</td> <td>Atlantic</td> <td>+1 (408) 257-1500 </td> </tr> <tr> <th scope="row">Ac/DC</th> <td>Paolla Matazo</td> <td>Sony</td> <td>+1 (302) 236-0800</td> </tr> <tr> <th scope="row">Queen</th> <td>Suzane Yeld</td> <td>Warner</td> <td>+1 (103) 222-6754</td> </tr> <tr> <th scope="row">Whitesnake</th> <td>Paul S. Senne</td> <td>Vertigo</td> <td>+1 (456) 233-1243</td> </tr> <tr> <th scope="row">Deep Purple</th> <td>Ian Friedman</td> <td>CosaNostra</td> <td>+1 (200) 255-0066</td> </tr> </tbody> </table> Applying the style as follows: table { width: 100%; background-color: transparent; border-collapse: collapse; border-spacing: 0; background-color: #fff } th { text-align: left; } td:last-child, th:last-child { text-align:right; } td, th { padding: 6px 12px; } tr:nth-child(odd), tr:nth-child(odd) { background: #f3f3f3; } tr:nth-child(even) { background: #ebebeb; } thead tr:first-child, thead tr:first-child { background: #000; color:white; } table td:empty { background:white; } We use CSS3 pseudo-selectors here again to help in the transformation of the table. And the most important part, the Media Queries breakpoints: @media (max-width: 768px) { tr :nth-child(3) {display: none;} } @media (max-width: 480px) { thead tr:first-child {display: none;} th {display: block} td {display: inline!important;} } When the resolution is set to 768px, we note that the penultimate column is removed. This way we keep the most relevant information on the screen. We have hidden the information less relevant to the subject. And when we decrease further, we have the data distributed as a block. Summary In this article, we saw an alternative solution combining the previous recipes with another plugin for rendering graphics. Resources for Article : Further resources on this subject: MySQL 5.1 Plugin: HTML Storage Engine—Reads and Writes [Article] Creating Accessible Tables in Joomla! [Article] HTML5: Generic Containers [Article]
Read more
  • 0
  • 0
  • 19420

article-image-ten-ipython-essentials
Packt
02 May 2013
10 min read
Save for later

Ten IPython essentials

Packt
02 May 2013
10 min read
(For more resources related to this topic, see here.) Running the IPython console If IPython has been installed correctly, you should be able to run it from a system shell with the ipython command. You can use this prompt like a regular Python interpreter as shown in the following screenshot: Command-line shell on Windows If you are on Windows and using the old cmd.exe shell, you should be aware that this tool is extremely limited. You could instead use a more powerful interpreter, such as Microsoft PowerShell, which is integrated by default in Windows 7 and 8. The simple fact that most common filesystem-related commands (namely, pwd, cd, ls, cp, ps, and so on) have the same name as in Unix should be a sufficient reason to switch. Of course, IPython offers much more than that. For example, IPython ships with tens of little commands that considerably improve productivity. Some of these commands help you get information about any Python function or object. For instance, have you ever had a doubt about how to use the super function to access parent methods in a derived class? Just type super? (a shortcut for the command %pinfo super) and you will find all the information regarding the super function. Appending ? or ?? to any command or variable gives you all the information you need about it, as shown here: In [1]: super? Typical use to call a cooperative superclass method: class C(B): def meth(self, arg): super(C, self).meth(arg) Using IPython as a system shell You can use the IPython command-line interface as an extended system shell. You can navigate throughout your filesystem and execute any system command. For instance, the standard Unix commands pwd, ls, and cd are available in IPython and work on Windows too, as shown in the following example: In [1]: pwd Out[1]: u'C:' In [2]: cd windows C:windows These commands are particular magic commands that are central in the IPython shell. There are dozens of magic commands and we will use a lot of them throughout this book. You can get a list of all magic commands with the %lsmagic command. Using the IPython magic commands Magic commands actually come with a % prefix, but the automagic system, enabled by default, allows you to conveniently omit this prefix. Using the prefix is always possible, particularly when the unprefixed command is shadowed by a Python variable with the same name. The %automagic command toggles the automagic system. In this book, we will generally use the % prefix to refer to magic commands, but keep in mind that you can omit it most of the time, if you prefer. Using the history Like the standard Python console, IPython offers a command history. However, unlike in Python's console, the IPython history spans your previous interactive sessions. In addition to this, several key strokes and commands allow you to reduce repetitive typing. In an IPython console prompt, use the up and down arrow keys to go through your whole input history. If you start typing before pressing the arrow keys, only the commands that match what you have typed so far will be shown. In any interactive session, your input and output history is kept in the In and Out variables and is indexed by a prompt number. The _, __, ___ and _i, _ii, _iii variables contain the last three output and input objects, respectively. The _n and _in variables return the nth output and input history. For instance, let's type the following command: In [4]: a = 12 In [5]: a ** 2 Out[5]: 144 In [6]: print("The result is {0:d}.".format(_)) The result is 144. In this example, we display the output, that is, 144 of prompt 5 on line 6. Tab completion Tab completion is incredibly useful and you will find yourself using it all the time. Whenever you start typing any command, variable name, or function, press the Tab key to let IPython either automatically complete what you are typing if there is no ambiguity, or show you the list of possible commands or names that match what you have typed so far. It also works for directories and file paths, just like in the system shell. It is also particularly useful for dynamic object introspection. Type any Python object name followed by a point and then press the Tab key; IPython will show you the list of existing attributes and methods, as shown in the following example: In [1]: import os In [2]: os.path.split<tab> os.path.split os.path.splitdrive os.path.splitext os.path.splitunc In the second line, as shown in the previous code, we press the Tab key after having typed os.path.split. IPython then displays all the possible commands. Tab Completion and Private Variables Tab completion shows you all the attributes and methods of an object, except those that begin with an underscore (_). The reason is that it is a standard convention in Python programming to prefix private variables with an underscore. To force IPython to show all private attributes and methods, type myobject._ before pressing the Tab key. Nothing is really private or hidden in Python. It is part of a general Python philosophy, as expressed by the famous saying, "We are all consenting adults here." Executing a script with the %run command Although essential, the interactive console becomes limited when running sequences of multiple commands. Writing multiple commands in a Python script with the .py file extension (by convention) is quite common. A Python script can be executed from within the IPython console with the %run magic command followed by the script filename. The script is executed in a fresh, new Python namespace unless the -i option has been used, in which case the current interactive Python namespace is used for the execution. In all cases, all variables defined in the script become available in the console at the end of script execution. Let's write the following Python script in a file called script.py: print("Running script.") x = 12 print("'x' is now equal to {0:d}.".format(x)) Now, assuming we are in the directory where this file is located, we can execute it in IPython by entering the following command: In [1]: %run script.py Running script. 'x' is now equal to 12. In [2]: x Out[2]: 12 When running the script, the standard output of the console displays any print statement. At the end of execution, the x variable defined in the script is then included in the interactive namespace, which is quite convenient. Quick benchmarking with the %timeit command You can do quick benchmarks in an interactive session with the %timeit magic command. It lets you estimate how much time the execution of a single command takes. The same command is executed multiple times within a loop, and this loop itself is repeated several times by default. The individual execution time of the command is then automatically estimated with an average. The -n option controls the number of executions in a loop, whereas the -r option controls the number of executed loops. For example, let's type the following command: In[1]: %timeit [x*x for x in range(100000)] 10 loops, best of 3: 26.1 ms per loop Here, it took about 26 milliseconds to compute the squares of all integers up to 100000. Quick debugging with the %debug command IPython ships with a powerful command-line debugger. Whenever an exception is raised in the console, use the %debug magic command to launch the debugger at the exception point. You then have access to all the local variables and to the full stack traceback in postmortem mode. Navigate up and down through the stack with the u and d commands and exit the debugger with the q command. See the list of all the available commands in the debugger by entering the ? command. You can use the %pdb magic command to activate the automatic execution of the IPython debugger as soon as an exception is raised. Interactive computing with Pylab The %pylab magic command enables the scientific computing capabilities of the NumPy and matplotlib packages, namely efficient operations on vectors and matrices and plotting and interactive visualization features. It becomes possible to perform interactive computations in the console and plot graphs dynamically. For example, let's enter the following command: In [1]: %pylab Welcome to pylab, a matplotlib-based Python environment [backend: TkAgg]. For more information, type 'help(pylab)'. In [2]: x = linspace(-10., 10., 1000) In [3]: plot(x, sin(x)) In this example, we first define a vector of 1000 values linearly spaced between -10 and 10. Then we plot the graph (x, sin(x)). A window with a plot appears as shown in the following screenshot, and the console is not blocked while this window is opened. This allows us to interactively modify the plot while it is open. Using the IPython Notebook The Notebook brings the functionality of IPython into the browser for multiline textediting features, interactive session reproducibility, and so on. It is a modern and powerful way of using Python in an interactive and reproducible way To use the Notebook, call the ipython notebook command in a shell (make sure you have installed the required dependencies). This will launch a local web server on the default port 8888. Go to http://127.0.0.1:8888/ in a browser and create a new Notebook. You can write one or several lines of code in the input cells. Here are some of the most useful keyboard shortcuts: Press the Enter key to create a new line in the cell and not execute the cell Press Shift + Enter to execute the cell and go to the next cell Press Alt + Enter to execute the cell and append a new empty cell right after it Press Ctrl + Enter for quick instant experiments when you do not want to save the output Press Ctrl + M and then the H key to display the list of all the keyboard shortcuts Customizing IPython You can save your user preferences in a Python file; this file is called an IPython profile. To create a default profile, type ipython profile create in a shell. This will create a folder named profile_default in the ~/.ipython or ~/.config/ ipython directory. The file ipython_config.py in this folder contains preferences about IPython. You can create different profiles with different names using ipython profile create profilename, and then launch IPython with ipython --profile=profilename to use that profile. The ~ directory is your home directory, for example, something like /home/ yourname on Unix, or C:Usersyourname or C:Documents and Settings yourname on Windows. Summary We have gone through 10 of the most interesting features offered by IPython in this article. They essentially concern the Python and shell interactive features, including the integrated debugger and profiler, and the interactive computing and visualization features brought by the NumPy and Matplotlib packages. Resources for Article : Further resources on this subject: Advanced Matplotlib: Part 1 [Article] Python Testing: Installing the Robot Framework [Article] Running a simple game using Pygame [Article]
Read more
  • 0
  • 0
  • 3681

article-image-echo-serverclients
Packt
02 May 2013
12 min read
Save for later

Echo Server/Clients

Packt
02 May 2013
12 min read
(For more resources related to this topic, see here.) We will implement first a synchronous application, and then an asynchronous application, so you can easily compare them: Some of the following code has been trimmed to save space. You will find the full code in the code accompanying this book. TCP Echo server/clients For TCP, we can have an extra guarantee; each message ends in line feed ('n'). Coding Echo servers/clients synchronously is extremely easy. We will present programs, such as synchronous client, a synchronous server, a asynchronous client, and an asynchronous server. TCP synchronous client In most non-trivial examples, it's usually the client that is easier to code, than the server (since the server needs to deal with multiple clients). The following code shows an exception to the rule: ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 8001);size_t read_complete(char * buf, const error_code & err, size_t bytes){if ( err) return 0;bool found = std::find(buf, buf + bytes, 'n') < buf + bytes;// we read one-by-one until we get to enter, no bufferingreturn found ? 0 : 1;}void sync_echo(std::string msg) {msg += "n";ip::tcp::socket sock(service);sock.connect(ep);sock.write_some(buffer(msg));char buf[1024];int bytes = read(sock, buffer(buf), boost::bind(read_complete,buf,_1,_2));std::string copy(buf, bytes - 1);msg = msg.substr(0, msg.size() - 1);std::cout << "server echoed our " << msg << ": "<< (copy == msg ? "OK" : "FAIL") << std::endl;sock.close();}int main(int argc, char* argv[]) {char* messages[] = { "John says hi", "so does James","Lucy just got home", "Boost.Asio is Fun!", 0};boost::thread_group threads;for ( char ** message = messages; *message; ++message) {threads.create_thread( boost::bind(sync_echo, *message));boost::this_thread::sleep( boost::posix_time::millisec(100));}threads.join_all();} The function to watch for is sync_echo. It contains all the logic for connecting to a server, sending it a message and waiting for the echo back. You'll notice that, for reading, I've used the free function read(), because I want to read everything up to 'n'. The sock.read_some() function would not be enough, since that would only read what's available, which is not necessarily the whole message. The third argument to the read() function is a completion handler. It will return 0 when it's read the full message. Otherwise, it will return the maximum buffer it can read in the next step (until read is complete). In our case, this is always 1, because we never want to mistakenly read more than we need. In main(), we create several threads; one thread for each message to send to the client, and wait for them to complete. If you run the program, you'll see the following output: server echoed our John says hi: OKserver echoed our so does James: OKserver echoed our Lucy just got home: OKserver echoed our Boost.Asio is Fun!: OK Notice that since we're synchronous, there's no need to call service.run(). TCP synchronous server The Echo synchronous server is quite easy to write, as shown in the following code snippet: io_service service;size_t read_complete(char * buff, const error_code & err, size_tbytes) {if ( err) return 0;bool found = std::find(buff, buff + bytes, 'n') < buff + bytes;// we read one-by-one until we get to enter, no bufferingreturn found ? 0 : 1;}void handle_connections() {ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(),8001));char buff[1024];while ( true) {ip::tcp::socket sock(service);acceptor.accept(sock);int bytes = read(sock, buffer(buff),boost::bind(read_complete,buff,_1,_2));std::string msg(buff, bytes);sock.write_some(buffer(msg));sock.close();}}int main(int argc, char* argv[]) {handle_connections();} The logic of the server is handle_connections(). Since we're single-threaded, we accept a new client, read the message it sends us, echo it back, and then wait for the next client. Let's say, if two clients connect at once, the second client will have to wait for the server to service the first client. Notice again that since we're synchronous, there's no need to call service.run(). TCP asynchronous client Once we go asynchronous, the code becomes a bit more complicated. We'll model the connection class. By looking at the following code snippets in this section, you will notice that every asynchronous operation starts a new asynchronous operation, keeping the service. run() busy. First, the core functionality is: #define MEM_FN(x) boost::bind(&self_type::x, shared_from_this())#define MEM_FN1(x,y) boost::bind(&self_type::x, shared_from_this(),y)#define MEM_FN2(x,y,z) boost::bind(&self_type::x, shared_from_this(),y,z)class talk_to_svr : public boost::enable_shared_from_this<talk_to_svr>, boost::noncopyable {typedef talk_to_svr self_type;talk_to_svr(const std::string & message): sock_(service), started_(true), message_(message) {}void start(ip::tcp::endpoint ep) {sock_.async_connect(ep, MEM_FN1(on_connect,_1));}public:typedef boost::system::error_code error_code;typedef boost::shared_ptr<talk_to_svr> ptr;static ptr start(ip::tcp::endpoint ep, const std::string &message) {ptr new_(new talk_to_svr(message));new_->start(ep);return new_;}void stop() {if ( !started_) return;started_ = false;sock_.close();}bool started() { return started_; }...private:ip::tcp::socket sock_;enum { max_msg = 1024 };char read_buffer_[max_msg];char write_buffer_[max_msg];bool started_;std::string message_;}; We want to always use shared pointers to talk_to_svr, so that as long as there are asynchronous operations on an instance of talk_to_svr, that instance is alive. In order to avoid mistakes, such as constructing an instance of the talk_to_svr object on the stack, I've made the constructor private and disallowed copy construction (derived from boost::noncopyable). We have the core functions, such as start(), stop(), and started() that do just what their names say. To construct a connection, just call talk_to_ svr::start(endpoint, message). We also have one read and one write buffer (read_buffer_ and write_buffer_). The MEM_FN* macros are convenience macros, and they enforce always using a shared pointer to *this, via the shared_ptr_from_this() function. The following lines are very different than explained earlier: // equivalent to "sock_.async_connect(ep, MEM_FN1(on_connect,_1));"sock_.async_connect(ep,boost::bind(&talk_to_svr::on_connect,shared_ptr_from_this(),_1));sock_.async_connect(ep, boost::bind(&talk_to_svr::on_connect,this,_1)); In the former case, we're creating the async_connect completion handler correctly; it will hold a shared pointer to the talk_to_server instance until it calls the completion handler, thus, making sure we're still alive when that happens. In the latter case, we're creating the completion handler incorrectly. By the time it gets called, the talk_to_server instance could have been deleted! To read from or write to the socket, you'll use following code snippet: void do_read() {async_read(sock_, buffer(read_buffer_),MEM_FN2(read_complete,_1,_2), MEM_FN2(on_read,_1,_2));}void do_write(const std::string & msg) {if ( !started() ) return;std::copy(msg.begin(), msg.end(), write_buffer_);sock_.async_write_some( buffer(write_buffer_, msg.size()),MEM_FN2(on_write,_1,_2));}size_t read_complete(const boost::system::error_code & err, size_tbytes) {// similar to the one shown in TCP Synchronous Client} The do_read() function will make sure that we read a line from the server, at which point on_read() is called. The do_write() function will first copy the message into the buffer (since msg will probably go out of scope and be destroyed by the time the async_write actually takes place), and then make sure on_write() is called after the actual write takes place. And the most important functions, the one that contain the main logic of the class: void on_connect(const error_code & err) {if ( !err) do_write(message_ + "n");else stop();}void on_read(const error_code & err, size_t bytes) {if ( !err) {std::string copy(read_buffer_, bytes - 1);std::cout << "server echoed our " << message_ << ": "<< (copy == message_ ? "OK" : "FAIL") <<std::endl;}stop();}void on_write(const error_code & err, size_t bytes) {do_read();} After we're connected, we send the message to the server, do_write(). When the write operation is finished, on_write() gets called, which initiates a do_read() function. When do_read() is complete, on_read() gets called; here, we simply check that the message from the server is simply an echo, and exit from it. We'll send three messages to the server just to make it a bit more interesting: int main(int argc, char* argv[]) {ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"),8001);char* messages[] = { "John says hi", "so does James", "Lucy gothome", 0 };for ( char ** message = messages; *message; ++message) {talk_to_svr::start( ep, *message);boost::this_thread::sleep( boost::posix_time::millisec(100));}service.run();} The preceding code snippet will generate the following code: server echoed our John says hi: OKserver echoed our so does James: OKserver echoed our Lucy just got home: OK TCP asynchronous server The core functionality is similar to the one from the asynchronous client, shown as follows: class talk_to_client : public boost::enable_shared_from_this<talk_to_client>, boost::noncopyable {typedef talk_to_client self_type;talk_to_client() : sock_(service), started_(false) {}public:typedef boost::system::error_code error_code;typedef boost::shared_ptr<talk_to_client> ptr;void start() {started_ = true;do_read();}static ptr new_() {ptr new_(new talk_to_client);return new_;}void stop() {if ( !started_) return;started_ = false;sock_.close();}ip::tcp::socket & sock() { return sock_;}...private:ip::tcp::socket sock_;enum { max_msg = 1024 };char read_buffer_[max_msg];char write_buffer_[max_msg];bool started_;}; Since we've a very simple Echo server, there is no need for an is_started() function. For each client, just read its message, echo it back, and close it. The do_read(), do_write() and read_complete() functions are exactly the same as in the TCP asynchronous client. The main logic of the class is again in on_read() and on_write(): void on_read(const error_code & err, size_t bytes) {if ( !err) {std::string msg(read_buffer_, bytes);do_write(msg + "n");}stop();}void on_write(const error_code & err, size_t bytes) {do_read();} Dealing with the clients is done as follows: ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(),8001));void handle_accept(talk_to_client::ptr client, const error_code & err){client->start();talk_to_client::ptr new_client = talk_to_client::new_();acceptor.async_accept(new_client->sock(),boost::bind(handle_accept,new_client,_1));}int main(int argc, char* argv[]) {talk_to_client::ptr client = talk_to_client::new_();acceptor.async_accept(client->sock(),boost::bind(handle_accept,client,_1));service.run();} Each time a client connects to the server, handle_accept is called, which will asynchronously start reading from that client, and also asynchronously wait for a new client. The code You'll find all four applications (TCP Echo Sync Client, TCP Echo Sync Server, TCP Echo Sync Client, TCP Echo Sync Server) in the code accompanying this book. When testing, you can use any client/server combination (such as, an asynchronous client versus a synchronous server). UDP Echo server/clients Since in UDP not all messages reach the recipient, we can't have the "message ends in enter" guarantee. Each message we receive, we simply echo back with no socket to close (on the server side), since we're UDP. UDP synchronous Echo client The UDP Echo client is simpler than the TCP Echo client: ip::udp::endpoint ep( ip::address::from_string("127.0.0.1"), 8001);void sync_echo(std::string msg) {ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(), 0));sock.send_to(buffer(msg), ep);char buff[1024];ip::udp::endpoint sender_ep;int bytes = sock.receive_from(buffer(buff), sender_ep);std::string copy(buff, bytes);std::cout << "server echoed our " << msg << ": "<< (copy == msg ? "OK" : "FAIL") << std::endl;sock.close();}int main(int argc, char* argv[]) {char* messages[] = { "John says hi", "so does James", "Lucy gothome", 0 };boost::thread_group threads;for ( char ** message = messages; *message; ++message) {threads.create_thread( boost::bind(sync_echo, *message));boost::this_thread::sleep( boost::posix_time::millisec(100));}threads.join_all();} The whole logic is in synch_echo(); connect to the server, send the message, receive the echo from server, and close the connection. UDP synchronous Echo server The UDP Echo server is the easiest server you'll ever write: io_service service;void handle_connections() {char buff[1024];ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(),8001));while ( true) {ip::udp::endpoint sender_ep;int bytes = sock.receive_from(buffer(buff), sender_ep);std::string msg(buff, bytes);sock.send_to(buffer(msg), sender_ep);}}int main(int argc, char* argv[]) {handle_connections();} That's simple, and quite self-explanatory. I'll leave the asynchronous UDP client and server as an exercise for the reader. Summary We've written full applications and finally put Boost.Asio to work. The Echo application is a very good tool to start learning a library. You can always study and run the code shown in this article to easily remember the library's fundamentals. Resources for Article : Further resources on this subject: FAQs on Microsoft SQL Server 2008 High Availability [Article] An Introduction to Rhomobile [Article] Overview of FIM 2010 R2 [Article]
Read more
  • 0
  • 0
  • 11511
article-image-creating-website-artisteer
Packt
30 Apr 2013
5 min read
Save for later

Creating a website with Artisteer

Packt
30 Apr 2013
5 min read
(For more resources related to this topic, see here.) Layout The first thing that we should set up while designing a new website is its width. If you are interested in creating web pages, you probably have a monitor with a large widescreen and good resolution. But we have to remember that not all of your visitors will have such good hardware. All the templates generated by Artisteer are centered, and almost all modern browsers enable you to freely zoom the page. It's far better to let some of your visitors enlarge the site than to make the rest of them use the horizontal scroll bar while reading. The resolution you choose will depend on the target audience of your site. Usually, private computers have better parameters than the typical PCs used for just office work in companies. So if you design a site that you know will be viewed mostly by private individuals, you can choose a slightly wider layout than you might for a typical business site. But you cannot forget that many nonbusiness websites, such as community sites, are often accessed from offices. So what is the answer? In my opinion, a layout with a width of 1,000 pixels is still a good choice for most of the cases. Such width ensures that the site will be displayed correctly on a pretty old, but still commonly used, nonwide 17'' monitor. (The typical resolution for this hardware is 1,024 x 768 and such a layout will fill the whole screen.) As more and more users have now started using computers that are equipped with a far better screen, you can consider increasing the resolution slightly, to, for example, 1,150 pixels. Remember that not every user will visit your site using a desktop. Many laptops, and especially netbooks and tablets, don't have wide screens either. Remember that the width of the page must be a little lower than the total resolution of the screen. You should reserve some space for the vertical scrollbar. We are going to set up the width of our project traditionally to 1,000 pixels. To do this, click on the Layout tab on the ribbon, and next to the Sheet Width button. Choose 1000 pixels from the available options on the list. The Sheet Options window is divided into two areas: on the left you can choose from the values expressed in pixels, while on the right, as a percentage. The percentage value means that the page doesn't have a fixed width, but it will change according to the parameters of the screen it is displayed on (according to the chosen percentage value). Designing layouts with the width defined in percentage might seem to be a great idea; and indeed, this technique, when properly used, can lead to great results. But you have to remember, that in such a case, all page elements have to be similarly prepared in order, to be able to adapt to the dynamically changing width of the site. It is far simpler to achieve good results for the layout with fixed values (expressed in pixels). It is a common rule while working with Artisteer that after clicking on a button on the ribbon, you get the list containing the most commonly used standard values. If you need a custom value, however, you can click on the button located at the bottom of the list to go to a window where you can freely set up and choose the required value. For example, while choosing the width of a layout, clicking on the More Sheet Widths... button (located just under the list) will lead you to a window where you can set up the required width with an accuracy up to 1 pixel. We can set the required value in three ways: We can click on the up and down arrows that are located on the right side of the field. We can move the mouse cursor on the field and use the slider that appears. We can click on the field. The text cursor will appear. Then we can type the required value using the keyboard. For me, this is the most comfortable way, especially since the slider's minimal progress is more than 1. Panel mode versus windows mode If you look carefully at the displayed windows, on the bottom-right corner you will see a panel mode button. This button switches Artisteer's interface between panel mode and windows mode. In the windows mode, the advanced settings are displayed in windows. In the panel mode, the advanced settings are displayed on the side panel located on the right side of Artisteer's window. If you are using a wide screen, you may find the panel mode to be more comfortable. Its advantage is that the side panel doesn't cover anything on your project, so you have a better view to observe the changes. Such a change is persistent and if you switch to the panel mode, all the advanced settings will be displayed in the right panel, as long as you decide to go back into the windows mode. To reverse, find and click on the icon located in the top-right corner of the side panel (just next to the x button that closes the panel). Summary This article has covered some features exclusive to Artisteer. It has also explained a brief process of how to create stunning templates for websites using Artisteer. Resources for Article : Further resources on this subject: Creating and Using Templates with Cacti 0.8 [Article] Using Templates to Display Channel Content in ExpressionEngine [Article] Working with Templates in Apache Roller 4.0 [Article]
Read more
  • 0
  • 0
  • 2140

article-image-installing-and-customizing-redmine
Packt
30 Apr 2013
12 min read
Save for later

Installing and customizing Redmine

Packt
30 Apr 2013
12 min read
(For more resources related to this topic, see here.) Installing Redmine from the package This guide can also be used to install Redmine on Debian. Ubuntu and Debian are very much alike so the installation procedure should not differ much. Still some things may differ. Assuming you have already installed Ubuntu Server 12.04 LTS (or a more recent version). If not, please do it! Assuming also that this is a clean installation, so we will need to install, Apache, MySQL, and so on, all software needed to run Redmine. If some software is already installed it's not a problem as it is still safe to execute the commands given. The Ubuntu (and Debian) package manager is smart enough to skip already installed software. Installing Redmine and MySQL server Now let's execute the following command in the console: $ sudo apt-get install redmine redmine-mysql mysql-server Instead of redmine-mysql and mysql-server, you can use redmine-pgsql and postgresql or redmine-sqlite and sqlite3 here. However, remember that neither PostgreSQL nor SQLite3 is reviewed in this topic. This command will install Redmine and MySQL as well as many dependency packages including Ruby and Rails. Before doing this, the Apt-Get package manager will ask you to confirm: On the screen, type y and press Enter. Configuring MySQL server package After this it will download all the packages and start the installation process. Soon you will get the screen: This screen asks you to enter a new password for the MySQL superuser. The same password will be used later to set up the Redmine database. After entering the password press Tab to switch to the Ok button and then press Enter. You will be redirected to the password confirmation screen. Enter the same password again, press Tab (to move to the Ok button) and then press Enter. After that it will take some time to install packages. In particular, it will install MySQL server and, when ready, initiate Redmine configuration. Configuring Redmine package The Debian/Ubuntu Redmine package supports many instances of Redmine. Several instances, for example, can be used to run Redmine in "production" and "development" modes at the same time (two instances for example, at different ports). The configurator of the package, however, will ask you to configure only one "default" instance. On this screen the configurator suggests its assistance in creating and configuring the database for Redmine. Unless you are willing to configure the database by yourself just press Enter here. The next screen, which appears immediately, asks you to select the database backend. It has nothing to do with database servers. This screen configures the Redmine database client. As we selected MySQL at command line just press Enter. And here comes the screen, which has already been mentioned: Enter here the MySQL superuser password which you specified before. This password will be used to create, configure and populate the Redmine database. When finished press Tab to switch to the Ok button and press Enter. Now the final screen of the Redmine database configuration comes: The password, what this screen asks, will be used by Redmine to access its database. It is unlikely that this password will be used elsewhere, moreover, it should not be used elsewhere! So this password should be as complex as possible. Therefore it is, perhaps, better to just press Enter here and let the configurator generate the password for you. You may also need to specify this password in Apache configuration files for advanced SCM integration. After this screen the Redmine package configurator will perform some finalizing work and return to the shell prompt. That's it! Redmine has been installed and configured and is ready to run. But the system is not yet ready to run Redmine. We need a web server to do this. As a web server we will use Apache. Besides Apache, we need something to run a Ruby application and this is going to be the Passenger module for Apache. Installing Apache and Passenger So let's now install Apache and Passenger: $ sudo apt-get install apache2 libapache2-mod-passenger As before you will be asked to press Enter. After this the package manager will download the specified packages and their dependencies, will install them and start Apache: If everything has gone well, you should see [ OK ] to the right from Starting ... and Reloading ... messages, as seen on the screenshot. You may also get the warning you see on the screenshot, but do not worry, it just means you need to set Apache's ServerName property to a proper value. Connecting Redmine and Apache But, wait, where is Redmine? Right now Redmine is not connected to Apache. Unfortunately, despite the power of Debian package management software this part should be configured manually. Luckily it's not so complex: the Debian Redmine package contains sample configuration files for Redmine under /usr/ share/doc/redmine/examples directory. In this directory you will find sample configurations for Apache and FastCGI or Passenger, Lighttpd, Nginx and Thin. In this directory we have two sample files for Apache2 and Passenger: apache2- passenger-alias.conf and apache2-passenger-host.conf. The former should be used if you want to run Redmine under some URL path for example, www.yourdomain.com/redmine. The latter should be used if you want to run Redmine under subdomain or as the primary application on your domain. Assuming that you have installed a clean Ubuntu (as I did) especially for Redmine, that is, that you want to use the server only for Redmine or for Redmine as the primary application. Let's copy apache2-passenger-host.conf to /etc/apache2/sites-available/ (the path for site configurations on Debian/Ubuntu). $ sudo cp /usr/share/doc/redmine/examples/apache2-passenger-host.conf /etc/apache2/sites-available/ Actually this file contains configurations for two Redmine instances, "default" and "instance2", and on two different ports, 3000 and 3030. Let's clean it up to get a configuration for the "default" instance only and for the default port. We should get something like: # These modules must be enabled : passenger<VirtualHost *:80># ServerName my.domain.name# this is the passenger configRailsEnv production# create a link in /var/lib/redmine/default/passenger to/usr/share/redminePassengerAppRoot /var/lib/redmine/default/passengerSetEnv X_DEBIAN_SITEID "default"Alias "/plugin_assets/" /var/cache/redmine/default/plugin_assets/DocumentRoot /usr/share/redmine/public<Directory "/usr/share/redmine/public">Order allow,denyAllow from all</Directory></VirtualHost> I changed localhost:3000 to *:80, removed port numbers and the second <VirtualHost> configuration. Before we proceed we need to do what is advised in the configuration file. To create symbolic link passenger in /var/lib/redmine/default pointing to /usr/share/redmine (the directory Redmine was installed into). $ sudo ln -sf /usr/share/redmine /var/lib/redmine/default/passenger Now we need to "apply" our new site. Remember we have copied apache2-passenger-host.conf to /etc/apache2/sites-available/? This directory stores available sites' configurations, as it comes from the name, and enabled sites configurations are stored in /etc/apache2/sites-enabled/. So we need to "move" our new configuration file into the latter directory. Let's do it in the correct Debian/Ubuntu way: $ sudo a2ensite apache2-passenger-host.conf The e2ensite script creates symbolic links in /etc/apache2/sites-enabled/ pointing to sites configuration files in /etc/apache2/sites-available/. The similar script e2dissite can be used to disable sites. So let's now disable the default site which comes with Apache in Debian/Ubuntu (the one displaying It works!): $ sudo a2dissite default Let's now reload Apache to activate the new configuration: $ sudo service apache2 reload Now when we load the site we get: Congratulations! We have successfully installed Redmine. But still there are things we need to do before making a break for coffee and moving ahead. Verifying and completing installation Click on the Sign in link in the top-right corner to log in to our Redmine. Use admin as a login and as a password. After you have signed in, click on the new item Administration on the top dark blue menu bar. Administration sections will appear on the right sidebar. Select the Information section. The above screenshot shows the screen one should always check after installing Redmine! As you see it contains the checklist that should be used to verify the installation. Changing administrator account is a common procedure for any type of installation while installing RMagick is specific, that's why we came to this screen. RMagick is Ruby interface for the ImageMagick image processing library. This library is used by Redmine for Gantt chart export. It can also be used by some third-party plugins. So to install RMagick execute the following command: $ sudo apt-get install ruby-rmagick Now reload Apache again to apply: $ sudo service apache2 reload After Apache reloads, we get the green checkmark to the right from RMagick. The only procedure left is changing the administrator account. To do this click on the Users link on the administration sidebar, open profile of the admin user (the only user available) and change login and password to some other values. Conclusion As you see this type of Redmine installation is quite easy and involves a few commands. Besides easiness, I believe, it has the following benefits: The installed Redmine conforms to FHS (Filesystem Hierarchy Standard), that is, configuration files are located in /etc/redmine, Redmine itself in /usr/share/redmine, cache in /var/cache/redmine, logs in /var/log/ redmine, and so on. That is, any administrator, who is aware of FHS (even if he/she is not aware of Redmine), will be able to understand the Redmine file structure, and system tools, such as log analyzers, will be able to pick up and process Redmine files. As Redmine was installed as a part of the Linux distribution, the system will be able to maintain it. Thus Redmine can be updated with the rest of the system and other system updates are unlikely to break Redmine. Customizing Redmine Personalization is the customization made by users for themselves using only the permissions they have. Installing plugins is the customization done by server administrators (don't confuse this with the Redmine administrator). In such cases we usually want to have our own look and feel (theme), to add custom content to different pages, and so on. During this customization phase users usually ask experts for help. Thus, sometimes they want to develop plugins to implement different ideas but plugins, actually, are not always needed. Also, during this phase users often customize Redmine by themselves and, usually, do this incorrectly. So, what the right way is to customize Redmine, what we can do without developing custom plugins, and so on, are the topics we will speak about now. In the customization section we will cover the following topics: Customizing with Textile Customizing theme Customizing with plugins Customizing with Textile I was formerly asked to create a custom plugin to improve the layout of the Redmine start page (available through the Home link) with buttons, links, sections, and other similar stuff. My answer was, you don't need a plugin to do that. Textile is a very simplified HTML. Of course, it can't be used to create full-featured HTML pages, but for many things it can appear to be sufficient. However, to achieve the necessary results you, most likely, will need to use the most advanced Redmine Textile features. Also, similar to HTML, you can't just learn how to create a good look and feel—you can only get the idea. You will need to inject your own creativity to get what you need. Therefore, under this topic we will review some interesting customization examples, which should help you understand the technique. Wiki pages as tabs in the project menu The wiki Extensions plugin, created by Haruyuki Iida, allows adding wiki pages to the project menu as tabs (configured per project). You can find more information on this at http://www.r-labs.org/projects/r-labs/wiki/Wiki_Extensions_en . Things we will discuss here will look tricky and, perhaps, you will ask, why should we prefer this technique over writing a plugin? The answer is, Textile formatting will survive the upgrade of Redmine, while a plugin, most likely, will need to be updated. Using HTML code in wiki pages Arlo Carreon created the wiki HTML Util plugin, which can be used to embed HTML, CSS, or JavaScript code directly into a wiki page. You can find more information at https://github.com/mexitek/redmine_wiki_html_util. Warnings and other boxes Redmine core CSS classes can also be utilized to build information boxes in the wiki content, for example: p(conflict). A warning message.p(box). Rendered as a box. This is shown as follows: Icons for text If you want to put an icon before a text, you can, for example: You can insert "(icon icon-fav)a link with an icon": http://www.andriylesyuk.com or even %(icon icon-checked).not a link%... This Textile code will be rendered in the following way: Here we use Redmine icon CSS classes and utilize the Textile SPAN element (using %). Table-based layout In modern web design everyone prefers building the page layout using DIVs and not old-style HTML tables. But in Textile we don't have enough control over DIVs. However, we can still use tables: table{border:none}.|{border:none}.eBook: %{color:#bbb}£18.99%|{border:none;padding:1em}.%{font-size:1.5em}£15.19%save 20%|{border:none}.!http://www.packtpub.com/sites/all/themes/packt_new/images/addtocart.gif!:http://www.packtpub.com/masteringredmine/book||{border:none}.Print + free eBook + free PacktLib access to thebook: %{color:#bbb}£49.98%|{border:none;padding:1em}.%{fontsize:1.5em}£27.89%save 44%|{border:none}.!http://www.packtpub.com/sites/all/themes/packt_new/images/addtocart.gif!:http://www.packtpub.com/masteringredmine/book| This tricky code produces the following result: In this example we defined CSS styles for the table (table{border:none}.) and its cells (for example, |{border:none;padding:1em}.) and, again, utilized the HTML SPAN element (for example, %{color:#bbb}£49.98%).
Read more
  • 0
  • 0
  • 5153

article-image-getting-started-modernizr-using-php-ide
Packt
30 Apr 2013
5 min read
Save for later

Getting started with Modernizr using PHP IDE

Packt
30 Apr 2013
5 min read
(For more resources related to this topic, see here.) From the Modernizr website: Modernizr is a small JavaScript library that detects the availability of native implementations for next-generation web technologies, i.e. features that stem from the HTML5 and CSS3 specifications. Many of these features are already implemented in at least one major browser (most of them in two or more), and what Modernizr does is, very simply, tell you whether the current browser has this feature natively implemented or not. Basically with this library, we can see if the user's browser can support certain features you wish to use on your site. This is important to do, as unfortunately not every browser is created the same. Each one has its own implementation of the HTML5 standard, so some features may be available on Google Chrome but not on Internet Explorer. Using Modernizr is a better alternative to the standard, but it is unreliable, user agent (UA) string checking. Let's begin. Getting ready Go ahead and create a new Web Project in Aptana Studio. Once it is set up, go ahead and add a new folder to the project named js. Next thing we need to do is to download the Development Version of Mondernizr from the Modernizr download page (http://modernizr.com/download/). You will see options to build your own package. The development version will do until you are ready for production use. As of this writing, the latest version is 2.6.2 and that will be the version we use. Place the downloaded file into the js folder. How to do it... Follow these steps: For this exercise, we will simply do a browser test to see if your browser currently supports the HTML5 Canvas element. Type this into a JavaScript file named canvas.js and add the following code: if (Modernizr.canvas) { var c=document.getElementById("canvastest"); var ctx=c.getContext("2d"); // Create gradient Var grd=ctx.createRadialGradient(75,50,5,90,60,100); grd.addColorStop(0,"black"); grd.addColorStop(1,"white"); // Fill with gradient ctx.fillStyle=grd; ctx.fillRect(10,10,150,80); alert("We can use the Canvas element!"); } else { alert("Canvas Element Not Supported"); } Now add the following to index.html: <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Canvas Support Test</title> <script src = "js/modernizr-latest.js" type="text/ javascript"></script> </head> <body> <canvas id="canvastest" width="200" height="100" style="border:1px solid #000000">Your browser does not support the HTML5 canvas tag.</canvas> <script src = "js/canvas.js"> </script> </body> </html> Let's preview the code and see what we got. The following screenshot is what you should see: How it works... What did we just do? Well, let's break it down: <script src = "js/modernizr-latest.js" type="text/javascript"></script> Here, we are calling in our Modernizr library that we downloaded previously. Once you do that, Modernizr does some things to your page. It will redo your opening <html> tag to something like the following (from Google Chrome): <html class=" js flexbox flexboxlegacy canvas canvastext webgl notouch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths"> This is all the features your browser supports that Modernizr was able to detect. Next up we have our <canvas> element: <canvas id="canvastest" width="200" height="100" style="border:1px solid #000000">Your browser does not support the HTML5 canvas tag.</ canvas> Here, we are just forming a basic canvas that is 200 x 100 with a black border going around it. Now for the good stuff in our canvas.js file, follow this code snippet: <script> if (Modernizr.canvas) { alert("We can use the Canvas element!"); var c=document.getElementById("canvastest"); var ctx=c.getContext("2d"); // Create gradient var grd=ctx.createRadialGradient(75,50,5,90,60,100); grd.addColorStop(0,"black"); grd.addColorStop(1,"white"); // Fill with gradient ctx.fillStyle=grd; ctx.fillRect(10,10,150,80); } else { alert("Canvas Element Not Supported"); } </script> In the first part of this snippet, we used an if statement to see if the browser supports the Canvas element. If it does support canvas, then we are displaying a JavaScript alert and then filling our canvas element with a black gradient. After that, we have our else statement that will alert the user that canvas is not supported on their browser. They will also see the Your browser does not support the HTML5 canvas tag message. That wasn't so bad, was it? There's more... I highly recommend reading over the documentation on the Modernizr website so that you can see all the feature tests you can do with this library. We will do a few more practice examples with Modernizr, and of course, it will be a big component of our RESS project later on in the book. Keeping it efficient For a production environment, I highly recommend taking the build-a-package approach and only downloading a script that contains the tests you will actually use. This way your script is as small as possible. As of right now, the file we used has every test in it; some you may never use. So, to be as efficient as possible (and we want all the efficiency we can get in mobile development), build your file with the tests you'll use or may use. Summary This article provided guidelines on creating a new Web Project in Aptana Studio, creating new folder to the project named js, downloading the Development Version of Mondernizr from the Modernizr download page, and placing the downloaded file into the js folder. Resources for Article : Further resources on this subject: Let's Chat [Article] Blocking versus Non blocking scripts [Article] Building Applications with Spring Data Redis [Article]
Read more
  • 0
  • 0
  • 5445
article-image-inventorying-servers-powershell
Packt
29 Apr 2013
5 min read
Save for later

Inventorying Servers with PowerShell

Packt
29 Apr 2013
5 min read
(For more resources related to this topic, see here.) Inventorying hardware with PowerShell Often times, a system administrator needs to identify what hardware is installed in their environment. This could be for an asset tracking project, finding available resources, or even identifying older equipment that needs to be retired. Most hardware information on a system is stored in WMI and can be accessed via in-built PowerShell functions or via WMI queries. In this recipe, we will review the various methods for gathering inventory information from our local system. In addition to collecting from the local system, these methods can be expanded to include remote systems. How to do it... We can review the various methods for gathering inventory information as follows: Gather disk information from the local system. $TargetSystem="." $myCim = New-CimSession -ComputerName $TargetSystem Get-Disk -CimSession $myCim When executed, the results will be displayed similar to the following screenshot: Review the contents of the Get-Disk function. Get-Content Function:Get-Disk When executed, the contents of the function will be displayed as shown in the following screenshot: Retrieve results using WMI. Get-WmiObject -Class MSFT_DISK ` -Namespace ROOTMicrosoftWindowsStorage When executed, the results will be displayed similar to the following screenshot: How it works... We start by gathering the disk information from the local system. First, we call New-CimSession to create a CIM connection to the target system, in this case we are connecting to the local system, so we can use "." instead of a system name. Next, we call the in-built PowerShell function Get-Disk to return the disk information. By default, PowerShell only returns a subset of information; more can be returned by piping the output through a Select-Object statement and choosing which columns to return. In the second step, we review the contents of the Get-Disk function to learn how it works. Because this command is a function, we can use Get-Content to view the contents of the function. This will return the full content of the script, but in this case we are only interested in the OutputType. In this line, we see that the function retrieves its content from WMI at the ROOTMicrosoftWindowsStorageMSFT_Disk namespace and class. Finally, we query WMI directly using the namespace and class previously identified. To perform this we use Get-WmiObject to search WMI directly. We use the –Namespace switch to connect to the ROOTMicrosoftWindowsStorage namespace. We use the –Class switch to return all objects in the MSFT_Disk class. This information is the same as previously returned, confirming the location is the same. There's more... In addition to the disk values shown here, there are several additional PowerShell commands and WMI locations to report hardware inventory. Only a few of these inventory types have been converted to in-built PowerShell functions, the remainder needs to be queried directly against WMI. Examples of additional counters are as follows: Logical disk Get-Disk -CimSession $myCim Physical disk Get-PhysicalDisk -CimSession $myCim Network adapters Get-NetAdapter -CimSession $myCim System enclosure Get-WmiObject -ComputerName $TargetSystem ` -Class Win32_SystemEnclosure Computer system Get-WmiObject -ComputerName $TargetSystem ` -Class Win32_ComputerSystemProduct Processor Get-WmiObject -ComputerName $TargetSystem -Class Win32_Processor Physical Memory Get-WmiObject -ComputerName $TargetSystem -Class Win32_ PhysicalMemory CD-Rom Get-WmiObject -ComputerName $TargetSystem -Class Win32_CDromDrive Sound card Get-WmiObject -ComputerName $TargetSystem -Class Win32_SoundDevice Video card Get-WmiObject -ComputerName $TargetSystem ` -Class Win32_VideoController BIOS Get-WmiObject -ComputerName $TargetSystem -Class Win32_BIOS Inventorying the installed software In addition to inventorying a system's hardware, it is often necessary to inventory the installed software. There are two primary methods to query the installed software: using the Microsoft Installer, and the Uninstall registry key. These two locations generally return the same information, however as we will see there are different uses for each. How to do it... Complete the following to review the installed software: Get installed features. Get-WindowsFeature | Where-Object Install`State -EQ "Installed" Return software inventory via MSI. Get-WmiObject -Class Win32_Product Open event viewer and review the system event logs. Note the multiple Event ID 1035 messages as shown in the following screenshot: Return inventory via a registry. $HKLM = 2147483650 (([wmiclass]"rootdefault:stdregprov").EnumKey($HKLM, ` "SoftwareMicrosoftWindowsCurrentVersionUninstall")).sNames Return installed patches. Get-WmiObject -Class Win32_QuickFixEngineering How it works... We start by using Get-WindowsFeature to list the features installed in our Windows 2012 Server. This command returns all of the installed features and roles on the current server. If you are unfamiliar with a system, this is a great method to know what Windows services include. In the second step, we use WMI to query the Win32_Product class. This class interacts with the MSI packages on your system and returns a list of all packages currently installed. However, this command should be used with caution as it also causes the MSI packages to be reconfigured, or reset to their default configurations. If we open Event Viewer and review the Application, log on your system after executing this task, we will notice a large number of Event ID 1035. In the fourth step, we use WMI to query the registry and return a list of applications. We start by defining the variable $HKLM and assigning the value 2147483650 which is used by WMI to reference the HKey_Local_Machine registry hive. We then query the results from the SoftwareMicrosoftWindowsCurrentVersionUninstall key. This returns information used by the Programs control panel icon. Often times this list will be different from the previous list because not all applications are installed as MSI packages, and because not all MSI packages appear in the Programs list. Lastly, we return the installed hotfixes. Most Microsoft hotfixes add an entry to the Win32_QuickFixEngineering WMI namespace when they are installed. This provides a quick and simple method to identify which updates are installed on a system.
Read more
  • 0
  • 0
  • 6394

article-image-creating-custom-hud
Packt
29 Apr 2013
5 min read
Save for later

Creating a Custom HUD

Packt
29 Apr 2013
5 min read
(For more resources related to this topic, see here.) Mission Briefing In this project we will be creating a HUD that can be used within a Medieval RPG and that will fit nicely into the provided Epic Citadel map, making use of Scaleform and ActionScript 3.0 using Adobe Flash CS6. As usual, we will be following a simple step—by—step process from beginning to end to complete the project. Here is the outline of our tasks: Setting up Flash Creating our HUD Importing Flash files into UDK Setting up Flash Our first step will be setting up Flash in order for us to create our HUD. In order to do this, we must first install the Scaleform Launcher. Prepare for Lift Off At this point, I will assume that you have run Adobe Flash CS6 at least once beforehand. If not, you can skip this section to where we actually import the .swf file into UDK. Alternatively, you can try to use some other way to create a Flash animation, such as FlashDevelop, Flash Builder, or SlickEdit; but that will have to be done on your own. Engage Thrusters The first step will be to install the Scaleform Launcher. The launcher will make it very easy for us to test our Flash content using the GFX hardware—accelerated Flash Player, which is what UDK will use to play it. Let's get started. Open up Adobe Flash CS6 Professional. Once the program starts up, open up Adobe Extension Manager by going to Help | Manage Extensions.... You may see the menu say Performing configuration tasks, please wait.... This is normal; just wait for it to bring up the menu as shown in the following screenshot: Click on the Install option from the top menu on the right—hand side of the screen. In the file browser, locate the path of your UDK installation and then go into the BinariesGFxCLICK Tools folder. Once there, select the ScaleformExtensions.mxp file and then select OK. When the agreement comes up, press the Accept button; then select whether you want the program to be installed for just you or everyone on your computer. If Flash is currently running, you should get a window popping up telling you that the program will not be ready until you restart the program. Close the manager and restart the program. With your reopened version of Flash start up the Scaleform Launcher by clicking on Window | Other Panels | Scaleform Launcher. At this point you should see the Scaleform Launcher panel come up as shown in the following screenshot: At this point all of the options are grayed out as it doesn't know how to access the GFx player, so let's set that up now. Click on the + button to add a new profile. In the profile name section, type in GFXMediaPlayer. Next, we need to reference the GFx player. Click on the + button in the player EXE section. Go to your UDK directory, BinariesGFx, and then select GFxMediaPlayerD3d9.exe. It will then ask you to give a name for the Player Name field with the value already filled in; just hit the OK button. UDK by default uses DirectX 9 for rendering. However, since GDC 2011, it has been possible for users to use DirectX 11. If your project is using 11, feel free to check out http://udn.epicgames.com/Three/DirectX11Rendering.html and use DX11. In order to test our game, we will need to hit the button that says Test with: GFxMediaPlayerD3d9 as shown in the following screenshot: If you know the resolution in which you want your final game to be, you can set up multiple profiles to preview how your UI will look at a specific resolution. For example, if you'd like to see something at a resolution of 960 x 720, you can do so by altering the command params field after %SWF PATH% to include the text —res 960:720. Now that we have the player loaded, we need to install the CLIK library for our usage. Go to the Preferences menu by selecting Edit | Preferences. Click on the ActionScript tab and then click on the ActionScript 3.0 Settings... button. From there, add a new entry to our Source path section by clicking on the + button. After that, click on the folder icon to browse to the folder we want. Add an additional path to our CLIK directory in the file explorer by first going to your UDK installation directory and then going to DevelopmentFlashAS3CLIK. Click on the OK button and drag—and—drop the newly created Scaleform Launcher to the bottom—right corner of the interface. Objective Complete — Mini Debriefing Alright, Flash is now set up for us to work with Scaleform within it, which for all intents and purposes is probably the hardest part about working with Scaleform. Now that we have taken care of it, let's get started on the HUD! As long as you have administrator access to your computer, these settings should be set for whenever you are working with Flash. However, if you do not, you will have to run through all of these settings every time you want to work on Scaleform projects.
Read more
  • 0
  • 0
  • 14668
Modal Close icon
Modal Close icon