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

How-To Tutorials

7019 Articles
article-image-enterprise-geodatabase
Packt
25 Jun 2014
5 min read
Save for later

Enterprise Geodatabase

Packt
25 Jun 2014
5 min read
(For more resources related to this topic, see here.) Creating a connection to the enterprise geodatabase A geodatabase connection is a channel that is established between ArcGIS and the enterprise geodatabase. To create a connection, we need to specify the database server and the user credentials. Without this information, we will not be able to create a connection. To create a geodatabase connection using the SDE user, perform the following steps: Open ArcCatalog and expand the Database Connections dialog from the Catalog Tree window. Double-click on Add Database Connection. From the Database Platform drop-down list, select the database; ours is SQL Server. In the Instance field, type the name of the server; here, it is GDBServer. Select the Database authentication option from the Authentication Type drop-down list and type in the SDE credentials. Click on the Database drop-down list. This should be populated automatically as you leave the password field. Select your geodatabase. Click on OK and rename the connection to sde@gdbserver. This is illustrated in the following screenshot: The type of geodatabase connection depends on the roles assigned to the user. Connecting with the sde user will grant you full access to the geodatabase, where you can copy, delete, and change almost anything. Create four more database connections with the users Robb, Joffrey, Tyrion, and Dany. Give them proper names so we can use them later. Migrating a file geodatabase to an enterprise geodatabase We have our enterprise geodatabase. You might have created a few feature classes and tables. But eventually, our clients at Belize need to start working on the new geodatabase. So, we need to migrate the Bestaurants_new.gdb file to this enterprise geodatabase. This can be done with a simple copy and paste operation. Note that these steps work in the exact same way on any other DBMS once it is set up. You can copy and paste from a file geodatabase to any enterprise geodatabase using the following steps: Open ArcCatalog and browse to your Bestaurants_new.gdb geodatabase. Right-click on the Food_and_Drinks feature class and select Copy, as seen in the following screenshot: Now, browse and connect to sde@gdbserver; right-click on an empty area and click on Paste, as seen in the following screenshot: You will be prompted with a list of datasets that will be copied as shown in the following screenshot. Luckily, all the configurations will be copied. This includes domains, subtypes, feature classes, and related tables as follows: After the datasets and configurations have been copied, you will see all your data in the new geodatabase. Note that in an SQL Server enterprise geodatabase, there are two prefixes added to each dataset. First, the database is added, which is sdedb, followed by the schema, which is SDE, and finally the dataset name, as shown in the following screenshot: Assigning privileges Have you tried to connect as Robb or Tyrion to your new geodatabase? If you haven't, try it now. You will see that none of the users you created have access to the Food_and_Drinks feature class or any other dataset. You might have guessed why. That is because SDE has created this data, and only this user can allow other users to see this data. So, how do we allow users to see other users' datasets? This is simple just perform the following steps: From ArcCatalog, connect as sde@gdbserver. Right-click on the sdedb.SDE.Food_and_Drinks feature class, point the cursor to Manage, and then click on Privileges as shown in the following screenshot: In the Privileges... dialog, click on Add. Select all four users, Robb, Joffrey, Tyrion, and Dany, and click on OK. Make sure that the Select checkbox is checked for all four users, which means they can see and read this feature class. For Dany, assign Insert, Update, and Delete so that she can also edit this feature class, as shown in the following screenshot. Apply the same privileges to all other datasets as follows and click on OK. Try connecting with Robb; you will now be able to view all datasets. You can use Dany's account to edit your geodatabase using ArcMap. You can create more viewer users who have read-only access to your geodatabase but cannot edit or modify it in any way. Summary Enterprise geodatabases are an excellent choice when you have a multiuser environment. In this article, you learned how to create a geodatabase connection using ArcCatalog to the new enterprise geodatabase. You also learned to migrate your file geodatabase into a fresh enterprise geodatabase. Finally, you learned to assign different privileges to each user and access control to your new enterprise geodatabase. While setting up and configuring an enterprise geodatabase is challenging, working with the enterprise geodatabases in ArcCatalog and ArcMap is similar to working with file geodatabases. Thus, in this article, we took a leap by using an upgraded version of a geodatabase, which is called an enterprise geodatabase. Resources for Article: Further resources on this subject: Server Logs [Article] Google Earth, Google Maps and Your Photos: a Tutorial [Article] Including Google Maps in your Posts Using Apache Roller 4.0 [Article]
Read more
  • 0
  • 0
  • 2723

article-image-adding-newsletters-web-site-using-drupal-6
Packt
22 Oct 2009
4 min read
Save for later

Adding Newsletters to a Web Site Using Drupal 6

Packt
22 Oct 2009
4 min read
Creating newsletters A newsletter is a great way of keeping customers up-to-date without them needing to visit your web site. Customers appreciate well-designed newsletters because they allow the customer to keep tabs on their favorite places without needing to check every web site on a regular basis. Creating a newsletter Good Eatin' Goal: Create a new newsletter on the Good Eatin' site, which will contain relevant news about the restaurant, and will be delivered quarterly to subscribers. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps Newsletters are containers for individual issues. For example, you could have a newsletter called Seasonal Dining Guide, which would have four issues per year (Summer, Fall, Winter, and Spring). A customer subscribes to the newsletter and each issue is sent to them as it becomes available. Begin by installing and activating the Simplenews module, as shown below: At this point, we only need to enable the Simplenews module, and the Simplenews action module can be left disabled. Next, select Content management and then Newsletters, from the Administer menu. Drupal will display an administration area divided into the following sections: a) Sent issuesb) Draftsc) Newslettersd) Subscriptions Click on the Newsletters tab and Drupal will display a page similar to the following: As you can see, a default newsletter with the name of our site has been automatically created for us. We can either edit this default newsletter or click on the Add newsletter link to create a new newsletter. Let's click the Add newsletter option to create our seasonal newsletter. Drupal will display a standard form where we can enter the name, description, and relative importance (relative importance weight) of the newsletter. Click Save to save the newsletter. It will now appear in the list of available newsletters. If you want to modify the Sender information for the newsletter to use an alternate name or email address to your site's default ones, you can either expand the Sender information section when adding the newsletter, or you click Edit newsletter and modify the Sender information, as shown in the following screenshot: Allowing users to sign-up for the newsletter Good Eatin' Goal: Demonstrate how registered and unregistered users can sign-up for a newsletter, and configure the registration process. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps To allow customers to sign-up for the newsletter, we will begin by adding a block to the page. Open the Block Manager by selecting Site building and then Blocks, from the Administer menu. Add the block for the newsletter that you want to allow customers to subscribe to, as shown in the following screenshot: We will now need to give users permission to subscribe to newsletters by selecting User management and then Permissions, from the Administer menu. We will give all users permissions to subscribe to newsletters and to view newsletter links, as shown below: If the customer does not have permission to subscribe to newsletters then the block will appear as shown in the following screenshot: However, if the customer has permissions to subscribe to newsletters, and is logged in to the site, the block will appear as shown in the following screenshot: If the customer has permission to subscribe, but is not logged in, the block will appear as follows: To subscribe to the newsletter, the customer will simply click on the Subscribe button. Once they he subscribed, the Subscribe button will change to Unsubscribe so that the user can easily opt out of the newsletter. If the user does not have an active account with the site, they will need to confirm that they want to subscribe to the site.
Read more
  • 0
  • 0
  • 2721

article-image-grouping-sets-advanced-sql
Packt
20 Jun 2017
6 min read
Save for later

Grouping Sets in Advanced SQL

Packt
20 Jun 2017
6 min read
In this article by Hans JurgenSchonig, the author of the book Mastering PostgreSQL 9.6, we will learn about advanced SQL. Introducing grouping sets Every advanced user of SQL should be familiar with GROUP BY and HAVING clauses. But are you also aware of CUBE, ROLLUP, and GROUPING SETS? If not this articlemight be worth reading for you. Loading some sample data To make this article a pleasant experience for you, I have compiled some sample data, which has been taken from the BP energy report at http://www.bp.com/en/global/corporate/energy-economics/statistical-review-of-world-energy.html. Here is the data structure, which will be used: test=# CREATE TABLE t_oil ( region text, country text, year int, production int, consumption int ); CREATE TABLE The test data can be downloaded from our website using curl directly: test=# COPY t_oil FROM PROGRAM 'curl www.cybertec.at/secret/oil_ext.txt'; COPY 644 On some operating systems curl is not there by default or has not been installed so downloading the file before might be the easier option for many people. All together there is data for 14 nations between 1965 and 2010, which are in two regions of the world: test=# SELECT region, avg(production) FROM t_oil GROUP BY region; region | avg ---------------+--------------------- Middle East | 1992.6036866359447005 North America | 4541.3623188405797101 (2 rows) Applying grouping sets The GROUP BY clause will turn many rows into one row per group. However, if you do reporting in real life, you might also be interested in the overall average. One additional line might be needed. Here is how this can be achieved: test=# SELECT region, avg(production) FROM t_oil GROUP BY ROLLUP (region); region | avg ---------------+----------------------- Middle East | 1992.6036866359447005 North America | 4541.3623188405797101 | 2607.5139860139860140 (3 rows) The ROLLUP clause will inject an additional line, which will contain the overall average. If you do reporting it is highly likely that a summary line will be needed. Instead of running two queries, PostgreSQL can provide the data running just a single query. Of course this kind of operation can also be used if you are grouping by more than just one column: test=# SELECT region, country, avg(production) FROM t_oil WHERE country IN ('USA', 'Canada', 'Iran', 'Oman') GROUP BY ROLLUP (region, country); region | country | avg ---------------+---------+----------------------- Middle East | Iran | 3631.6956521739130435 Middle East | Oman | 586.4545454545454545 Middle East | | 2142.9111111111111111 North America | Canada | 2123.2173913043478261 North America | USA | 9141.3478260869565217 North America | | 5632.2826086956521739 | | 3906.7692307692307692 (7 rows) In this example, PostgreSQL will inject three lines into the result set. One line will be injected for Middle East, one for North America. On top of that we will get a line for the overall averages. If you are building a web application the current result is ideal because you can easily build a GUI to drill into the result set by filtering out the NULL values. The ROLLUPclause is nice in case you instantly want to display a result. I always used it to display final results to end users. However, if you are doing reporting, you might want to pre-calculate more data to ensure more flexibility. The CUBEkeyword is what you might have been looking for: test=# SELECT region, country, avg(production) FROM t_oil WHERE country IN ('USA', 'Canada', 'Iran', 'Oman') GROUP BY CUBE (region, country); region | country | avg ---------------+---------+----------------------- Middle East | Iran | 3631.6956521739130435 Middle East | Oman | 586.4545454545454545 Middle East | | 2142.9111111111111111 North America | Canada | 2123.2173913043478261 North America | USA | 9141.3478260869565217 North America | | 5632.2826086956521739 | | 3906.7692307692307692 | Canada | 2123.2173913043478261 | Iran | 3631.6956521739130435 | Oman | 586.4545454545454545 | USA | 9141.3478260869565217 (11 rows) Note that even more rows have been added to the result. The CUBEwill create the same data as: GROUP BY region, country + GROUP BY region + GROUP BY country + the overall average. So the whole idea is to extract many results and various levels of aggregation at once. The resulting cube contains all possible combinations of groups. The ROLLUP and CUBE are really just convenience features on top of GROUP SETS. With the GROUPING SETS clause you can explicitly list the aggregates you want: test=# SELECT region, country, avg(production) FROM t_oil WHERE country IN ('USA', 'Canada', 'Iran', 'Oman') GROUP BY GROUPING SETS ( (), region, country); region | country | avg ---------------+---------+----------------------- Middle East | | 2142.9111111111111111 North America | | 5632.2826086956521739 | | 3906.7692307692307692 | Canada | 2123.2173913043478261 | Iran | 3631.6956521739130435 | Oman | 586.4545454545454545 | USA | 9141.3478260869565217 (7 rows) In this I went for three grouping sets: The overall average, GROUP BY region and GROUP BY country. In case you want region and country combined, use (region, country). Investigating performance Grouping sets are a powerful feature, which help to reduce the number of expensive queries. Internally,PostgreSQL will basically turn to traditional GroupAggregates to make things work. A GroupAggregate node requires sorted data so be prepared that PostgreSQL might do a lot of temporary sorting: test=# explain SELECT region, country, avg(production) FROM t_oil WHERE country IN ('USA', 'Canada', 'Iran', 'Oman') GROUP BY GROUPING SETS ( (), region, country); QUERY PLAN --------------------------------------------------------------- GroupAggregate (cost=22.58..32.69 rows=34 width=52) Group Key: region Group Key: () Sort Key: country Group Key: country -> Sort (cost=22.58..23.04 rows=184 width=24) Sort Key: region ->Seq Scan on t_oil (cost=0.00..15.66 rows=184 width=24) Filter: (country = ANY ('{USA,Canada,Iran,Oman}'::text[])) (9 rows) Hash aggregates are only supported for normal GROUP BY clauses involving no grouping sets. According to the developer of grouping sets (AtriShama), adding support for hashes is not worth the effort so it seems PostgreSQL already has an efficient implementation even if the optimizer has fewer choices than it has with normal GROUP BY statements. Combining grouping sets with the FILTER clause In real world applications grouping sets can often be combined with so called FILTER clauses. The idea behind FILTER is to be able to run partial aggregates. Here is an example: test=# SELECT region, avg(production) AS all, avg(production) FILTER (WHERE year < 1990) AS old, avg(production) FILTER (WHERE year >= 1990) AS new FROM t_oil GROUP BY ROLLUP (region); region | all | old | new ---------------+----------------+----------------+---------------- Middle East | 1992.603686635 | 1747.325892857 | 2254.233333333 North America | 4541.362318840 | 4471.653333333 | 4624.349206349 | 2607.513986013 | 2430.685618729 | 2801.183150183 (3 rows) The idea here is that not all columns will use the same data for aggregation. The FILTER clauses allow you to selectively pass data to those aggregates. In my example, the second aggregate will only consider data before 1990 while the second aggregate will take care of more recent data. If it is possible to move conditions to a WHERE clause it is always more desirable as less data has to be fetched from the table. The FILTERis only useful if the data left by the WHERE clause is not needed by each aggregate. The FILTER works for all kinds of aggregates and offers a simple way to pivot your data. Summary We have learned about advanced feature provided by SQL. On top of the simple aggregates,PostgreSQL provides, grouping sets to create custom aggregates.  Resources for Article: Further resources on this subject: PostgreSQL in Action [article] PostgreSQL as an Extensible RDBMS [article] Recovery in PostgreSQL 9 [article]
Read more
  • 0
  • 0
  • 2721

article-image-modifying-system-using-microsoft-dynamics-nav-2009-part-1
Packt
06 Oct 2009
7 min read
Save for later

Modifying the System using Microsoft Dynamics Nav 2009: Part 1

Packt
06 Oct 2009
7 min read
"The best investment is in the tools of one's own trade." Benjamin Franklin Understanding the tools Have you ever held a chainsaw in your hands? Go try it, hear it roar. Quite a beast, eh? Now, what can you do with it? Was felling timber the first image that popped up? We had something else in mind. Have you ever seen any of those ice sculptures? Did you know that sculptors often use chainsaws to carve them out? Carving them slowly over days with fine tools is often not an option—the ice can start melting in a matter of minutes. To be able to finish in time before physics takes over, power tools must be used, and specially equipped chainsaws have been selected as a tool of choice of many ice carvers. Modifying a big system, one like Microsoft Dynamics NAV 2009, requires a lot of skill, knowledge, and experience. While skill and experience can't be learned from a book, knowledge for the better part of it can. There are two kinds of knowledge: the knowledge of the tools, and the knowledge of the product. If you only know the tools, and don't know the object you will work on with these tools, you can easily mess up. If you only know the product, but don't know the tools, you are missing many opportunities. When you know the tools, and what they can do, and how the product will behave when it has been touched, you are on the right path. If you are an application consultant, and you know the product and how it works, but haven't ever dared to open it up in Object Designer and shape it to your liking, this chapter is for you. You already have the knowledge of the product, what it is and how it works; you only need the knowledge of the tools to become a true artist. A chainsaw artist, if you wish. The tools you are about to master are quite powerful: they can craft beautifully architectured state-of-the-art solutions, or they can leave a complete mess. Let's become artists. Modifications for non-programmers In Microsoft Dynamics NAV 2009, it is possible to create a fully functioning modification without really writing a single line of code. As a matter of fact, it happens quite often. Often, customers will demand changes that are simple in nature: adding a field to a report, or rearranging the screen elements. You don't need to be a programmer to be able to accomplish that mission. Microsoft Dynamics NAV comes with a comprehensive set of tools aimed at modifying the solution and every aspect of it, from the data model, via business logic, all the way to the user interface. Many steps along this way can be done without any programming knowledge. Let's take a look at what can be done without writing code: Extending the data model: Application data is stored in tables, which are specifically designed to store exactly that information which is required by the application, no more, no less. When your customer presents you with new requirements, these will often spawn many changes to the underlying data model, to accommodate all those types of information that weren't originally supposed to be stored, because nobody knew they existed. You can do all of these data model modifications using special data design tools, without writing any code. True, some business logic is usually associated with data, so called business rules, but these should be written much later, after the model has been completed. Modifying the user interface: To put a functional user interface together requires a good understanding of the underlying data model, and of various user interface controls that can be put on screen, what they can do, and what they can't. You can compose hundreds of fully functional data-enabled pages or forms, and establish complex navigation rules between them, without ever coming anywhere close to the C/AL code editor. Reporting: Again, to compose reports mainly requires good knowledge of the underlying data, and the knowledge of tools. While some complex reports may require extensive coding, the vast majority of reports will be prepared by simply laying out fields in the report designer. Data import and export: When data needs to go in and out of the system, you can reach for built-in development tools that can create data migration objects in a matter of minutes. One of those times when knowing how to shape the system matters, while coding doesn't at all, is prototyping. Imagine how quickly you could get the requirements straight with a customer if you were able to quickly compose a usable user interface prototype! Object Designer basics All of the development in Microsoft Dynamics NAV is done through the Object Designer feature of the Classic client. To invoke the Object Designer from anywhere within the application, simply press Shift+F12, or go to main menu, click Tools, then Object Designer. It looks like the following screenshot: To the left there is a series of buttons, which you can use to switch between the lists of objects of various types: Type   Description   Tables are used to store information in the system.   Forms are used to provide access to information by displaying it on screen and allowing data entry and modification. Forms can only be used by Classic client.   Reports are primarily used to display information in printable form, but can also be used to execute batch jobs.   Dataports are used to export and import information to and from the system in fixed width or variable length text format.   Dataports on steroids, XMLports are RoleTailored and can get information into or out of the system in XML and text format. XMLports can also be used to automate communication with external application in a way transparent to the users, such as with Business Notifications functionality.   Codeunits contain blocks of application code: the part of the system popularly called business logic.   MenuSuites define what the navigation pane in Classic client and the Departments page in the RoleTailored client look like.   Pages are the forms of the RoleTailored client: they are used to present the information to users and provide means for data entry using RoleTailored or any other service-tier clients (such as SharePoint client).   On the right, there is a table displaying all the objects of the selected type. The following columns are on show: Column Description Type This is actually displayed as an icon, which can represent any of the eight object types described in the previous table. ID An integer number representing the unique identifier of an object. Every object in the system is uniquely distinguished from every other by its type and ID. Name A textual identifier of the object, which has to be unique for each object type. You typically refer to objects by their names when you are declaring C/AL variables. Caption A localized version of the name, aware of the multi-language capabilities of Microsoft Dynamics NAV. Modified Tells if the object was modified. Upon saving, every object will automatically get a checkmark in this field. Version List A textual list of version tags, explaining which product releases, add-ons, or customizations have changed the object. Date Date of the last save operation in Object Designer. Time Time of the last save operation in Object Designer. BLOB Size Size of BLOB representation of the object in the database. The definition, and for all compiled objects an executable version of it, are saved in the database. This makes for a very portable solution, where the database is, so are the application objects. Compiled Flag that tells if the object was compiled, either during the last save operation, or manually by calling the Compile command. Only compiled objects can be executed. On the bottom right, you have a few basic command buttons: New to create a new object of the selected type, Design to open an existing one, Run to execute the selected object, and Help to answer any questions that we might come across in the process of modifying the system.
Read more
  • 0
  • 0
  • 2721

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

Date and Calendar Module in Drupal 5: Part 1

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

article-image-designing-jasmine-tests-spies
Packt
22 Apr 2015
17 min read
Save for later

Designing Jasmine Tests with Spies

Packt
22 Apr 2015
17 min read
In this article by Munish Sethi, author of the book Jasmine Cookbook, we will see the implementation of Jasmine tests using spies. (For more resources related to this topic, see here.) Nowadays, JavaScript has become the de facto programming language to build and empower frontend/web applications. We can use JavaScript to develop simple or complex applications. However, applications in production are often vulnerable to bugs caused by design inconsistencies, logical implementation errors, and similar issues. Due to this, it is usually difficult to predict how applications will behave in real-time environments, which leads to unexpected behavior, nonavailability of applications, or outage for shorter/longer durations. This generates lack of confidence and dissatisfaction among application users. Also, high cost is often associated with fixing the production bugs. Therefore, there is a need to develop applications with high quality and high availability. Jasmine is a Behavior-Driven development (BDD) framework for testing JavaScript code both in browser and on server side. It plays a vital role to establish effective development process by applying efficient testing processes. Jasmine provides a rich set of libraries to design and develop Jasmine specs (unit tests) for JavaScript (or JavaScript enabled) applications. In this article, we will see how to develop specs using Jasmine spies and matchers. We will also see how to write Jasmine specs with the Data-Driven approach using JSON/HTML fixture from end-to-end (E2E) perspective. Let's understand the concept of mocks before we start developing Jasmine specs with spies. Generally, we write one unit test corresponding to a Jasmine spec to test a method, object, or component in isolation, and see how it behaves in different circumstances. However, there are situations where a method/object has dependencies on other methods or objects. In this scenario, we need to design tests/specs across the unit/methods or components to validate behavior or simulate a real-time scenario. However, due to nonavailability of dependent methods/objects or staging/production environment, it is quite challenging to write Jasmine tests for methods that have dependencies on other methods/objects. This is where Mocks come into the picture. A mock is a fake object that replaces the original object/method and imitates the behavior of the real object without going into the nitty-gritty or creating the real object/method. Mocks work by implementing the proxy model. Whenever, we create a mock object, it creates a proxy object, which replaces the real object/method. We can then define the methods that are called and their returned values in our test method. Mocks can then be utilized to retrieve some of the runtime statistics, as follows: How many times was the mocked function/object method called? What was the value that the function returned to the caller? With how many arguments was the function called? Developing Jasmine specs using spies In Jasmine, mocks are referred to as spies. Spies are used to mock a function/object method. A spy can stub any function and track calls to it and all its arguments. Jasmine provides a rich set of functions and properties to enable mocking. There are special matchers to interact with spies, that is, toHaveBeenCalled and toHaveBeenCalledWith. Now, to understand the preceding concepts, let's assume that you are developing an application for a company providing solutions for the healthcare industry. Currently, there is a need to design a component that gets a person's details (such as name, age, blood group, details of diseases, and so on) and processes it further for other usage. Now, assume that you are developing a component that verifies a person's details for blood or organ donation. There are also a few factors or biological rules that exist to donate or receive blood. For now, we can consider the following biological factors: The person's age should be greater than or equal to 18 years The person should not be infected with HIV+ Let's create the validate_person_eligibility.js file and consider the following code in the current context: var Person = function(name, DOB, bloodgroup, donor_receiver) {    this.myName = name; this.myDOB = DOB; this.myBloodGroup = bloodgroup; this.donor_receiver = donor_receiver; this.ValidateAge    = function(myDOB){     this.myDOB = myDOB || DOB;     return this.getAge(this.myDOB);    };    this.ValidateHIV   = function(personName,personDOB,personBloodGroup){     this.myName = personName || this.myName;     this.myDOB = personDOB || this.myDOB;     this.myBloodGroup = personBloodGroup || this.myBloodGroup;     return this.checkHIV(this.myName, this.myDOB, this.myBloodGroup);    }; }; Person.prototype.getAge = function(birth){ console.log("getAge() function is called"); var calculatedAge=0; // Logic to calculate person's age will be implemented later   if (calculatedAge<18) {    throw new ValidationError("Person must be 18 years or older"); }; return calculatedAge; }; Person.prototype.checkHIV = function(pName, pDOB, pBloodGroup){ console.log("checkHIV() function is called"); bolHIVResult=true; // Logic to verify HIV+ will be implemented later   if (bolHIVResult == true) {    throw new ValidationError("A person is infected with HIV+");   }; return bolHIVResult; };   // Define custom error for validation function ValidationError(message) { this.message = message; } ValidationError.prototype = Object.create(Error.prototype); In the preceding code snapshot, we created an object Person, which accepts four parameters, that is, name of the person, date of birth, the person's blood group, and the donor or receiver. Further, we defined the following functions within the person's object to validate biological factors: ValidateAge(): This function accepts an argument as the date of birth and returns the person's age by calling the getAge function. You can also notice that under the getAge function, the code is not developed to calculate the person's age. ValidateHIV(): This function accepts three arguments as name, date of birth, and the person's blood group. It verifies whether the person is infected with HIV or not by calling the checkHIV function. Under the function checkHIV, you can observe that code is not developed to check whether the person is infected with HIV+ or not. Next, let's create the spec file (validate_person_eligibility_spec.js) and code the following lines to develop the Jasmine spec, which validates all the test conditions (biological rules) described in the previous sections: describe("<ABC> Company: Health Care Solution, ", function() { describe("When to donate or receive blood, ", function(){    it("Person's age should be greater than " +        "or equal to 18 years", function() {      var testPersonCriteria = new Person();      spyOn(testPersonCriteria, "getAge");      testPersonCriteria.ValidateAge("10/25/1990");      expect(testPersonCriteria.getAge).toHaveBeenCalled();      expect(testPersonCriteria.getAge).toHaveBeenCalledWith("10/25/1990");    });    it("A person should not be " +        "infected with HIV+", function() {      var testPersonCriteria = new Person();      spyOn(testPersonCriteria, "checkHIV");      testPersonCriteria.ValidateHIV();      expect(testPersonCriteria.checkHIV).toHaveBeenCalled();    }); }); }); In the preceding snapshot, we mocked the functions getAge and checkHIV using spyOn(). Also, we applied the toHaveBeenCalled matcher to verify whether the function getAge is called or not. Let's look at the following pointers before we jump to the next step: Jasmine provides the spyOn() function to mock any JavaScript function. A spy can stub any function and track calls to it and to all arguments. A spy only exists in the describe or it block; it is defined, and will be removed after each spec. Jasmine provides special matchers, toHaveBeenCalled and toHaveBeenCalledWith, to interact with spies. The matcher toHaveBeenCalled returns true if the spy was called. The matcher toHaveBeenCalledWith returns true if the argument list matches any of the recorded calls to the spy. Let's add the reference of the validate_person_eligibility.js file to the Jasmine runner (that is, SpecRunner.html) and run the spec file to execute both the specs. You will see that both the specs are passing, as shown in the following screenshot: While executing the Jasmine specs, you can notice that log messages, which we defined under the getAge() and checkHIV functions, are not printed in the browser console window. Whenever, we mock a function using Jasmine's spyOn() function, it replaces the original method of the object with a proxy method. Next, let's consider a situation where the function <B> is called under the function <A>, which is mocked in your test. Due to the mock behavior, it creates a proxy object that replaces the function <A>, and function <B> will never be called. However, in order to pass the test, it needs to be executed. In this situation, we chain the spyOn() function with .and.callThrough. Let's consider the following test code: it("Person's age should be greater than " +    "or equal to 18 years", function() { var testPersonCriteria = new Person(); spyOn(testPersonCriteria, "getAge").and.callThrough(); testPersonCriteria.ValidateAge("10/25/1990"); expect(testPersonCriteria.getAge).toHaveBeenCalled(); expect(testPersonCriteria.getAge).toHaveBeenCalledWith("10/25/1990"); }); Whenever the spyOn() function is chained with and.callThrough, the spy will still track all calls to it. However, in addition, it will delegate the control back to the actual implementation/function. To see the effect, let's run the spec file check_person_eligibility_spec.js with the Jasmine runner. You will see that the spec is failing, as shown in the following screenshot: This time, while executing the spec file, you can notice that a log message (that is, getAge() function is called) is also printed in the browser console window. On the other hand, you can also define your own logic or set values in your test code as per specific requirements by chaining the spyOn() function with and.callFake. For example, consider the following code: it("Person's age should be greater than " +    "or equal to 18 years", function() { var testPersonCriteria = new Person(); spyOn(testPersonCriteria, "getAge").and.callFake(function()      {    return 18; }); testPersonCriteria.ValidateAge("10/25/1990"); expect(testPersonCriteria.getAge).toHaveBeenCalled(); expect(testPersonCriteria.getAge).toHaveBeenCalledWith("10/25/1990"); expect(testPersonCriteria.getAge()).toEqual(18); }); Whenever the spyOn() function is chained with and.callFake, all calls to the spy will be delegated to the supplied function. You can also notice that we added one more expectation to validate the person's age. To see execution results, run the spec file with the Jasmine runner. You will see that both the specs are passing: Implementing Jasmine specs using custom spy method In the previous section, we looked at how we can spy on a function. Now, we will understand the need of custom spy method and how Jasmine specs can be designed using it. There are several cases when one would need to replace the original method. For example, original function/method takes a long time to execute or it depends on the other method/object (or third-party system) that is/are not available in the test environment. In this situation, it is beneficial to replace the original method with a fake/custom spy method for testing purpose. Jasmine provides a method called jasmine.createSpy to create your own custom spy method. As we described in the previous section, there are few factors or biological rules that exist to donate or receive bloods. Let's consider few more biological rules as follows: Person with O+ blood group can receive blood from a person with O+ blood group Person with O+ blood group can give the blood to a person with A+ blood group First, let's update the JavaScript file validate_person_eligibility.js and add a new method ValidateBloodGroup to the Person object. Consider the following code: this.ValidateBloodGroup   = function(callback){ var _this = this; var matchBloodGroup; this.MatchBloodGroupToGiveReceive(function (personBloodGroup) {    _this.personBloodGroup = personBloodGroup;    matchBloodGroup = personBloodGroup;    callback.call(_this, _this.personBloodGroup); }); return matchBloodGroup; };   Person.prototype.MatchBloodGroupToGiveReceive = function(callback){ // Network actions are required to match the values corresponding // to match blood group. Network actions are asynchronous hence the // need for a callback. // But, for now, let's use hard coded values. var matchBloodGroup; if (this.donor_receiver == null || this.donor_receiver == undefined){    throw new ValidationError("Argument (donor_receiver) is missing "); }; if (this.myBloodGroup == "O+" && this.donor_receiver.toUpperCase() == "RECEIVER"){    matchBloodGroup = ["O+"]; }else if (this.myBloodGroup == "O+" && this.donor_receiver.toUpperCase() == "DONOR"){    matchBloodGroup = ["A+"]; }; callback.call(this, matchBloodGroup); }; In the preceding code snapshot, you can notice that the ValidateBloodGroup() function accepts an argument as the callback function. The ValidateBloodGroup() function returns matching/eligible blood group(s) for receiver/donor by calling the MatchBloodGroupToGiveReceive function. Let's create the Jasmine tests with custom spy method using the following code: describe("Person With O+ Blood Group: ", function(){ it("can receive the blood of the " +      "person with O+ blood group", function() {    var testPersonCriteria = new Person("John Player", "10/30/1980", "O+", "Receiver");    spyOn(testPersonCriteria, "MatchBloodGroupToGiveReceive").and.callThrough();    var callback = jasmine.createSpy();    testPersonCriteria.ValidateBloodGroup(callback);    //Verify, callback method is called or not    expect(callback).toHaveBeenCalled();    //Verify, MatchBloodGroupToGiveReceive is    // called and check whether control goes back    // to the function or not    expect(testPersonCriteria.MatchBloodGroupToGiveReceive).toHaveBeenCalled();    expect(testPersonCriteria.MatchBloodGroupToGiveReceive.calls.any()).toEqual(true);        expect(testPersonCriteria.MatchBloodGroupToGiveReceive.calls.count()).toEqual(1);    expect(testPersonCriteria.ValidateBloodGroup(callback)).toContain("O+"); }); it("can give the blood to the " +      "person with A+ blood group", function() {    var testPersonCriteria = new Person("John Player", "10/30/1980", "O+", "Donor");    spyOn(testPersonCriteria, "MatchBloodGroupToGiveReceive").and.callThrough();    var callback = jasmine.createSpy();    testPersonCriteria.ValidateBloodGroup(callback);    expect(callback).toHaveBeenCalled();    expect(testPersonCriteria.MatchBloodGroupToGiveReceive).toHaveBeenCalled();    expect(testPersonCriteria.ValidateBloodGroup(callback)).toContain("A+"); }); }); You can notice that in the preceding snapshot, first we mocked the function MatchBloodGroupToGiveReceive using spyOn() and chained it with and.callThrough() to hand over the control back to the function. Thereafter, we created callback as the custom spy method using jasmine.createSpy. Furthermore, we are tracking calls/arguments to the callback and MatchBloodGroupToGiveReceive functions using tracking properties (that is, .calls.any() and .calls.count()). Whenever we create a custom spy method using jasmine.createSpy, it creates a bare spy. It is a good mechanism to test the callbacks. You can also track calls and arguments corresponding to custom spy method. However, there is no implementation behind it. To execute the tests, run the spec file with the Jasmine runner. You will see that all the specs are passing: Implementing Jasmine specs using Data-Driven approach In Data-Driven approach, Jasmine specs get input or expected values from the external data files (JSON, CSV, TXT files, and so on), which are required to run/execute tests. In other words, we isolate test data and Jasmine specs so that one can prepare the test data (input/expected values) separately as per the need of specs. For example, in the previous section, we provided all the input values (that is, name of person, date of birth, blood group, donor or receiver) to the person's object in the test code itself. However, for better management, it's always good to maintain test data and code/specs separately. To implement Jasmine tests with the data-driven approach, let's create a data file fixture_input_data.json. For now, you can use the following data in JSON format: [ { "Name": "John Player", "DOB": "10/30/1980", "Blood_Group": "O+", "Donor_Receiver": "Receiver" }, { "Name": "John Player", "DOB": "10/30/1980", "Blood_Group": "O+", "Donor_Receiver": "Donor" } ] Next, we will see how to provide all the required input values in our tests through a data file using the jasmine-jquery plugin. Before we move to the next step and implement the Jasmine tests with the Data-Driven approach, let's note the following points regarding the jasmine-jquery plugin: It provides two extensions to write the tests with HTML and JSON fixture: An API for handling HTML and JSON fixtures in your specs A set of custom matchers for jQuery framework The loadJSONFixtures method loads fixture(s) from one or more JSON files and makes it available at runtime To know more about the jasmine-jquery plugin, you can visit the following website: https://github.com/velesin/jasmine-jquery Let's implement both the specs created in the previous section using the Data-Driven approach. Consider the following code: describe("Person With O+ Blood Group: ", function(){    var fixturefile, fixtures, myResult; beforeEach(function() {        //Start - Load JSON Files to provide input data for all the test scenarios        fixturefile = "fixture_input_data.json";        fixtures = loadJSONFixtures(fixturefile);        myResult = fixtures[fixturefile];            //End - Load JSON Files to provide input data for all the test scenarios });   it("can receive the blood of the " +      "person with O+ blood group", function() {    //Start - Provide input values from the data file    var testPersonCriteria = new Person(        myResult[0].Name,        myResult[0].DOB,        myResult[0].Blood_Group,        myResult[0].Donor_Receiver    );    //End - Provide input values from the data file    spyOn(testPersonCriteria, "MatchBloodGroupToGiveReceive").and.callThrough();    var callback = jasmine.createSpy();    testPersonCriteria.ValidateBloodGroup(callback);    //Verify, callback method is called or not    expect(callback).toHaveBeenCalled();    //Verify, MatchBloodGroupToGiveReceive is    // called and check whether control goes back    // to the function or not    expect(testPersonCriteria.MatchBloodGroupToGiveReceive).toHaveBeenCalled();    expect(testPersonCriteria.MatchBloodGroupToGiveReceive.calls.any()).toEqual(true);        expect(testPersonCriteria.MatchBloodGroupToGiveReceive.calls.count()).toEqual(1);    expect(testPersonCriteria.ValidateBloodGroup(callback)).toContain("O+"); }); it("can give the blood to the " +      "person with A+ blood group", function() {    //Start - Provide input values from the data file    var testPersonCriteria = new Person(        myResult[1].Name,        myResult[1].DOB,        myResult[1].Blood_Group,        myResult[1].Donor_Receiver    );    //End - Provide input values from the data file    spyOn(testPersonCriteria, "MatchBloodGroupToGiveReceive").and.callThrough();    var callback = jasmine.createSpy();    testPersonCriteria.ValidateBloodGroup(callback);    expect(callback).toHaveBeenCalled();    expect(testPersonCriteria.MatchBloodGroupToGiveReceive).toHaveBeenCalled();    expect(testPersonCriteria.ValidateBloodGroup(callback)).toContain("A+"); }); }); In the preceding code snapshot, you can notice that first we provided the input data from an external JSON file (that is, fixture_input_data.json) using the loadJSONFixtures function and made it available at runtime. Thereafter, we provided input values/data to both the specs, as required; we set the value of name, date of birth, blood group, and donor/receiver for specs 1 and 2, respectively. Further, following the same methodology, we can also create a separate data file for expected values, which we require in our tests to compare with actual values. If test data (input or expected values) is required during execution, it is advisable to provide it from an external file instead of using hardcoded values in your tests. Now, execute the test suite with the Jasmine runner and you will see that all the specs are passing: Summary In this article, we looked at the implementation of Jasmine tests using spies. We also demonstrated how to test the callback function using custom spy method. Further, we saw the implementation of Data-Driven approach, where you learned how to to isolate test data from the code. Resources for Article: Further resources on this subject: Web Application Testing [article] Testing Backbone.js Application [article] The architecture of JavaScriptMVC [article]
Read more
  • 0
  • 0
  • 2718
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-getting-started-oracle-primavera-p6
Packt
23 Aug 2012
7 min read
Save for later

Getting Started with Oracle Primavera P6

Packt
23 Aug 2012
7 min read
Product history The core concepts of project scheduling were laid down in the years following World War II, as construction projects in the United States became larger and more complex. By the 1960s, these concepts were being implemented in mainframe computers by such entities as DuPont, IBM, and the U.S. military. In 1983, Joel Koppelman and Dick Faris founded Primavera Systems in Philadelphia. Their vision was that these same principles of project management could be implemented on desktop PCs, which were then just making their way into common use. The first product went on sale in 1983, available on a set of 5¼-inch floppy disks that held a whopping 360 KB of data each. The application required 256 KB of RAM to run, which was quite a lot at the time. And so Primavera Project Planner (P3) was born. The company was quite successful and eventually P3 became the leading scheduling product in the engineering and construction industries. In fact, it soon became a requirement for certain government contracts that schedules could only be delivered in a P3-compatible format. In the late 1990s, with the rise of networks and the Internet, it became clear that the future of project scheduling software lay beyond a single product installed on one person's desktop. Instead, project scheduling was moving towards systems that could be accessed simultaneously by multiple people in different locations. In 1999, Primavera acquired Eagle Ray Software. This company had created a product in 1998 called Eagle Ray 1000 Project Management Suite. Primavera took ER1000 and released it as two products in 1999: P3 e/c, which was marketed for Engineering and Construction, and TeamPlay for IT and Financial services. Over the years, the products have appeared to merge and diverge, adding capabilities such as timesheet entry, integration, and portfolio analysis, eventually evolving into what is now called P6. In 2004, Primavera 5.0 was released, and in 2007, P6.0 was released, followed by P6.2 in 2008. In 2008, another major change occurred. Primavera, a privately held company, was bought by Oracle, a publicly held corporation. Enter Oracle In 2008, soon after P6.2 came out, it was announced that Oracle Corporation was buying Primavera. Starting as a database provider in 1979, Oracle had grown over the years into a large and influential company, focused not only on databases, but on providing an array of software products that are fundamental to managing modern businesses. This array included enterprise resource planning (ERP) systems, content management systems, analytical and reporting systems, and application servers and technology, to describe just a few. In order to ensure that they also owned the best-of-breed in project scheduling software, Oracle acquired Primavera Systems in 2008. Since the acquisition, P6 has undergone a number of changes. First, the various names were consolidated into one: P6. Oracle also spent considerable resources improving and adding to the product. For example, P6 now supports a standards-compliant Web Services API; it can run from a cluster of WebLogic or WebSphere application servers; and the full capabilities of the system are now available through a web browser. P3 and SureTrak Some users may confuse P3 and SureTrak with P6. P3 is the heir to the original Primavera Project Planner product. It is a standalone desktop application. SureTrak was a lighter version of P3 designed for users with simpler requirements, and so had a limit on the number of activities it would support. Both products have reached the end of their life cycles, and sales of P3 and SureTrak officially ended on December 31st, 2010. Yet this is not the end of the standalone desktop client. With P6 version 8.1, a true standalone version of P6 was created, finally closing the gap that sprang open in 1999 when Primavera bought Eagle Ray, and set separate tracks for its desktop and enterprise solutions. Now users can have the power of P6 on their laptop with P6 Professional, or deploy P6 Enterprise and gain the additional benefits of enterprise-wide capabilities. P6 release 8.2 allows these two products to work even better together. What's in the name? The product that we all know as P6 is officially named Oracle Primavera P6 Enterprise Project Portfolio Management, which is quite a mouthful. But the name accurately reflects the scope and purpose of the software: Enterprise: Unlike P3, which was a standalone application designed to be used by a single user on a dedicated machine, P6 is designed to facilitate multiple users across a large organization. It is a true multi-tier system, with a database on the back end, an application server in the middle, and a web server to which users can connect through an internet browser client such as Microsoft Internet Explorer or Mozilla Firefox. This means that the system is very scalable, and can support hundreds of users working on thousands of projects with millions of activities. This also means that it can support companies with geographically diverse projects and a workforce spread across the globe. Project: At its heart, P6 supports projects. But what is a project? In the Project Management Body of Knowledge, a project is defined as a temporary endeavor undertaken to create a unique product or service. (A Guide to the Project Management Body of Knowledge, 4th Edition, The Project Management Institute, 2008). A project can mean different things in different industries, but projects comprise an amazingly large part of the commercial world. Traditionally we think of construction with respect to projects. But making entertainment is also a project. Think of all the people and equipment and coordination required to make a movie, television show, or album. Developing a new drug is a project as well, starting with basic research and moving to clinical trials, government approval, marketing, manufacturing, and distribution. Each of these is a project by itself. But what matters is this: A project has a scope of work to be done, a timeline for completing the work, and a set amount of resources to do the work. All of these can be measured within the boundaries of the project. P6 allows you to make these measurements, and it gives you the ability to react to these measurements (scope, schedule, and budget) to ensure that your project accomplishes its goals. Portfolio: With very few exceptions, a project does not stand alone. A studio creates many movies over the course of a year. A pharmaceutical company develops many different drugs. An energy company has facilities ranging from the frigid tar sands of northern Alberta to the tropical coastline of Brazil. When making strategic decisions about what projects to pursue, which ones to pour more resources into, and which ones to halt, you need to see the larger picture. This is the grouping of projects into a portfolio. P6 can handle thousands of projects and has analytical capabilities to roll up information across projects and perform analysis across the enterprise. This allows decision makers to understand their business from a broad perspective, and to take action on that information. Management: There is an old adage that says: only what can be measured can be controlled. P6 is about planning projects and measuring progress as the project moves forward. Although P6 is very flexible in how it can be used, it is also designed to help you manage projects well. And when used properly, you can maintain a reliable budget, anticipate cash flow and resource usage, and record and react to changes as they arise. What's more, you can bring the various members of the project team together, set standards, and define the right way to run projects at your specific company. In a nutshell, P6 is designed to help organizations manage their projects in a coherent manner, giving them the power to make better decisions and allowing them to focus on the best strategies.
Read more
  • 0
  • 0
  • 2717

article-image-advanced-jira-52-features
Packt
13 Aug 2013
6 min read
Save for later

Advanced JIRA 5.2 Features

Packt
13 Aug 2013
6 min read
(For more resources related to this topic, see here.) GreenHopper So far, you have seen and used JIRA as a traditional issue-tracking system, where users can log issues and transition them through workflows. With the recent increased adoption of agile development methodologies, it is clear that JIRA by itself is not enough, and this is where GreenHopper comes in. GreenHopper adds the power of agile methodologies to JIRA, by providing a new user interface to help you and your team plan and visualize the tasks you have at hand. GreenHopper is a separate product and does not come with JIRA. So the first step for us is to install it via the Marketplace. Getting GreenHopper GreenHopper is a commercial add-on provided by Atlassian. We can discover and install add-ons directly from JIRA through the Universal Plugin Manager. Perform the following steps to install GreenHopper via the UPM: Browse to Universal Plugin Manager. Select the Find New Add-ons tab. Search for GreenHopper in the search box. This will locate the add-on GreenHopper - Agile project management for JIRA. Click on on the Free Trial button if you want to evaluate GreenHopper before purchasing, or click on the Buy Now button to purchase directly. This will prompt the UPM to start downloading and installing the add-on. Click on the Get License button when prompted, and follow the steps to either generate a trial license or purchase a full license: After you have successfully installed GreenHopper, there will be a new item added to JIRA's top menu bar called Agile, as shown in the following screenshot: Starting with GreenHopper Before we start using GreenHopper, the first thing you need to understand is that GreenHopper adds a new user interface to JIRA, allowing you to better visualize the data you already have in JIRA. For example, an issue in GreenHopper is the same as an issue in JIRA, and you can go back and forth between the two user interfaces. Now that the relationship between GreenHopper and JIRA is clear, we need to familiarize ourselves with a number of new terminologies that we will be using. Scrum Scrum is an agile software development methodology, where the development team plans and works on the project iteratively and incrementally to complete the project. You can read more on Scrum at http://en.wikipedia.org/wiki/Scrum(development). Kanban Kanban is a methodology where the focus is to visualize and limit the amount of work that is in progress. Kanban allows the project team to focus on delivering custom value. You can read more on Kanban at http://en.wikipedia.org/wiki/Scrum(development). Board A board is what GreenHopper uses to display and visualize issues in JIRA. You can think of it as a traditional white board, where you will have sticky notes representing the tasks to be completed. Card Following the preceding white board analogy, a card is the sticky note that represents the task to be done. With GreenHopper, a card is an issue, visualized differently: Story Stories or user stories represent requirements or features that are to be implemented. They are usually written in a non-technical language and describe what needs to be done and whom the requirement is designed for (e.g. the end user, the administrator), in a few short sentences. In GreenHopper, a story is represented as an issue of type User Story. Sprint Sprints also known as iterations, are used in iterative agile development methodologies, such as Scrum. A sprint has a specific duration (that is, a start and end date) and is usually between one to four weeks, in which the team works to deliver a portion or an improvement of the whole product or project. Epic An epic is a large user story that has not yet been broken down into smaller, more manageable stories, usually a group of related stories. Epics should be broken down into their component stories during the planning session, before becoming part of a sprint. In GreenHopper, an epic is represented as an issue of type Epic. Backlog The backlog contains all the issues that have not yet been included in a sprint. Working with boards To start working with GreenHopper, you need to get familiar with boards. You can view and access boards from the Manage Boards page, by pulling down the Agile menu and selecting Manage Boards. From the Manage Boards page, you will see all the boards that are shared with you. The following screenshot shows three boards, two are shared with Sample Project, and one is not shared at all, making it a private board: GreenHopper has two types of boards, Scrum and Kanban. The Scrum board is designed to support the Scrum methodology, where teams plan and work in sprints. Scrum boards have access to all three modes mentioned above. The Kanban board is designed to support the Kanban methodology, where teams focus on managing and constraining their work in progress. Since Kanban does not have a planning session like Scrum, its boards do not have the Plan mode. There are three modes for GreenHopper boards, namely Plan, Work, and Report: Plan: This is where you plan your sprints. This mode is only available to Scrum boards. Work: This is where cards (issues) are progressed (workflow transition) from one column (issue status) to another. Report: This contains a number of built-in reports and charts such as the Burndown chart (Scrum) and Control chart. The following screenshot shows an example of a Scrum board in the Plan mode: Creating a new board There are two ways to create a new board. You can create either a new Scrum or Kanban board. Perform the following steps to create a new board from presets: Bring down the Agile menu and select Manage Boards. Click on the Tools option at the top-right and select Create Board. Choose to create either a Scrum or Kanban board. Provide a name for the new board. Select the project the new board is for. Click on the Create button. When creating a new board based on the presets, GreenHopper will automatically generate the necessary JQL queries based on the selected project. For a Scrum board, it will include all the issues in the project, while for a Kanban board, it will include all the issues that do not belong to a released version. Creating a new board based on the presets is simple and fast but each board is linked to a project only. You can also create a new board with a filter, and this way, you can control what issues will be added to the board. One thing to keep in mind is that you can only create Kanban boards this way. You cannot create a Scrum board with a filter. Perform the following steps to create a new Kanban board with a filter: Bring down the Agile menu and select Manage Boards. Click on the Tools option at the top-right and select Create Board. Select the Advanced option. Provide a name for the new board. Select a filter you want to use. Click on the Create button.
Read more
  • 0
  • 0
  • 2717

article-image-tortoisesvn-getting-started
Packt
18 Jan 2011
7 min read
Save for later

TortoiseSVN: Getting Started

Packt
18 Jan 2011
7 min read
  TortoiseSVN 1.7 Beginner's Guide Perform version control in the easiest way with the best SVN client – TortoiseSVN Master version control techniques with TortoiseSVN without the need for boring theory Revolves around a real-world example based on a software company The first and the only book that focuses on version control with TortoiseSVN Reviewed by Stefan Kung, lead developer for the TortoiseSVN project So let's get on with it... Our case study Shiny Moose Software is a software house with a small team of developers. They have just started working on their first project—a Hiragana Learning Game written in Python. The lead developer, Quinn, has created a skeleton for the project. He has written the code for the games "splash screen". One of the other developers, Mowbray, downloaded a compressed archive containing Quinn's code and found that on his older computer, the CPU usage spiked massively when the code was run. He looked at the code and noticed that Quinn had made a poor choice when deciding how to detect mouse events. The problem is simple to fix, but Mowbray knows that communicating the changes to Quinn could be problematic. Mowbray could make the required changes and then e-mail the updated code to Quinn, but what if Quinn returns to his computer and resumes his work on the application before he checks his e-mail? What if one of the other developers at Shiny Moose Software has also decided to make some changes to the code? Keeping track of changes submitted by several different developers would be confusing enough even with this relatively small application. Imagine how difficult it would become when the code is measured in hundreds, or thousands of lines, rather than just a few dozen! This is where Subversion saves the day. Instead of copying the code from a normal shared folder, or downloading it from the company's intranet site, Mowbray can use TortoiseSVN to check out a working copy of the code, inform the Subversion server that is currently working on that file, make the changes, and check it back in. A word about our examples The code snippets used in this article are incredibly simplistic. Please don't use them as examples for how to write a Python application! Also, don't worry too much about the language or IDE used in these examples. TortoiseSVN can be used with any language and any development environment. Even team members working on other areas, such as documentation or translation work, can take advantage of TortoiseSVN. The most important thing is to understand the version control principles which are being applied. Working copies explained The first thing Mowbray needs to do is check out a working copy. He can make changes to this copy and then submit the changes once he is done. Time for action – checking out a working copy Checking out a working copy takes just a few simple steps. Create a folder which you will use to store your working copies. For example, C:ProjectsMooseHiragana. Right-click inside that folder and select SVN Checkout... from the menu that appears. Browse to your project's repository (or enter the correct network path) and click OK. A window containing a list of the files which have been checked out will appear. If the checkout was successful, you should see a list of files in your chosen directory, with a green tick on the icon of each file. (Move the mouse over the image to enlarge.) What just happened? You have just checked out a working copy of the files which are stored on the repository. This is useful because it allows you to safely test, change, and experiment with the code without the risk of breaking the original code. Once you are happy with the changes you have made, you can check them in to the repository, so that your fellow developers can synchronize their copies to see your changes. Local repositories vs. remote repositories We will use remote repositories in most of our examples. It is likely that you will, at some point, need to work with a remote repository—either one which is accessed via the internet, or one which is part of your company's network. In that case, all you need to do is enter the full network/ internet address of the repository in the place of the file:/// reference in the URL of Repository box. Checkout depth The MooseHiragana project is quite small, so there is no issue with checking out the entire repository. If you were working on a much larger project, which had thousands of files, then you may prefer to save time, bandwidth and storage space by checking out only the folders that relate to the part of the project you are working on. Time for action – using checkout depth Using a different folder for this working copy, right-click inside the folder, and select SVN Checkout.... This time, in the Checkout window that appears, as well as selecting the correct repository, choose Only file children from the Checkout Depth dropdown. You should see that when the checkout process completes, all the files that are part of the root folder appear in your working copy, but none of the folders have been checked out. What just happened? You have just checked out only the files that are in the root folder of the project on the Subversion server. That may not seem like a particularly useful feature when the project consists of just a few files, but imagine if there were thousands of files. The checkout depth feature becomes useful when projects increase greatly in size. It is also useful if your team has members that work only on specific parts of the application. For example, an artist could check out only the images folder, or a translator could check out only the folder containing the localization files for the language he is working in. If the artist then needs to expand his checkout to include deeper folders, he can use the repository browser to select the extra folders that he needs. There are a number of different checkout depth options. The following table explains what each option means. Checkout Depth OptionPurposeFully recursiveChecks out the entire tree, including all child folders and sub-folders.Immediate children, including foldersChecks out the specified directory, including all files and child folders, but does not populate the child folders.Only file childrenChecks out the specified directory, including all files, but does not check out any child folders.Only this itemChecks out the selected directory only. Does not populate it with files or child folders.Working copyThis option is not shown on the checkout dialog, but it is the default for all other dialogs which have a depth setting. This option tells TortoiseSVN to adhere to the depth specified in the working copy.ExcludeThis option is not shown on the checkout dialog. It is used to reduce the depth of the working copy after a folder has already been populated. Have a go hero – working with checkout depth Imagine that you are an artist. You have been hired by Shiny Moose Software and asked to redesign the logo used on the splash screen and also to create a smaller one for use in the theme of the game. The directory structure chosen by the developers looks like this: The images that you will be working on are stored in the /images folder. You will not need to work on anything inside the /images/artwork or /images/japanese folders. You need to set up your working copy. Rather than cluttering your filesystem with files that you will never need to use, you have decided to checkout only the folder you need for your work—the /images folder. Using another user account (or another PC on your network), try checking out just the contents of that folder from the repository. If you prefer, you could simply create a new working directory using the same user. However, if you do this, you should note that any changes made in that folder will be marked with your own user name. That may be fine for testing TortoiseSVN's features, but is not good practice in a production environment.  
Read more
  • 0
  • 0
  • 2713

article-image-magento-designs-and-themes
Packt
19 May 2012
13 min read
Save for later

Magento: Designs and Themes

Packt
19 May 2012
13 min read
(For more resources on e-Commerce, see here.) The Magento theme structure The same holds true for themes. You can specify the look and feel of your stores at the Global, Website, or Store levels (themes can be applied for individual store views relating to a store) by assigning a specific theme. In Magento,a group of related themes is referred to as a design package. Design packages contain files that control various functional elements that are common among the themes within the package. By default, Magento Community installs two design packages: Base package: A special package that contains all the default elements for a Magento installation (we will discuss this in more detail in a moment) Default package: This contains the layout elements of the default store (look and feel) Themes within a design package contain the various elements that determine the look and feel of the site: layout files, templates, CSS, images, and JavaScript. Each design package must have at least one default theme, but can contain other theme variants. You can include any number of theme variants within a design package and use them, for example, for seasonal purposes (that is, holidays, back-to-school, and so on). The following image shows the relationship between design packages and themes: A design package and theme can be specified at the Global, Website or Store levels. Most Magento users will use the same design package for a website and all descendant stores. Usually, related stores within a website business share very similar functional elements, as well as similar style features. This is not mandatory; you are free to specify a completely different design package and theme for each store view within your website hierarchy. The Theme structure Magento divides themes into two group of files: templating and skin. Templating files contain the HTML, PHTML, and PHP code that determines the functional aspects of the pages in your Magento website. Skin files are made of CSS, image, and JavaScript files that give your site its outward design. Ingeniously, Magento further separates these areas by putting them into different directories of your installation: Templating files are stored in the app/design directory, where the extra security of this section protects the functional parts of your site design Skin files are stored within the skin directory (at the root level of the installation), and can be granted a higher permission level, as these are the files that are delivered to a visitor's browser for rendering the page Templating hierarchy Frontend theme template files (the files used to produce your store's pages) are stored within three subdirectories: layout: It contains the XML files that contain the various core information that defines various areas of a page. These files also contain meta and encoding information. template: This stores the PHTML files (HTML files that contain PHP code and processed by the PHP server engine) used for constructing the visual structure of the page. locale: This add files within this directory to provide additional language translations for site elements, such as labels and messages. Magento has a distinct path for storing templating files used for your website: app/design/frontend/[Design Package]/[Theme]/. Skin hierarchy The skin files for a given design package and theme are subdivided into the following: css: This stores the CSS stylesheets, and, in some cases, related image files that are called by CSS files (this is not an acceptable convention, but I have seen some designers do this) images:This contains the JPG, PNG, and GIF files used in the display of your site js: This contains the JavaScript files that are specific to a theme (JavaScript files used for core functionality are kept in the js directory at the root level) The path for the frontend skin files is: skin/frontend/[Design Package]/[Theme]/. The concept of theme fallback A very important and brilliant aspect of Magento is what is called the Magento theme fallback model. Basically, this concept means that when building a page, Magento first looks to the assigned theme for a store. If the theme is missing any necessary templating or skin files, Magento then looks to the required default theme within the assigned design package. If the file is not found there, Magento finally looks into the default theme of the Base design package. For this reason, the Base design package is never to be altered or removed; it is the failsafe for your site. The following flowchart outlines the process by which Magento finds the necessary files for fulfilling a page rendering request. This model also gives the designers some tremendous assistance. When a new theme is created, it only has to contain those elements that are different from what is provided by the Base package. For example, if all parts of a desired site design are similar to the Base theme, except for the graphic appearance of the site, a new theme can be created simply by adding new CSS and image files to the new theme (stored within the skin directory). Any new CSS files will need to be included in the local.xml file for your theme (we will discuss the local.xml file later in this article). If the design requires different layout structures, only the changed layout and template files need to be created; everything that remains the same need not be duplicated. While previous versions of Magento were built with fallback mechanisms, only in the current versions has this become a true and complete fallback. In the earlier versions, the fallback was to the default theme within a package, not to the Base design package. Therefore, each default theme within a package had to contain all the files of the Base package. If Magento base files were updated in subsequent software versions, these changes had to be redistributed manually to each additional design package within a Magento installation. With Magento CE 1.4 and above, upgrades to the Base package automatically enhance all design packages. If you are careful not to alter the Base design package, then future upgrades to the core functionality of Magento will not break your installation. You will have access to the new improvements based on your custom design package or theme, making your installation virtually upgrade proof. For the same reason, never install a custom theme inside the Base design package. Default installation design packages and themes In a new, clean Magento Community installation, you are provided with the following design packages and themes: Depending on your needs, you could add additional a custom design packages, or custom themes within the default design package: If you're going to install a group of related themes, you should probably create a new design package, containing a default theme as your fallback theme On the other hand, if you're using only one or two themes based on the features of the default design package, you can install the themes within the default design package hierarchy I like to make sure that whatever I customize can be undone, if necessary. It's difficult for me to make changes to the core, installed files; I prefer to work on duplicate copies, preserving the originals in case I need to revert back. After re-installing Magento for the umpteenth time because I had altered too many core files, I learned the hard way! As Magento Community installs a basic variety of good theme variants from which to start, the first thing you should do before adding or altering theme components is to duplicate the default design package files, renaming the duplicate to an appropriate name, such as a description of your installation (for example, Acme or Sports). Any changes you make within this new design package will not alter the originally installed components, thereby allowing you to revert any or all of your themes to the originals. Your new theme hierarchy might now look like this: When creating new packages, you also need to create new folders in the /skin directory to match your directory hierarchy in the /app/design directory. Likewise, if you decide to use one of the installed default themes as the basis for designing a new custom theme, duplicate and rename the theme to preserve the original as your fallback. The new Blank theme A fairly recent default installed theme is Blank. If your customization to your Magento stores is primarily one of colors and graphics, this is not a bad theme to use as a starting point. As the name implies, it has a pretty stark layout, as shown in the following screenshot. However, it does give you all the basic structures and components. Using images and CSS styles, you can go a long way to creating a good-looking, functional website, as shown in the next screenshot for www.aviationlogs.com: When duplicating any design package or theme, don't forget that each of them is defined by directories under /app/design/frontend/ and /skin/frontend/ Installing third-party themes In most cases, Magento users who are beginners will explore hundreds of the available Magento themes created by third-party designers. There are many free ones available, but most are sold by dedicated designers. Shopping for themes One of the great good/bad aspects of Magento is the third-party themes. The architecture of the Magento theme model gives knowledgeable theme designers tremendous abilities to construct themes that are virtually upgrade proof, while possessing powerful enhancements. Unfortunately, not all designers have either upgraded older themes properly or created new themes fully honoring the fallback model. If the older fallback model is still used for current Magento versions, upgrades to the Base package could adversely affect your theme. Therefore, as you review third-party themes, take time to investigate how the designer constructs their themes. Most provide some type of site demo. As you learn more about using themes, you'll find it easier to analyze third-party themes. Apart from a few free themes offered through the Magento website, most of them require that you install the necessary files manually, by FTP or SFTP to your server. Every third-party theme I have ever used has included some instructions on how to install the files to your server. However, allow me to offer the following helpful guidelines: When using FTP/SFTP to upload theme files, use the merge function so that only additional files are added to each directory, instead of replacing entire directories. If you're not sure whether your FTP client provides merge capabilities, or not sure how to configure for merge, you will need to open each directory in the theme and upload the individual files to the corresponding directories on your server. If you have set your CSS and JavaScript files to merge, under System | Configuration | Developer, you should turn merging off while installing and modifying your theme. After uploading themes or any component files (for example, templates, CSS, or images), clear the Magento caches under System | Cache Management in your backend. Disable your Magento cache while you install and configure themes. While not critical, it will allow you to see changes immediately instead of having to constantly clear the Magento cache. You can disable the cache under System | Cache Management in the backend. If you wish to make any changes to a theme's individual file, make a duplicate of the original file before making your changes. That way, if something goes awry, you can always re-install the duplicated original. If you have followed the earlier advice to duplicate the Default design package before customizing, instructions to install files within /app/design/frontend/default/ and /skin/frontend/default/ should be interpreted as /app/design/frontend/[your design package name]/ and /skin/frontend/[your design package name]/, respectively. As most of the new Magento users don't duplicate the Default design package, it's common for theme designers to instruct users to install new themes and files within the Default design package. (We know better, now, don't we?) Creating variants Let's assume that we have created a new design package called outdoor_package. Within this design package, we duplicate the Blank theme and call it outdoor_theme. Our new design package file hierarchy, in both /app/design/ and /skin/frontend/ might resemble the following hierarchy: app/ design/ frontend/ default/ blank/ modern/ iphone/ outdoor_package/ outdoor_theme/ skin/ frontend/ default/ blank/ blue/ french/ german/ modern/ iphone/ outdoor_package/ outdoor_theme/ However, let's also take one more customization step here. Since Magento separates the template structure from the skin structure—the layout from the design, so to speak—we could create variations of a theme that are simply controlled by CSS and images, by creating more than one skin. For Acme, we might want to have our English language store in a blue color scheme, but our French language store in a green color scheme. We could take the acme/skin directory and duplicate it, renaming both for the new colors: app/ design/ frontend/ default/ blank/ modern/ iphone/ outdoor_package/ outdoor_theme/ skin/ frontend/ default/ blank/ blue/ french/ german/ modern/ iphone/ outdoor_package/ outdoor_blue/ outdoor_green/ Before we continue, let's go over something which is especially relevant to what we just created. For our outdoor theme, we created two skin variants: blue and green. However, what if the difference between the two is only one or two files? If we make changes to other files that would affect both color schemes, but which are otherwise the same for both, this would create more work to keep both color variations in sync, right? Remember, with the Magento fallback method, if your site calls on a file, it first looks into the assigned theme, then the default theme within the same design package, and, finally, within the Base design package. Therefore, in this example, you could use the default skin, under /skin/frontend/outdoor_package/default/ to contain all files common to both blue and green. Only include those files that will forever remain different to each of them within their respective skin directories. Assigning themes As mentioned earlier, you can assign design packages and themes at any level of the GWS hierarchy. As with any configuration, the choice depends on the level you wish to assign control. Global configurations affect the entire Magento installation. Website level choices set the default for all subordinant store views, which can also have their own theme specifics, if desired. Let's walk through the process of assigning custom design package and themes. For the sake of this exercise, let's continue with our Outdoor theme, as described earlier.Refer to the following screenshot: We're going to now assign our Outdoor theme to a Outdoor website and store views. Our first task is to assign the design package and theme to the website as the default for all subordinant store views: Go to System | Configuration | General | Design in your Magento backend. In the Current Configuration Scope drop-down menu, choose Outdoor Products. As shown in the following screenshot, enter the name of your design package, template, layout, and skin. You will have to uncheck the boxes labeled Use Default beside each field you wish to use. Click on the Save Config button. The reason you enter default in the fields, as shown in the previous screenshot, is to provide the fallback protection I described earlier. Magento needs to know where to look for any files that may be missing from your theme files.
Read more
  • 0
  • 0
  • 2713
article-image-tensorflow
Packt
04 Jan 2017
17 min read
Save for later

TensorFlow

Packt
04 Jan 2017
17 min read
In this article by Nicholas McClure, the author of the book TensorFlow Machine Learning Cookbook, we will cover basic recipes in order to understand how TensorFlow works and how to access data for this book and additional resources: How TensorFlow works Declaring tensors Using placeholders and variables Working with matrices Declaring operations (For more resources related to this topic, see here.) Introduction Google's TensorFlow engine has a unique way of solving problems. This unique way allows us to solve machine learning problems very efficiently. We will cover the basic steps to understand how TensorFlow operates. This understanding is essential in understanding recipes for the rest of this book. How TensorFlow works At first, computation in TensorFlow may seem needlessly complicated. But there is a reason for it: because of how TensorFlow treats computation, developing more complicated algorithms is relatively easy. This recipe will talk you through the pseudo code of how a TensorFlow algorithm usually works. Getting ready Currently, TensorFlow is only supported on Mac and Linux distributions. Using TensorFlow on Windows requires the usage of a virtual machine. Throughout this book we will only concern ourselves with the Python library wrapper of TensorFlow. This book will use Python 3.4+ (https://www.python.org) and TensorFlow 0.7 (https://www.tensorflow.org). While TensorFlow can run on the CPU, it runs faster if it runs on the GPU, and it is supported on graphics cards with NVidia Compute Capability 3.0+. To run on a GPU, you will also need to download and install the NVidia Cuda Toolkit (https://developer.nvidia.com/cuda-downloads). Some of the recipes will rely on a current installation of the Python packages Scipy, Numpy, and Scikit-Learn as well. How to do it… Here we will introduce the general flow of TensorFlow algorithms. Most recipes will follow this outline: Import or generate data: All of our machine-learning algorithms will depend on data. In this book we will either generate data or use an outside source of data. Sometimes it is better to rely on generated data because we will want to know the expected outcome. Transform and normalize data: The data is usually not in the correct dimension or type that our TensorFlow algorithms expect. We will have to transform our data before we can use it. Most algorithms also expect normalized data and we will do this here as well. TensorFlow has built in functions that can normalize the data for you as follows: data = tf.nn.batch_norm_with_global_normalization(...) Set algorithm parameters: Our algorithms usually have a set of parameters that we hold constant throughout the procedure. For example, this can be the number of iterations, the learning rate, or other fixed parameters of our choosing. It is considered good form to initialize these together so the reader or user can easily find them, as follows: learning_rate = 0.01 iterations = 1000 Initialize variables and placeholders: TensorFlow depends on us telling it what it can and cannot modify. TensorFlow will modify the variables during optimization to minimize a loss function. To accomplish this, we feed in data through placeholders. We need to initialize both of these, variables and placeholders with size and type, so that TensorFlow knows what to expect. See the following: code: a_var = tf.constant(42) x_input = tf.placeholder(tf.float32, [None, input_size]) y_input = tf.placeholder(tf.fload32, [None, num_classes]) Define the model structure: After we have the data, and have initialized our variables and placeholders, we have to define the model. This is done by building a computational graph. We tell TensorFlow what operations must be done on the variables and placeholders to arrive at our model predictions: y_pred = tf.add(tf.mul(x_input, weight_matrix), b_matrix) Declare the loss functions: After defining the model, we must be able to evaluate the output. This is where we declare the loss function. The loss function is very important as it tells us how far off our predictions are from the actual values: loss = tf.reduce_mean(tf.square(y_actual – y_pred)) Initialize and train the model: Now that we have everything in place, we need to create an instance for our graph, feed in the data through the placeholders and let TensorFlow change the variables to better predict our training data. Here is one way to initialize the computational graph: with tf.Session(graph=graph) as session: ... session.run(...) ... Note that we can also initiate our graph with: session = tf.Session(graph=graph) session.run(…) (Optional) Evaluate the model: Once we have built and trained the model, we should evaluate the model by looking at how well it does with new data through some specified criteria. (Optional) Predict new outcomes: It is also important to know how to make predictions on new, unseen, data. We can do this with all of our models, once we have them trained. How it works… In TensorFlow, we have to setup the data, variables, placeholders, and model before we tell the program to train and change the variables to improve the predictions. TensorFlow accomplishes this through the computational graph. We tell it to minimize a loss function and TensorFlow does this by modifying the variables in the model. TensorFlow knows how to modify the variables because it keeps track of the computations in the model and automatically computes the gradients for every variable. Because of this, we can see how easy it can be to make changes and try different data sources. See also A great place to start is the official Python API Tensorflow documentation: https://www.tensorflow.org/versions/r0.7/api_docs/python/index.html There are also tutorials available: https://www.tensorflow.org/versions/r0.7/tutorials/index.html Declaring tensors Getting ready Tensors are the data structure that TensorFlow operates on in the computational graph. We can declare these tensors as variables or feed them in as placeholders. First we must know how to create tensors. When we create a tensor and declare it to be a variable, TensorFlow creates several graph structures in our computation graph. It is also important to point out that just by creating a tensor, TensorFlow is not adding anything to the computational graph. TensorFlow does this only after creating a variable out of the tensor. See the next section on variables and placeholders for more information. How to do it… Here we will cover the main ways to create tensors in TensorFlow. Fixed tensors: Creating a zero filled tensor. Use the following: zero_tsr = tf.zeros([row_dim, col_dim]) Creating a one filled tensor. Use the following: ones_tsr = tf.ones([row_dim, col_dim]) Creating a constant filled tensor. Use the following: filled_tsr = tf.fill([row_dim, col_dim], 42) Creating a tensor out of an existing constant.Use the following: constant_tsr = tf.constant([1,2,3]) Note that the tf.constant() function can be used to broadcast a value into an array, mimicking the behavior of tf.fill() by writing tf.constant(42, [row_dim, col_dim]) Tensors of similar shape: We can also initialize variables based on the shape of other tensors, as follows: zeros_similar = tf.zeros_like(constant_tsr) ones_similar = tf.ones_like(constant_tsr) Note, that since these tensors depend on prior tensors, we must initialize them in order. Attempting to initialize all the tensors all at once will result in an error. Sequence tensors: Tensorflow allows us to specify tensors that contain defined intervals. The following functions behave very similarly to the range() outputs and numpy's linspace() outputs. See the following function: linear_tsr = tf.linspace(start=0, stop=1, start=3) The resulting tensor is the sequence [0.0, 0.5, 1.0]. Note that this function includes the specified stop value. See the following function integer_seq_tsr = tf.range(start=6, limit=15, delta=3) The result is the sequence [6, 9, 12]. Note that this function does not include the limit value. Random tensors: The following generated random numbers are from a uniform distribution: randunif_tsr = tf.random_uniform([row_dim, col_dim], minval=0, maxval=1) Know that this random uniform distribution draws from the interval that includes the minval but not the maxval ( minval<=x<maxval ). To get a tensor with random draws from a normal distribution, as follows: randnorm_tsr = tf.random_normal([row_dim, col_dim], mean=0.0, stddev=1.0) There are also times when we wish to generate normal random values that are assured within certain bounds. The truncated_normal() function always picks normal values within two standard deviations of the specified mean. See the following: runcnorm_tsr = tf.truncated_normal([row_dim, col_dim], mean=0.0, stddev=1.0) We might also be interested in randomizing entries of arrays. To accomplish this there are two functions that help us, random_shuffle() and random_crop(). See the following: shuffled_output = tf.random_shuffle(input_tensor) cropped_output = tf.random_crop(input_tensor, crop_size) Later on in this book, we will be interested in randomly cropping an image of size (height, width, 3) where there are three color spectrums. To fix a dimension in the cropped_output, you must give it the maximum size in that dimension: cropped_image = tf.random_crop(my_image, [height/2, width/2, 3]) How it works… Once we have decided on how to create the tensors, then we may also create the corresponding variables by wrapping the tensor in the Variable() function, as follows. More on this in the next section: my_var = tf.Variable(tf.zeros([row_dim, col_dim])) There's more… We are not limited to the built in functions, we can convert any numpy array, Python list, or constant to a tensor using the function convert_to_tensor(). Know that this function also accepts tensors as an input in case we wish to generalize a computation inside a function. Using placeholders and variables Getting ready One of the most important distinctions to make with data is whether it is a placeholder or variable. Variables are the parameters of the algorithm and TensorFlow keeps track of how to change these to optimize the algorithm. Placeholders are objects that allow you to feed in data of a specific type and shape or that depend on the results of the computational graph, like the expected outcome of a computation. How to do it… The main way to create a variable is by using the Variable() function, which takes a tensor as an input and outputs a variable. This is the declaration and we still need to initialize the variable. Initializing is what puts the variable with the corresponding methods on the computational graph. Here is an example of creating and initializing a variable: my_var = tf.Variable(tf.zeros([2,3])) sess = tf.Session() initialize_op = tf.initialize_all_variables() sess.run(initialize_op) To see whatthe computational graph looks like after creating and initializing a variable, see the next part in this section, How it works…, Figure 1. Placeholders are just holding the position for data to be fed into the graph. Placeholders get data from a feed_dict argument in the session. To put a placeholder in the graph, we must perform at least one operation on the placeholder. We initialize the graph, declare x to be a placeholder, and define y as the identity operation on x, which just returns x. We then create data to feed into the x placeholder and run the identity operation. It is worth noting that Tensorflow will not return a self-referenced placeholder in the feed dictionary. The code is shown below and the resulting graph is in the next section, How it works…: sess = tf.Session() x = tf.placeholder(tf.float32, shape=[2,2]) y = tf.identity(x) x_vals = np.random.rand(2,2) sess.run(y, feed_dict={x: x_vals}) # Note that sess.run(x, feed_dict={x: x_vals}) will result in a self-referencing error. How it works… The computational graph of initializing a variable as a tensor of zeros is seen in Figure 1to follow: Figure 1: Variable Figure 1: Here we can see what the computational graph looks like in detail with just one variable, initialized to all zeros. The grey shaded region is a very detailed view of the operations and constants involved. The main computational graph with less detail is the smaller graph outside of the grey region in the upper right. For more details on creating and visualizing graphs. Similarly, the computational graph of feeding a numpy array into a placeholder can be seen to follow, in Figure 2: Figure 2: Computational graph of an initialized placeholder Figure 2: Here is the computational graph of a placeholder initialized. The grey shaded region is a very detailed view of the operations and constants involved. The main computational graph with less detail is the smaller graph outside of the grey region in the upper right. There's more… During the run of the computational graph, we have to tell TensorFlow when to initialize the variables we have created. While each variable has an initializer method, the most common way to do this is with the helper function initialize_all_variables(). This function creates an operation in the graph that initializes all the variables we have created, as follows: initializer_op = tf.initialize_all_variables() But if we want to initialize a variable based on the results of initializing another variable, we have to initialize variables in the order we want, as follows: sess = tf.Session() first_var = tf.Variable(tf.zeros([2,3])) sess.run(first_var.initializer) second_var = tf.Variable(tf.zeros_like(first_var)) # Depends on first_var sess.run(second_var.initializer) Working with matrices Getting ready Many algorithms depend on matrix operations. TensorFlow gives us easy-to-use operations to perform such matrix calculations. For all of the following examples, we can create a graph session by running the following code: import tensorflow as tf sess = tf.Session() How to do it… Creating matrices: We can create two-dimensional matrices from numpy arrays or nested lists, as we described in the earlier section on tensors. We can also use the tensor creation functions and specify a two-dimensional shape for functions like zeros(), ones(), truncated_normal(), and so on: Tensorflow also allows us to create a diagonal matrix from a one dimensional array or list with the function diag(), as follows: identity_matrix = tf.diag([1.0, 1.0, 1.0]) # Identity matrix A = tf.truncated_normal([2, 3]) # 2x3 random normal matrix B = tf.fill([2,3], 5.0) # 2x3 constant matrix of 5's C = tf.random_uniform([3,2]) # 3x2 random uniform matrix D = tf.convert_to_tensor(np.array([[1., 2., 3.],[-3., -7., -1.],[0., 5., -2.]])) print(sess.run(identity_matrix)) [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]] print(sess.run(A)) [[ 0.96751703 0.11397751 -0.3438891 ] [-0.10132604 -0.8432678 0.29810596]] print(sess.run(B)) [[ 5. 5. 5.] [ 5. 5. 5.]] print(sess.run(C)) [[ 0.33184157 0.08907614] [ 0.53189191 0.67605299] [ 0.95889051 0.67061249]] print(sess.run(D)) [[ 1. 2. 3.] [-3. -7. -1.] [ 0. 5. -2.]] Note that if we were to run sess.run(C) again, we would reinitialize the random variables and end up with different random values. Addition and subtraction uses the following function: print(sess.run(A+B)) [[ 4.61596632 5.39771316 4.4325695 ] [ 3.26702736 5.14477345 4.98265553]] print(sess.run(B-B)) [[ 0. 0. 0.] [ 0. 0. 0.]] Multiplication print(sess.run(tf.matmul(B, identity_matrix))) [[ 5. 5. 5.] [ 5. 5. 5.]] Also, the function matmul() has arguments that specify whether or not to transpose the arguments before multiplication or whether each matrix is sparse. Transpose the arguments as follows: print(sess.run(tf.transpose(C))) [[ 0.67124544 0.26766731 0.99068872] [ 0.25006068 0.86560275 0.58411312]] Again, it is worth mentioning the reinitializing that gives us different values than before. Determinant, use the following: print(sess.run(tf.matrix_determinant(D))) -38.0 Inverse: print(sess.run(tf.matrix_inverse(D))) [[-0.5 -0.5 -0.5 ] [ 0.15789474 0.05263158 0.21052632] [ 0.39473684 0.13157895 0.02631579]] Note that the inverse method is based on the Cholesky decomposition if the matrix is symmetric positive definite or the LU decomposition otherwise. Decompositions: Cholesky decomposition, use the following: print(sess.run(tf.cholesky(identity_matrix))) [[ 1. 0. 1.] [ 0. 1. 0.] [ 0. 0. 1.]] Eigenvalues and Eigenvectors, use the following code: print(sess.run(tf.self_adjoint_eig(D)) [[-10.65907521 -0.22750691 2.88658212] [ 0.21749542 0.63250104 -0.74339638] [ 0.84526515 0.2587998 0.46749277] [ -0.4880805 0.73004459 0.47834331]] Note that the function self_adjoint_eig() outputs the eigen values in the first row and the subsequent vectors in the remaining vectors. In mathematics, this is called the eigen decomposition of a matrix. How it works… TensorFlow provides all the tools for us to get started with numerical computations and add such computations to our graphs. This notation might seem quite heavy for simple matrix operations. Remember that we are adding these operations to the graph and telling TensorFlow what tensors to run through those operations. Declaring operations Getting ready Besides the standard arithmetic operations, TensorFlow provides us more operations that we should be aware of and how to use them before proceeding. Again, we can create a graph session by running the following code: import tensorflow as tf sess = tf.Session() How to do it… TensorFlow has the standard operations on tensors, add(), sub(), mul(), and div(). Note that all of these operations in this section will evaluate the inputs element-wise unless specified otherwise. TensorFlow provides some variations of div() and relevant functions. It is worth mentioning that div() returns the same type as the inputs. This means it really returns the floor of the division (akin to Python 2) if the inputs are integers. To return the Python 3 version, which casts integers into floats before dividing and always returns a float, TensorFlow provides the function truediv()shown as follows: print(sess.run(tf.div(3,4))) 0 print(sess.run(tf.truediv(3,4))) 0.75 If we have floats and want integer division, we can use the function floordiv(). Note that this will still return a float, but rounded down to the nearest integer. The function is shown as follows: print(sess.run(tf.floordiv(3.0,4.0))) 0.0 Another important function is mod(). This function returns the remainder after division.It is shown as follows: print(sess.run(tf.mod(22.0, 5.0))) 2.0 The cross product between two tensors is achieved by the cross() function. Remember that the cross product is only defined for two 3-dimensional vectors, so it only accepts two 3-dimensional tensors. The function is shown as follows: print(sess.run(tf.cross([1., 0., 0.], [0., 1., 0.]))) [ 0. 0. 1.0] Here is a compact list of the more common math functions. All of these functions operate element-wise: abs() Absolute value of one input tensor ceil() Ceiling function of one input tensor cos() Cosine function of one input tensor exp() Base e exponential of one input tensor floor() Floor function of one input tensor inv() Multiplicative inverse (1/x) of one input tensor log() Natural logarithm of one input tensor maximum() Element-wise max of two tensors minimum() Element-wise min of two tensors neg() Negative of one input tensor pow() The first tensor raised to the second tensor element-wise round() Rounds one input tensor rsqrt() One over the square root of one tensor sign() Returns -1, 0, or 1, depending on the sign of the tensor sin() Sine function of one input tensor sqrt() Square root of one input tensor square() Square of one input tensor Specialty mathematical functions: There are some special math functions that get used in machine learning that are worth mentioning and TensorFlow has built in functions for them. Again, these functions operate element-wise, unless specified otherwise: digamma() Psi function, the derivative of the lgamma() function erf() Gaussian error function, element-wise, of one tensor erfc() Complimentary error function of one tensor igamma() Lower regularized incomplete gamma function igammac() Upper regularized incomplete gamma function lbeta() Natural logarithm of the absolute value of the beta function lgamma() Natural logarithm of the absolute value of the gamma function squared_difference() Computes the square of the differences between two tensors How it works… It is important to know what functions are available to us to add to our computational graphs. Mostly we will be concerned with the preceding functions. We can also generate many different custom functions as compositions of the preceding, as follows: # Tangent function (tan(pi/4)=1) print(sess.run(tf.div(tf.sin(3.1416/4.), tf.cos(3.1416/4.)))) 1.0 There's more… If we wish to add other operations to our graphs that are not listed here, we must create our own from the preceding functions. Here is an example of an operation not listed above that we can add to our graph: # Define a custom polynomial function def custom_polynomial(value): # Return 3 * x^2 - x + 10 return(tf.sub(3 * tf.square(value), value) + 10) print(sess.run(custom_polynomial(11))) 362 Summary Thus in this article we have implemented some introductory recipes that will help us to learn the basics of TensorFlow. Resources for Article: Further resources on this subject: Data Clustering [article] The TensorFlow Toolbox [article] Implementing Artificial Neural Networks with TensorFlow [article]
Read more
  • 0
  • 0
  • 2713

article-image-learning-create-and-edit-data-arcgis
Packt
18 Feb 2016
19 min read
Save for later

Learning to Create and Edit Data in ArcGIS

Packt
18 Feb 2016
19 min read
In this article by Daniela Cristiana Docan, author of the book Learning ArcGIS For Desktop, we will look at the ArcGIS editing tools to create and edit feature shapes and attributes. By the end of this article, you will learn the following: Spatially adjusting vector data to real-world units Editing feature shapes and attributes using ArcMap editing tools (For more resources related to this topic, see here.) Editing features in a geodatabase file In this article, we will work with three primary features’ geometries: point, line, and polygon. A point feature is defined by a single pair of x, y coordinates. The line and polygon features are defined by vertices and segments. The vertices represent ordered x, y coordinate pairs that form a feature's shape. The coordinates of a vertex also include the M (measure) and Z (elevation) values. A segment connects only two vertices. A line with two or more segments is called polyline. In ArcGIS, the line and polygon feature classes can store single or multipart features. A multipart feature is composed of two or more disconnected shapes that have only one record in the feature class attribute table. A simple point feature class cannot store multipart features, but a multipoint feature class can store multipoint features. In the editing process, the shape of a feature can be modified by moving, adding, or deleting the vertices that form its sketch. A sketch displays the location of vertices and segments that define the feature's shape. There are six main steps in the feature's shape editing process, which are as follows: Adding the data in a map document Starting an edit session Setting a feature template and snapping properties to edit the layer's feature geometry Creating a new feature by adding a new sketch or select an existing feature and display its sketch Editing a feature’s shape—moving, deleting, or inserting one or more vertices Saving the feature edits and stopping the edit session Using spatial adjustment In this section, we will perform a spatial adjustment for two feature classes imported from a CAD file that don't have a real-world coordinate system associated. We will use the Affine Transformation method that requires at least three displacement links. A displacement link defines the source and destination coordinates used by the transformation method. Before starting any spatial adjustment, be sure that the horizontal accuracy of the destination coordinates is at least the same or better as the horizontal accuracy of source coordinates. Follow these steps to perform a spatial adjustment in the ArcMap application: Start the ArcMap application and open the existing map document, SpatialAdjustment.mxd, from <drive>:LearningArcGISChapter05. In Table Of Contents, right-click on the Polyline layer and navigate to Properties | Source. Note that there is no projection information associated with the layer. Close the Layer Properties window. Repeat the step for the Polygon layer.First, we will add a basemap for the Brussels city from ArcGIS Online. Check whether ArcGIS for Desktop is connected to ArcGIS Online. In the Standard toolbar, from the drop-down menu next to Add Data, click on Add Data from ArcGIS Online. Search for the brusselsdata and select Brussels - Orthophoto 2012. Click on Details to read the information from the Description tab. Click on the yellow button called Add Data, as shown in the following screenshot: Drag the Brussels - Orthophoto 2012 basemap layer to the bottom of Table Of Contents. Right-click on the Brussels-Orthophoto 2012 basemap layer and go to Properties | Source. Inspect the resolution and the coordinate system of the orthophoto map. The layer's coordinate system is Belge_Lambert_1972002C, and the map projection is Lambert_Conformal_Conic.Second, we will use Spatial Adjustment tools to move the Polyline and Polygon layers to their correct coordinates using the Brussels-Orthophoto 2012 basemap layer as the destination coordinate space, as shown in the following screenshot: Add the Spatial Adjustment and Editor toolbars from Customize | Toolbars. To apply a spatial adjustment to the Polyline and Polygon layers, you must start the editing session. In the Editor toolbar, navigate to Editor | Start Editing. In the Spatial Adjustment toolbar, go to Spatial Adjustment | Set Adjust Data. Check All features in these layers[SI1]  and make sure both the Polyline and Polygon layers are selected. Click on OK. Then, in the Spatial Adjustment toolbar, go to Spatial Adjustment | Adjustment Methods. We will use the default transformation method called Transformation-Affine. Go to the Bookmarks menu and select Manage Bookmarks. Click on the Load button and add Source_points.dat and Destination_points.dat from <drive>:LearningArcGISChapter05. Keep Bookmarks Manager open and inspect Source and Destination for all the seven points by selecting the bookmark and clicking on Zoom To button. When finished, close the Bookmarks Manager window.Instead of adding the displacement links manually, you can load them through a links file. In the Spatial Adjustment toolbar, click on Link Table. Go to Spatial Adjustment | Links|Open Links File, navigate to <drive>:LearningArcGISChapter05, and select DisplacementLinks.txt. Now, click on Open. Link Table is automatically updated with seven coordinate pairs. You can modify or delete the individual links. In the Spatial Adjustment toolbar, navigate to Spatial Adjustment | Adjust. Note the RMS Error value: 4.9 meters. For a dataset with the reference scale of 1:15,000, an RMS value of 4.9 meters is a reasonable one. The assumed reference scale and the resulting RMS value should be mentioned in metadata file (at Item Description | Resource | Lineage). Next, close the Link Table. If you want add the displacement links manually, you should set up the snapping environment by checking Vertex Snapping in the Editor | Snapping toolbar. As you can note, the Polyline and Polygon layers were both transformed to match the Brussels-Orthophoto 2012 coordinate space. Inspect the results. In the Editor toolbar, navigate to Editor | Save Edits to save the spatial adjustment applied to the Polyline and Polygon layers.In the second part of the exercise, we will define the reference system for the Brussels_CADToGeodatabase feature dataset. Open the Catalog window and connect to the <drive>:LearningArcGISChapter05 folder. Expand World.gdb. Then, right-click on Brussels_CADToGeodatabase and go to Properties | XY Coordinate System. In the Search text box, type belge. Navigate to Projected Coordinate Systems | National Grids | Europe and select Belge Lambert 1972. Click on the Add To Favorites button. Then, click on Apply.You will see a warning message that tells you that it will modify the existing object as it cannot acquire a schema lock. However, you cannot modify the reference system while you are in an open edit session. Click on OK twice to close all dialog windows. In the Editor toolbar, navigate to Editor | Stop Editing. Repeat the last step to define the reference system for the Brussels_CADToGeodatabase feature dataset. Note that the Polyline and Polygon feature classes automatically inherit the feature dataset's reference system. When finished, save your map document as MySpatialAdjustment.mxd to <drive>:LearningArcGISChapter05. You can find the results of this exercise at <drive>:LearningArcGISChapter05 ResultsSpatialAdjustment. Editing features In this section, you will learn how to create a new feature class from an existing one using the Export Data tool in the ArcMap application. Next, you will explore different edit tools to create new features by splitting or combining the existing features. In the end, you will learn how to modify the feature's shape by adding, moving, and deleting vertices on its sketch. Before you start editing a feature sketch, you should always set the snapping properties, such as the snap type or snapping tolerance value. Snapping helps you create coincidence during the editing process. Snapping allows you to move the mouse pointer exactly to a vertex, edge, start point, or endpoint of a feature, when the pointer location is within a predefined distance of them. This distance is called snapping tolerance. ArcMap calculates the value of the snapping tolerance for you, but you can change it and specify your own value. Follow these steps to start editing features using the ArcMap application: Start the ArcMap application and open a new map document. Open the Catalog window, and navigate to..Chapter05EditingFeaturesWorld.gdb. Expand the Europefeature dataset. Select the EuropeCities_10k feature class and drag it on the ArcMap map display. The map shows the Paris and Brussels cities at a scale of 1:10,000. In Table Of Contents, right-click on theEuropeCities_10k layer and select Open Attribute Table. Dock the Table window to the bottom of the map display by dragging and dropping it on the down arrow of the blue centered target. Click on the Table Options button in the upper-left corner and select Select by Attributes. Build the following expression: CITIES = 'Bruxelles/Brussel'. Then, click on Apply and Close. Note that 32945 records are selected in the attribute table and on the map display. We will save these selected features in a new feature class called Brussels. Right-click on the EuropeCities_10k layer and select Data | Export Data. For Export, accept the Selected features option. Click on the browser button, make sure you are in the ..Chapter05EditingFeaturesWorld.gdbEurope folder, and type Brussels for the name of the feature class. Click on the No button to not add the exported data to map display as a layer. In the Catalog window, the Europe feature dataset is updated with your new polygon feature class. Hide the Catalog window by clicking on the Auto hide button. Then, close the Table window.Next, we will change the projection of the Brussels feature class and save it into the Brussels feature dataset. In the Standard toolbar, click on the ArcToolbox tool. Navigate to ArcToolbox | Data Management Tools | Projections and Transformations and select Projection. Set the following parameters:      Input Dataset or Feature Class: ..EditingFeaturesWorld.gdbEuropeBrussels      Output Dataset or Feature Class: ..EditingFeaturesWorld.gdbBrusselsBrusselsCity      Output Coordinate System: Belge_Lambert_1972      Geographic Transformation: Belge _1972_To_ETRS_1989_2 Click on OK. Click on No to not add the exported data to the map display as a layer. Hide the ArcToolbox window by clicking on the Auto hide button. On the Standard toolbar, click on the New tool to open a new map document. In the New Document dialog window, for Default geodatabase for this map, click on the browser button and navigate to <drive>:LearningArcGISChapter05EditingFeaturesWorld.gdb. Click on Add and OK. Finally, click on No to not save the changes from the last map document. Add the BrusselsCity and Buildings feature classes from the Brussels feature dataset in ArcMap by dragging them on the map display. Change the BrusselsCity symbol to Hollow, Outline Width to 1.5 , and Outline Color to Medium Coral Light. Label the features with the OBJECTID field's values. Change the label to Medium Coral Light. Change the Buildings symbol to Hollow, Outline Width to 1.5, and Outline Color to Solar Yellow. Label the Buildings features with the OBJECTID field's values. Navigate to Add Data | Add Data From ArcGIS Online to add two aerial photos of Brussels: Brussels -Othotophoto 2004 and Brussels -Othotophoto 2012. In Table Of Contents, drag Brussels -Othotophoto 2004 to the bottom of list. From the Bookmarks menu, select Manage Bookmarks. Click on the Load button, navigate to <drive>:LearningArcGISChapter05, and select the EditingFeaturesAttributes.dat ArcGIS Place file. Click on Open. These bookmarks will help us identify particular study areas in the next exercises. Click on Close. When finished, save your map document as MyEditingFeatures.mxd at <drive>:LearningArcGISChapter05EditingFeatures.In the next steps, we will start editing the building footprints from the Buildings layer. These buildings were digitized using an aerial photo from 2004 (Brussels -Othotophoto 2004) as layer reference. We will update the features to reflect the changes that were made from 2004 to 2012 using Brussels -Othotophoto 2012 as the reference layer. First, we will set the Buildings layer as the only selectable layer in the map. At the top of Table Of Contents, click on the List By Selection button. Both the BrusselsCity and Buildings layers will be selectable. Click on the Selectable button next to the BrusselsCity layer to move it to the Not Selectable list. Return to the List By Drawing Order layers’ list mode. From Bookmarks, select Edit 1. You will divide a feature into five separate features, as shown in the following screenshot: In Table Of Contents, right-click onthe Buildings layer and select Open Attribute Table. Dock the Table window to the bottom of the map display. First, we will start an edit session and set the snapping properties. If necessary, add the Editor toolbar. In the Editor toolbar, go to Editor | Start Editing. Second, we will create a feature template. If the Create Features window isn't open, you should navigate to Editor | Editing Windows | Create Features. As the BrusselsCity and Buildings layers reference two feature classes that are stored in the same workspace called World.gdb, the Create Features window displays the default feature templates for both of them. In the Create Features window, double-click on the Buildings template to open the Template Properties window. Inspect the information for the template displays. For Description, type Brussels buildings . For Default Tool, accept Polygon. Click on OK to update the Buildings feature template. At the bottom of the Created Features window, in the Construction Tools list, make sure that the Polygon tool is selected. Next, we will use the default snapping environment to enable snapping to feature vertices. From the Editor menu, navigate to Snapping | Snapping Toolbar. In the Snapping toolbar, turn off all snapping types, except the Vertex Snapping button. During the edit process, your mouse pointer will be moved exactly only to the vertices of a feature. ArcMap allows you to activate the classic snapping environment if you need more control to snapping properties, such as the individual type of snapping on each editable layer or snapping tolerance units (pixels or map units). To activate the classic snapping, in the Editor menu, navigate to Editor | Options | General and take a look at Use classic snapping. From the Editor menu, navigate to Snapping | Snapping Window to manage the individual snapping on layers. To change the snapping tolerance units, go to Editor | Snapping | Options. In the Tools toolbar, click on the Select Feature tool and select the building shown in the preceding screenshot. At the bottom of the Table window, click on the Show selected records button to see only the selected building’s record. In the Editor toolbar, select the Cut Polygons tool. Note that another tool called Straight Segment is selected. You will cut the polygon feature using a multipart polyline. Move the pointer close to the start point (1) indicated before to see the SnapTip  called Buildings: Vertex. Click on the 1 point to add the first vertex of the segment. Click on the 2 point and again on the 3 point. Then, right-click on the third vertex and select Finish Part. If you want to delete a vertex, right-click on it and select Delete Vertex.You can use the Zoom in, Zoom out, and Pan tools while you are splitting the polygon, but you have to select the Cut Polygons tool again to continue adding vertices. Click on the 4, 5, and 6 points, as shown in the preceding screenshot. Right-click on the sixth vertex and select Finish Part. Repeat the steps for the rest of points. Right-click on the twelfth vertex (Sketch: Enpoint) and select Finish Sketch. Five new features are created and selected on the map display. In the Table window, note that the Buildings feature class table is updated with five new building records corresponding to the five polygons on the map display. To unselect the new features on the map, use the Clear Selected Features tool on the Tools toolbar. To save your edits to the data, select Save Edits in the Editor menu.In the next steps, we will continue to update the buildings by erasing the two buildings that have been demolished since 2010, and we will merge the two existing features to represent a larger commercial building, as shown in the following screenshot: We will continue to use the Buildings feature template. From Bookmarks, select Edit 2. Add the Effects toolbar on the map display and select Brussels-Orthophoto 2012 from the drop-down list of layers. Select the Swipe button. Then, click on the map display and drag to see the differences between the two ortophoto maps. Use the Select Feature tool and the Shift key to select two buildings that have the following OBJECTID values: 53 and 52. Right-click on the map display and select Delete. You have a second option of removing them from the Buildings layer using the Delete Selected tool in the Table window. During an edit session, you should use the Edit tool to select a feature by clicking on it. As we don't set Sticky move tolerance at Editor | Options | General, we have to use the Select Feature tool to prevent the accidental moving of the selected features. Use the Select Feature tool to select the buildings with the OBJECTID values 51 and 54. In the Table window, inspect the attribute values of the building with the ID 51. In the Editor toolbar, navigate to Editor | Merge. In the Merge dialog window, click on the first feature Industrial (Buildings). The selected feature flashes on the map. As the first feature in the list is the larger one that has a name, we would like to keep its attribute values. Click on OK. In the Table window, note that the OBJECTID, Type, and Name values were inherited from the previous selected feature. Instead, the SHAPE_Length and SHAPE_Area fields are updated by ArcMap.In the next steps, we will reshape the building with OBJECTID 51, as shown in the following screenshot: To edit the building shape, you must display its sketch. In the Editor toolbar, select the Edit Tool button, double-click on the building to select it, and display the feature's sketch, as shown in the preceding screenshot. The Edit Vertices mini toolbar is automatically added on the map. Drag and draw a box over the four vertices as shown before. Move the pointer over one of the selected vertices until it turns in a compass arrow, right-click, and select Delete Vertices. If you make a mistake, use the Undo Delete tool from the Standard toolbar and repeat the step. To erase the vertices of two or more sketches, you can also draw a box over the vertices using the Delete Vertex tool from the Edit Vertices mini toolbar. Click away from the selected feature to unselect it and see the changes. In the Editor toolbar, select the Edit Tool button again and double-click on the building to display the feature's sketch. On the Edit Vertices toolbar, select Add Vertex. Click on the line segment and add two vertices, as shown in the preceding screenshot. Click on the first new vertex (1) to select it. Move the pointer over the selected vertex until it turns in a compass arrow. Drag and drop the vertex to the new location. Now, click on the second new vertex (2) to select it. You will move this feature's vertex to an exact x, y location. Right-click on vertex and select Move To Fist; then, click on the down arrow next to the X box and check whether Meter is selected. In the X box, select and delete the existing value. Type 154266.227 and press the Tab key. For Y, type 172231.383 and press the Enter key. Note that the vertex has moved to the exact location. Press the F2 key to finish the sketch. Even if your feature shape changes in your map document, the edits of the data is not save in your feature class. To store the updated date in your file geodatabase, you must save your edits during an edit session or when you stop the edit session. In the Editor toolbar, navigate to Editor | Save Edits. Saving your map document does not save the data edits to your geodatabase.In the last steps, we will move three adjacent buildings and reshape one of them, as shown in the following screenshot: From Bookmarks, select Edit 4. In the Editor toolbar, click on the Edit tool. Drag and draw a box over the three buildings, as shown in the preceding screenshot. Note that the Start and End points of the box do not touch the polygon’s features. This way, you can select three adjacent buildings with the Edit tool without accidentally producing small position moves. To move all the buildings 5 meters on the Y axis, from the Editor toolbar, go to Editor | Move. In the Delta X, Y window, type 5 in the second box and press the Enter key. All the three buildings will shift 5 meters on the Yaxis. Next, we will adjust the shape of a building. In the Tool toolbar, click on the Clear Selected Features tool to unselect the buildings. With the Edit tool, select the building with ID 45 and then click on the Reshape Feature tool on the Editor toolbar. Click on the 1 point to add the first vertex of the line segment. Click on the 2 point to add the second vertex, and then click on the 3 point to add the third vertex. Press the F2 key to finish the sketch. Inspect the results. Unselect the building and save the edits. In the Editor toolbar, stop the edit session by navigating to Editing | Stop Editing. When finished, save your changes to the map document. Leave the MyEditingFeatures map document open to continue working with map topology in the next recipe. You can find the results at <drive>:LearningArcGISChapter05 ResultsEditingFeaturesEditingFeatures.mxd. Summary In this article, we identified the main steps in the editing process. You learned how to modify the existing features and add new features. Also, we explored different ArcMap instruments to edit the coincident features—that is, using the Auto-Complete Polygons and map topology tools. Resources for Article: Further resources on this subject: Extracting Real-Time Wildfire Data from ArcGIS Server with the ArcGIS REST API[article] ArcGIS – Advanced ArcObjects[article] ArcGIS Spatial Analyst[article]
Read more
  • 0
  • 0
  • 2711

article-image-customizing-look-and-feel-uag
Packt
22 Feb 2012
8 min read
Save for later

Customizing Look and Feel of UAG

Packt
22 Feb 2012
8 min read
(For more resources on Microsoft Forefront UAG, see here.) Honey, I wouldn't change a thing! We'll save the flattery for our spouses, and start by examining some key areas of interest what you might want and be able to change on a UAG implementation. Typically, the end user interface is comprised of the following: The Endpoint Components Installation page The Endpoint Detection page The Login page The Portal Frame The Portal page The Credentials Management page The Error pages There is also a Web Monitor, but it is typically only used by the administrator, so we won't delve into that. The UAG management console itself and the SSL-VPN/SSTP client-component user interface are also visual, but they are compiled code, so there's not much that can be done there. The elements of these pages that you might want to adjust are the graphics, layout, and text strings. Altering a piece of HTML or editing a GIF in Photoshop to make it look different may sound trivial, but there's actually more to it than that, and the supportability of your changes should definitely be questioned on every count. You wouldn't want your changes to disappear upon the next update to UAG, would you? Nor would you look the page to suddenly become all crooked because someone decided that he wants the RDP icon to have an animation from the Smurfs. The UI pages Anyone familiar with UAG will know of its folder structure and the many files that make up the code and logic that is applied throughout. For those less acquainted however, we'll start with the two most important folders you need to know—InternalSite and PortalHomePage. InternalSite contains pages that are displayed to the user as part of the login and logout process, as well as various error pages. PortalHomePage contains the files that are a part of the portal itself, shown to the user after logging in. The portal layout comes in three different flavors, depending on the client that is accessing it. The most common one is the Regular portal, which happens to be the more polished version of the three, shown to all computers. The second is the Premium portal, which is a scaled-down version designed for phones that have advanced graphic capabilities, such as Windows Mobile phones. The third is the Limited portal, which is a text-based version of the portal, shown to phones that have limited or no graphic capabilities, such as the Nokia S60 and N95 handsets. Regardless of the type, the majority of devices connecting to UAG will present a user-agent string in their request and it is this string that determines the type of layout that UAG will use to render its pages and content. UAG takes advantage of this, by allowing the administrator to choose between the various formats that are made available, on a per application basis. The results are pretty cool and being able to cater for most known platforms and form factors, provides users with the best possible experience. The following screenshot illustrates an application that is enabled for the Premium portal, and how the portal and login pages would look on both a premium device and on a limited device: Customizing the login and admin pages The login and admin pages themselves are simple ASP pages, which contain a lot of code, as well as some text and visual elements. The main files in InternalSite that may be of interest to you are the following: Login.asp LogoffMsg.asp InstallAndDetect.asp Validate.asp PostValidate.asp InternalError.asp In addition, UAG keeps another version of some of the preceding files for ADFS, OTP, and OWA under similarly named folders. This means that if you have enabled the OWA theme on your portal, and you wish to customize it, you should work with the files under the /InternalSite/OWA folder. Of course, there are many other files that partake in the flow of each process, but the fact is there is little need to touch either the above or the others, as most of the appearance is controlled by a CSS template and text strings stored elsewhere. Certain requirements may even involve making significant changes to the layout of the pages, and leave you with no other option but to edit core ASP files themselves, but be careful as this introduces risk and is not technically supported. It's likely that these pages change with future updates to UAG, and that may cause a conflict with the older code that is in your files. The result of mixing old and new code is unpredictable, to say the least. The general appearance of the various admin pages is controlled by the file /InternalSite/CSS/template.css. This file contains about 80 different style elements including some of the 50 or so images displayed in the portal pages, such as the gradient background, the footer, and command buttons to name a few. The images themselves are stored in /InternalSite/Images. Both these folders have an OWA folder, which contains the CSS and images for the OWA theme. When editing the CSS, most of the style names will make sense, but if you are not sure, then why not copy the relevant ASP file and the CSS to your computer, so you can take a closer look with a visual editor, to better understand the structure. If you are doing this be careful not to make any changes that may alter the code in a damaging way, as this is easily done and can waste a lot of valuable time. A very useful piece of advice for checking tweaked code is to consider the use of Internet Explorer's integrated developer tool. In case you haven't noticed, it's a simple press of F12 on the keyboard and you'll find everything you need to get debugging. IE 9 and higher versions even pack a nifty trace module that allows you to perform low-level inspection on client-server interaction, without the need for additional third-party tools. We don't intend to devote this book to CSS, but one useful CSS element to be familiar with is the display: none; element, which can be used to hide any element it's put in. For example, if you add this to the .button element, it will hide the Login button completely. A common task is altering the part of the page where you see the Application and Network Access Portal text displayed. The text string itself can be edited using the master language files, which we will discuss shortly. The background of that part of the page, however, is built with the files headertopl.gif, headertopm.gif, and headertopr.gif. The original page design is classic HTML—it places headertopl on the left, headertopr on the right, and repeats headertopm in between to fill the space. If you need to change it, you could simply design a similar layout and put the replacement image files in /InternalSite/Images/CustomUpdate. Alternatively, you might choose to customize the logo only by copying the /InternalSite/Samples/logo.inc file into the /InternalSite/Inc/CustomUpdate folder, as this is where the HTML code that pertains to that area is located. Another thing that's worth noting is that if you create a custom CSS file, it takes effect immediately, and there's no need to do an activation. Well at least for the purposes of testing anyway. The same applies for image file changes too but as a general rule you should always remember to activate when finished, as any new configurations or files will need to be pushed into the TMG storage. Arrays are no exception to this rule either and you should know that custom files are only propagated to array members during an activation, so in this scenario, you do need to activate after each change. During development, you may copy the custom files to each member node manually to save time between activations, or better still, simply stop NLB on all array members so that all client traffic is directed to the one you are working on. An equally important point is that when you test changes to the code, the browser's cache or IIS itself may still retain files from the previous test or config, so if changes you've made do not appear first time around, then start by clearing your browser's cache and even reset IIS, before assuming you messed up the code. Customizing the portal As we said earlier, the pages that make up a portal and its various flavors are under the PortalHomePage folder. These are all ASP.NET files (.ASPX), and the scope for making any alterations here is very limited. However, the appearance is mostly controlled via the file /InternalSite/PortalHomePage/Standard.Master, which contains many visual parameters that you can change. For example, the DIV with ID content has a section pertaining to the side bar application list. You might customize the midTopSideBarCell width setting to make the bar wider or thinner. You can even hide it completely by adding style="display: none;" to the contentLeftSideBarCell table cell. As always, make sure you copy the master file to CustomUpdate, and not touch the original file, and as with the CSS files, any changes you make take effect immediately. Additional things that you can do with the portal are removing or adding buttons to the portal toolbar. For example, you might add a button to point to a help page that describes your applications, or a procedure to contact your internal technical support in case of a problem with the site.
Read more
  • 0
  • 0
  • 2710
article-image-using-playlist
Packt
23 Jun 2014
9 min read
Save for later

Using the Playlist

Packt
23 Jun 2014
9 min read
(For more resources related to this topic, see here.) You must use patterns that were made in the FL Studio step sequencer in order to build an original musical production from scratch. In this way, you build, overdub, and continually layer in order to come up with an original work. You may also insert full-length WAV or MP3 files and function exclusively as a recording studio, where you would then record vocals on top of the completed instrumental. You can chop any type of material (patterns or audio) in the playlist. So, in the end it may be a true fusion, mixture, and mash up of digital music. All files exist as channels. Using patterns to build a song If you were a writer who is writing a novel, you would start with a blank document and build your story with words and paragraphs. If you were a painter, you would start with a blank canvas and use markers or a paintbrush to build your creative vision. When working with FL Studio, you will be pasting your various patterns in the step sequencer in the FL Studio playlist. Getting ready… In order to start using the playlist, you need to have some data entered in your steps within channels and patterns on the step sequencer. You can press F5 or use the VIEW menu to bring up the playlist. Press Tab to toggle between the various windows that are open in FL Studio. How to do it… Let's look at two quick start methods to paste/paint patterns into the playlist: Quick start: Hover your mouse over the PAT box and drag it up/down to select a pattern number. Click on the playlist (F5) to paint it in. In Fig 5.1, the PAT box is shown to the right of the TEMPO button, with a value of 162.000. Alternative method: You may also click where it says Kick, next to the word Playlist in Fig 5.1. Not only will it bring up a list of patterns, but also show a list of all the automation clips and audio files created in the current project. Right-click on the same area to open up a really cool PROJECT PICKER window, where you can select your patterns or channels laid out in an awesome interface. Let's take a look at the multiple patterns being arranged using the following steps: Select a pattern in the step sequencer. Make sure you select the SONG mode, next to the transport controls in Fig 5.1. This will make your music project enter the SONG mode, and Play Position Marker (a small, orange-colored triangle) will be engaged when you press the Space bar to stop or play your project. Click with the Paint tool in the desired area in order to paste the pattern you have selected. You may also click-and-drag to the right with the Paint tool in order to smoothly paste the same pattern over and over again. Use the right-click button to erase patterns. The following screenshot shows that anything pasted in the Playlist section is like a small graphic of any given pattern in the step sequencer and the information inside it. You can see that the Hat and 303ish 2 patterns come in at bar 5. The 303ish 2 pattern shows Piano roll data because we have entered Piano roll data using a virtual instrument on that particular pattern. When you enter notes in the Piano roll on a given channel or pattern, the Playlist window will reflect this in order to help you see and organize your arrangement. The following screenshot shows the Playlist window: Fig 5.1 Click on the small square button next to the name of your pattern and then select the source pattern to populate and choose available patterns as per Fig 5.2. Once your patterns are pasted into the Playlist window, you will have the option to toggle between your patterns present in the list, as shown in the following screenshot: Fig 5.2 In the following screenshot, we have opened the pattern selector under the step sequencer by hovering our mouse on Kick. Your cursor will turn into a hand when you hover over Kick or any generic pattern name, indicating that the drop-down menu will get populated. Fig 5.3 How it works… By pasting your patterns (which have your channel steps or notes) in the playlist, you can form a full music production project. This happens when you click on the SONG mode, and the small play-position marker is engaged at the very start of the playlist on bar 1. Now, when you press the Space bar key, any pattern you paste into the playlist will be in time from left-to-right, and you can see the position pointer move along while highlighting the grid in time. A regular pattern when operating in the PAT mode will simply play your data and loop back to the beginning. You can stretch patterns to extremely long lengths by using the Piano roll, but you still have to paint your given pattern into the playlist. The area where you paste your patterns in the playlist will also be the area that is used to export your project into the rendered audio. There's more… You may also use the Slice tool directly (hover your mouse on the various tools at the upper left-hand corner of the playlist and look at the hint bar) in order to slice particular patterns and then edit or move them. Slicing is also exceedingly useful in the FL Studio Piano roll. If you select the Make unique option (shown in Fig 5.2), it will automatically create a new, unique pattern in the step sequencer. This can be handy if you want to tweak a pattern without navigating back to the step sequencer. This is also a great tool to remove part of your drums or incorporate a short silence to bring variety to your arrangement. Many times, you may want to slice off a certain part and then make it unique so that it becomes its own separate entity that you can mix later on. You can do this by pressing the Pattern clip drop-down box in Fig 5.2. This can prove handy because your song arrangement is affected and changed immediately. This method is used on any type of audio or samples. When working with vocals, you may want to make some of your pieces unique in order to change the volume of a specific word or add a different effect in the mixer. You may also paste any pattern you want, even if it has no steps or notes yet. This means that you can paste a blank pattern in the playlist; you can go to this pattern while your arrangement is playing and add your notes later. The longer you stretch your notes in a channel/pattern, the longer will your pattern automatically stretch in the playlist. If your pattern is currently playing or being triggered in the playlist, you will clearly see the LEDs of the playing step (orange slits) at the bottom of your step sequencer. A tremendous option when working with your arrangement is to double-click and drag your pattern where you see the numbers that represent the measures in your playlist and where the play position marker is located. When you do this, your selection will become in red color, and you can highlight the measure/sections that will be played and looped back around. This is handy to specify a particular area that you want to play back, which can then be edited and fine-tuned without listening to the whole song. If you only want to edit the intro, you can click-and-drag your mouse to highlight this area only. This feature allows you to specify which part of your song will play back and is helpful when adding/changing/revising/experimenting with pieces and parts, recording vocals, and drawing automation curves. Comparing patterns and audio The patterns that you paste into the FL Studio playlist reflect how you manage/arrange your project and decide which parts will play or not play during your song. This is easy to see on the FL Studio Playlist, where you will have a graphical readout of your patterns, audio, and automation clips. Audio clips will be shown on the playlist in a waveform readout, as will any type of MP3 or WAV file. Patterns in the playlist can stretch very far if your Piano roll is extended. Getting ready… In order start using the Playlist section and patterns, you need to have some data entered in your steps within the channels and patterns on the step sequencer. You may press F5 or use the VIEW menu to bring up the playlist. We will be working with a recorded vocal file. In some cases, your recording can show up directly on the FL Studio Playlist. How to do it… We will review the different types of patterns that are seen as specific images on the playlist using the following steps: Press the space bar key or click on play with your mouse on the FL Studio transport controls while in the SONG mode. Paste your patterns as discussed in the previous recipe of this article, Using patterns to build your song. If you have data in your steps and have not used the Piano roll on that channel, the data will be read out like the Hat pattern shown in Fig 5.4. If you have a channel/pattern that used a Piano roll, it will be similar to the 303ish 2 pattern in Fig 5.4. If you have vocals, an MP3 file, or a WAV file, it will show the audio data, as shown in Fig 5.4, next to Track 5 titled Vocals track 1 in the header. When working with automation clips, you will see automation curves and shapes as seen in the example in Fig 5.4. Fig 5.4 How it works… The readouts on various channels, patterns, audio data, and automation curves are a friendly way to keep your project organized and see exactly what is happening at specific moments (bars and beats) in time. You can use all of the features described in the previous recipe of this article, Using patterns to build your song. If you need to paste the same pattern multiple times in a row, you can use the paint tool and click-and-drag the pattern to the right. You can also use the Maximize / restore button to drag FL Studio's main window and drag audio files directly into the playlist. This restore button is shown in the following screenshot, directly to the left of the exit icon. You may click-and-drag an audio file from your desktop (or anywhere on your computer) into the FL Studio Playlist. The following screenshot shows the Maximize / restore button: Fig 5.5
Read more
  • 0
  • 0
  • 2710

article-image-facelets-templating-jsf-20
Packt
20 Jun 2011
7 min read
Save for later

Facelets Templating in JSF 2.0

Packt
20 Jun 2011
7 min read
One advantage that Facelets has over JSP is its templating mechanism. Templates allow us to specify page layout in one place, then we can have template clients that use the layout defined in the template. Since most web applications have consistent layout across pages, using templates makes our applications much more maintainable, since changes to the layout need to be made in a single place. If at one point we need to change the layout for our pages (add a footer, or move a column from the left side of the page to the right side of the page, for example), we only need to change the template, and the change is reflected in all template clients. NetBeans provides very good support for facelets templating. It provides several templates "out of the box", using common web page layouts. We can then select from one of several predefined templates to use as a base for our template or simply to use it "out of the box". NetBeans gives us the option of using HTML tables or CSS for layout. For most modern web applications, CSS is the preferred approach. For our example we will pick a layout containing a header area, a single left column, and a main area. After clicking on Finish, NetBeans automatically generates our template, along with the necessary CSS files. The automatically generated template looks like this: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="./resources/css/default.css" rel="stylesheet" type="text/css" /> <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" /> <title>Facelets Template</title> </h:head> <h:body> <div id="top" class="top"> <ui:insert name="top">Top</ui:insert> </div> <div> <div id="left"> <ui:insert name="left">Left</ui:insert> </div> <div id="content" class="left_content"> <ui:insert name="content">Content</ui:insert> </div> </div> </h:body> </html> As we can see, the template doesn't look much different from a regular Facelets file. Adding a Facelets template to our project We can add a Facelets template to our project simply by clicking on File | New File, then selecting the JavaServer Faces category and the Facelets Template file type. Notice that the template uses the following namespace: Java EE 6 Development with NetBeans 7" href="http://java.sun.com" target="_blank">http://java.sun.com/jsf/facelets. This namespace allows us to use the <ui:insert> tag, the contents of this tag will be replaced by the content in a corresponding <ui:define> tag in template clients. Using the template To use our template, we simply need to create a Facelets template client, which can be done by clicking on File | New File, selecting the JavaServer Faces category and the Facelets Template Client file type. After clicking on Next >, we need to enter a file name (or accept the default), and select the template that we will use for our template client. After clicking on Finish, our template client is created. <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="./template.xhtml"> <ui:define name="top"> top </ui:define> <ui:define name="left"> left </ui:define> <ui:define name="content"> content </ui:define> </ui:composition> </body> </html> As we can see, the template client also uses the Java EE 6 Development with NetBeans 7" href="http://java.sun.com" target="_blank">http://java.sun.com/jsf/facelets" namespace. In a template client, the <ui:composition> tag must be the parent tag of any other tag belonging to this namespace. Any markup outside this tag will not be rendered; the template markup will be rendered instead. The <ui:define> tag is used to insert markup into a corresponding <ui:insert> tag in the template. The value of the name attribute in <ui:define> must match the corresponding <ui:insert> tag in the template. After deploying our application, we can see templating in action by pointing the browser to our template client URL. Notice that NetBeans generated a template that allows us to create a fairly elegant page with very little effort on our part. Of course, we should replace the markup in the <ui:define> tags to suit our needs. Here is a modified version of our template, adding markup to be rendered in the corresponding places in the template: <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="./template.xhtml"> <ui:define name="top"> <h2>Welcome to our Site</h2> </ui:define> <ui:define name="left"> <h3>Links</h3> <ul> <li> <h:outputLink value="http://www.packtpub.com"> <h:outputText value="Packt Publishing"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.ensode.net"> <h:outputText value="Ensode.net"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.ensode.com"> <h:outputText value="Ensode Technology, LLC"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.netbeans.org"> <h:outputText value="NetBeans.org"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.glassfish. org"> <h:outputText value="GlassFish.org"/> </h:outputLink> </li> <li> <h:outputLink value="http://www.oracle.com/technetwork/ java/javaee/overview/index.html"> <h:outputText value="Java EE 6"/> </h:outputLink> </li> <li><h:outputLink value="http://www.oracle.com/ technetwork/java/index.html"> <h:outputText value="Java"/> </h:outputLink></li> </ul> </ui:define> <ui:define name="content"> <p> In this main area we would put our main text, images, forms, etc. In this example we will simply use the typical filler text that web designers love to use. </p> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc venenatis, diam nec tempor dapibus, lacus erat vehicula mauris, id lacinia nisi arcu vitae purus. Nam vestibulum nisi non lacus luctus vel ornare nibh pharetra. Aenean non lorem lectus, eu tempus lectus. Cras mattis nibh a mi pharetra ultricies. In consectetur, tellus sit amet pretium facilisis, enim ipsum consectetur magna, a mattis ligula massa vel mi. Maecenas id arcu a erat pellentesque vestibulum at vitae nulla. Nullam eleifend sodales tincidunt. Donec viverra libero non erat porta sit amet convallis enim commodo. Cras eu libero elit, ac aliquam ligula. Quisque a elit nec ligula dapibus porta sit amet a nulla. Nulla vitae molestie ligula. Aliquam interdum, velit at tincidunt ultrices, sapien mauris sodales mi, vel rutrum turpis neque id ligula. Donec dictum condimentum arcu ut convallis. Maecenas blandit, ante eget tempor sollicitudin, ligula eros venenatis justo, sed ullamcorper dui leo id nunc. Suspendisse potenti. Ut vel mauris sem. Duis lacinia eros laoreet diam cursus nec hendrerit tellus pellentesque. </p> </ui:define> </ui:composition> </body> After making the above changes, our template client now renders as follows: As we can see, creating Facelets templates and template clients with NetBeans is a breeze.
Read more
  • 0
  • 0
  • 2709
Modal Close icon
Modal Close icon