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

How-To Tutorials - Server-Side Web Development

406 Articles
article-image-introduction-moodle-modules
Packt
22 Nov 2010
8 min read
Save for later

Introduction to Moodle Modules

Packt
22 Nov 2010
8 min read
  Moodle 1.9 Top Extensions Cookbook Over 60 simple and incredibly effective recipes for harnessing the power of the best Moodle modules to create effective online learning sites Packed with recipes to help you get the most out of Moodle modules Improve education outcomes by situating learning in a real-world context using Moodle Organize your content and customize your courses Reviews of the best Moodle modules—out of the available 600 modules Installation and configuration guides Written in a conversational and easy-to-follow manner       Introduction Moodle is an open source Learning Management System (LMS). Image source: http://moodle.org/ The word Moodle is actually an acronym. The 'M' in Moodle stands for Modular and the modularity of Moodle has been one of the key aspects of its success. Being modular means you can: Add modules to your Moodle instance Selectively use the modules you need M.O.O.D.L.E. The acronym Moodle stands for Modular Object-Oriented Dynamic Learning Environment. It is modular because you can add and remove modules. The programming paradigm used to create Moodle code is Object-Oriented. It is dynamic because it can be used for information delivery and interactivity, in a changeable and flexible way. It is a learning environment designed for teaching at many levels. Because Moodle is modular and open source, many people have created modules for Moodle, and many of those modules are available freely for you to use. At time of writing, there are over 600 modules that you can download from the Moodle Modules and plugins database. Some of these are popular, well designed, and well maintained modules. Others are ideas that didn't seem to get off the ground. Some are contributed and maintained by large institutions, but most are contributed by individuals, often teachers themselves, who want to share what they have created. If you have an idea for something you would like to do with Moodle, it's possible that someone has had that idea before and has created and shared a module you can use. This article will show you how to download and test contributed Moodle modules, to see if they suit your needs. Origins of Moodle Moodle began in 1999 as postgraduate work of Martin Dougiamas, "out of frustration with the existing commercial software at the time". Considering the widespread use of Moodle around the world (over 40,000 registered sites in over 200 countries), Martin is a very humble man. If you ever make it to a MoodleMoot and Martin is in attendance, be sure to introduce yourself. A test server If you only want to test modules, consider setting up your own basic web server, such as XAMPP (http://www.apachefriends.org/en/xampp.html) and installing Moodle from the Moodle Downloads page (http://download.moodle.org/). If you are a Windows or Mac user, you can even download and install Moodle packages where these two ingredients are already combined and ready to go. Once installed, add a course or two. Create some dummy students to see how modules work within a course. Have a play around with the modules available—Moodle is quite hard to break—don't be afraid to experiment. Getting modules you can trust The Moodle Modules and plugins database is filled with modules great and small. This article will help you to know how you can find modules yourself. Getting ready You may have an idea in mind, or you may just want to see what's out there. You'll need a web browser and an active Internet connection. How to do it... Point your browser to the Moodle Modules and plugins database. Refer http://moodle.org/mod/data/view.php?id=6009: Image source: http://moodle.org/mod/data/view.php?id=6009 As you scroll down you will see list of modules that can be downloaded. At the bottom of the page is a Search facility: Image source: http://moodle.org/mod/data/view.php?id=6009 You can also try an advanced search to get more specific about the following: What type of module you want What version of Moodle you have A number of other features The following is a search result for the term 'progress': Image source: http://moodle.org/mod/data/view.php?id=6009 Each entry has a type, the version of Moodle that it is compatible with, and a brief description. Clicking on the name of the module will take you to a page with details about the module. This is the module's 'entry': Image source: http://moodle.org/mod/data/view.php?d=13&rid=2524&filter=1 On each entry page there is a wealth of information about the module. The following is a list of questions you will want to answer when determining if the module is worth testing. Will it work with your version of Moodle? Is documentation provided? When was the module released and has there been activity (postings on the page below) since then? Is the module author active in the discussion about the module? Is the discussion positive (don't be too discouraged by bug reports if the author is involved and reporting that bugs have been fixed)? From discussion, can you tell if the module is widely used with a community of users behind it? What is the rating of the module? If you are happy with your answers to these questions, then you may have found a useful module. Be wary of modules that do what you want, but are not supported; you may be wasting your time and putting the security of your system and the integrity your teaching at risk. There's more... Here is some additional information that may help you on a module hunt. Types of modules In order to get a sense of how modules will work, you need to have an understanding of the distinction between different module types. The following table describes common module types. Amid the array of modules available, the majority are blocks and activity modules. Activity moduleActivity modules deliver information or facilitate interactivity within a course. Links to activity modules are added on a course main page and the activity module itself appears on a new page when clicked. Examples in the core installation are 'Forums' and 'Quizzes'.Assignment typeAssignment types are a specific type of activity module that focus on assessable work. They are all based on a common assignment framework and appear under 'Assignments' in the activities list. Examples in the core installation are 'Advanced upload of files' and 'Online text' assignments.BlockBlocks usually appear down each side of a course main page. They are usually passive, presenting specific information, and links to more information and activities. A block is a simpler type of module. Because they are easy to create, there are a large number of these in the Modules and Plugins database. Examples in the core installation are the 'Calendar' and 'Online Users' blocks.Course formatA course format allows the structure of a course main page to be changed to reflect the nature of the delivery of the course, for example, by schedule or by topic.FilterFilters allow targeted text appearing around a Moodle site to be replaced with other content, for example, equations, videos, or audio clips.IntegrationAn integration module allows Moodle to make use of systems outside the Moodle instance itself.Question typeWithin a quiz, question types can be added to enable different forms of questions to be asked. Checking your version If you are setting up your own Moodle instance for teaching or just for testing, take note of the version you are installing. If you have access to the Site Administration interface (the Moodle site root page when logged in as an administrator), clicking on Notifi cations will show you the version number near the bottom, for example Moodle 1.9.8 (Build: 20100325). The first part of this is the Moodle version; this is what you need when searching through modules on the Modules and plugins database. The second part, labeled "Build" shows the date when the installed version was released in YYYYMMDD format. This version information reflects what is stored in the /version.php file. If you are not the administrator of your system, consult the person who is. They should usually be able to tell you the version without looking it up. Moodle 2.0 The next version of Moodle to follow version 1.9 has been "on the cards" for some time. The process of installing modules will not change in the new version, so most of the information in this book will still be valid. You will need to look for versions of modules ready for Moodle 2.0 as earlier versions will not work without adjustment. As modules are usually contributed by volunteers, there may be some waiting before this happens; the best way to encourage this re-development is to suggest an improvement for the module on the Moodle bug tracker system at http://tracker.moodle.org/. See also Adding modules to Moodle
Read more
  • 0
  • 0
  • 2931

article-image-moodle-20-multimedia-working-2d-and-3d-maps
Packt
08 Jun 2011
12 min read
Save for later

Moodle 2.0 Multimedia: Working with 2D and 3D Maps

Packt
08 Jun 2011
12 min read
  Moodle 2.0 Multimedia Cookbook Add images, videos, music, and much more to make your Moodle course interactive and fun         Read more about this book       (For more resources on Moodle 2.0, see here.) Introduction Whenever you think of a map, you may either think of the traditional planisphere or the terrestrial globe. There are several types of maps apart from those previously mentioned. We can work with maps of the moon, Mars, constellations, and even the universe! Thus, we are not only going to focus on our planet, but we are going to travel even further! The topic of this article is going to deal with Traveling Around the World and Watching the Universe. After reading this article, you can focus on your next holiday! We explain how to work with different types of maps. We are going to be as creative as possible. We should try to work with maps in an unconventional way. That is to say, the idea is to use a map for a Geography class, but we can use maps as a resource for any type of activity. Thus, we can work with the Geography teacher and he/she could work on another geographical feature of the place that we are working with. Therefore, in that way, we are adding more information to the place we are exploring. Maps are very attractive and they may become quite appealing to our students as long as we find a way to develop a rich activity using them. We should encourage the use of maps and the available resources that we have on the Web so that they can insert them in their homework by themselves as well. Thus, we can develop the activities in such a way that we can either provide the map or ask them to design a map. We can also work with maps in the case of Literature. We can ask students to draw a map of a place that has never existed in the real world, though it did in a story. Thus, another bit of homework that could prove helpful would be for students to design and carry out the map of such a place using the tools that we are going to explore in the following recipes. An example of this could be to draw the map of the country Ruritania and locate the cities of Zenda and Strealsau. These places do not exist in the real world, but they exist in the book The Prisoner of Zenda by Anthony Hope. So, many things can be done with maps. Creating maps with sceneries In this activity, we are going to create a map with sceneries. Therefore, we could either browse our files for pictures from our trips or holidays, or we can search for sceneries on the Web. After selecting the pictures, we create a new folder in Windows Explorer, for example C:Images_Traveling. In this folder, we save all the pictures so as to organize our work. We will use the following well-known website: http://earth.google.com/ to design a map using the pictures we have saved in the folder that we have just created. Let's get ready! Getting ready In this activity, we will work with the previously mentioned website. Therefore, we need to open the web browser and enter it. Click on Download Google Earth 6. Read the Google Maps/Earth Terms of Service and if you agree, click on Agree and Download. The icon of Google Earth will appear on your desktop, as shown in the following screenshot: How to do it... We have already carried out the first steps for this activity. Now, we have to design the maps with the pictures that we want to add. There are also some pictures that are available in the maps; you can also work with them, though the aim of this activity is to upload images in the map. Follow these steps in order to create a folder and find images for the activity: Click on the icon on your desktop and open Google Earth. Bring the Earth closer with the icons on the right. Locate a remote city in the southern hemisphere, as shown in the following screenshot: In the Fly to block, write "Mar del Plata", or any other remote city. Then press Enter or click on the magnifying glass next to the block. You will travel virtually to the desired city. Bring the map forward and locate the place where the picture to be uploaded was taken. Click on Add | Photo. Complete the Name block. Click on Browse. Search for the picture that you want to upload and click on it. Complete the other blocks: Description | View | Photo. Click on OK. The picture will appear, as shown in the following screenshot: You can repeat the same process as many times as the number of pictures you want to upload. After uploading all the pictures, click on File | Save | Save Image, as shown in the following screenshot: Complete the File name block and click on Save. How it works... After uploading the desired pictures to the map, we can create an activity. We could start this course with a little social interaction. We ask our students to think about what element they shouldn't forget if they happen to go to this place. They may not know this city, for sure, unless they live nearby. This is the most interesting part of inserting a remote city that they may want to know more about it! Therefore, a Chat is a good idea to have where all the students will be invited in order to discuss the city. We upload the map that we have created with the images to our activity within the Moodle course. Choose the weekly outline section where you want to insert this activity and follow these steps: Click on Add an activity | Chat. Complete the Name of this chat room and Introduction text blocks. Click on the Insert/edit image icon | Find or upload an image | Browse and look for the image that we have just saved. Click on Upload this file. Complete the Image description block and click on Insert. Click on Save and return to course. The activity looks as shown in the following screenshot: Drawing regions within a map In this activity, we are going to use an interactive website in which we choose a map to work with. It is a very simple one, but we could enhance it by adding interesting ingredients to the recipe. We will use a software for drawing a region on the map, and highlight a region for our students to work with. As it was pointed out before, we are not going to focus on geographical features, though you can add this ingredient yourself when designing the activity. Getting ready We open our default web browser and work with the following website: http://www.fusioncharts.com/maps/Default.asp. We click on Map Gallery and choose a map to work with. In this case, we choose a map of the world and highlight five regions, one for each continent. You can modify it and work with different regions within a continent or a country too. How to do it... We look for the desired map. We can find different types of maps to work with. Everything depends on what type of activity we have in mind. In this case, as the topic of this article has to do with traveling, we circle five regions and ask our students to choose where they would like to go. First of all, we have to find the map and save it as an image so that we can draw the regions and upload it to our Moodle course. Therefore, follow these steps: Click on click here | World Map with countries on the aforementioned site. Another pop-up window appears, displaying a map of the world with the countries. There appears a Map Configuration block where you can customize some features, as shown in the next screenshot. Click on Save Map as Image, as shown in the following screenshot: Another pop-up window will appear. Click on Save. Complete the File name block. Click on Save. Click on Open. A pop-up window displaying the map will appear. Click on File | Copy. Paste the map in Paint or Inkscape. Click on Edit | Paste from and browse for the name of the file. Select the file and click on Open. Use the resources available to draw the regions that you want students to work with, as shown in the following screenshot: Click on File | Save as and write a name for the file. Click on Save. How it works... We have already drawn the regions that we want our students to work with. We have chosen one country from every continent; you can choose another or design it in a different way. We can add a writing activity in which students choose where they would like to travel using the previous map. Select the weekly outline section where you want to add the activity and follow these steps: Click on Add an activity | Upload a single file within Assignments. Complete the Assignment name and Description blocks. Click on the Insert/edit image icon | Find or upload an image | Browse. When you find the image that you want to upload, click on Open | Upload this file. Complete the Image description block. Click on Insert. Click on Save and return to course. The activity is ready! When students click on the activity, it looks as shown in the following screenshot: Labeling a map with pins In this recipe, we will learn how to insert a map in our Moodle course labeled with pins, because we pin all the cities that we are going to work with. Therefore, we insert the map as a resource. After that, we design activities for our students to use the interactive map that we have just added. It is another way to use a resource, making our Moodle course more appealing to the eyes of our students. Getting ready We are going to work with Google Earth, as we did in the first recipe, so we have already installed it. We should think of the cities to insert in our course because we need to pin them all! How to do it... Click on the Google Earth icon that you have on your desktop. This is a way to enrich our traveling course by enhancing its appearance. So, these are the steps that you have to follow: Complete the Fly to block with the place that you want to pin. Click on the yellow pin, as shown in the following screenshot: A pop-up window will appear. Complete the Name block by writing the name of the city. Check the Latitude and Longitude, so that you place the pin correctly. You may complete the Description block. You can change the appearance of the pin by clicking on the pin itself. Another pop-up window will appear showing different sorts of icons, as shown in the following screenshot: You can choose the desired icon by clicking on it | OK. The icon that you have selected will appear in the map. Pin as many cities as you are going to work with and repeat steps 1-7. After pinning all the cities, save the file. Click on File | Save | Save Place as. Complete the File name block (remember to save the file in the folder which was created for this course) | Save. You have already saved the pinned map. How it works... We have to insert the map in our Moodle course. In this case, we are going to Add a resource, because we are introducing all the activities that are to come. So, choose the weekly outline section where you want to save the resource. These are the steps that you have to follow: Click on Add a resource | File. Complete the Name and Description blocks. Click on Add | Browse. Click on the file that you are going to upload | Open | Upload this file | Save and return to course. Although we have added a file, students can work with the map interactively! There's more We can embed the map in an HTML block in our Moodle course. Click on the downwards arrow next to Add... in Add a block, as shown in the following screenshot: Choose HTML and a new block will appear in our Moodle course. Embedding a map in an HTML block Open Google Earth and follow these steps in order to embed the map in the block that we have already added: Click on the View in Google Maps icon, as shown in the following screenshot: Another window appears. Click on Link | Customize and preview embedded map, as shown in the following screenshot: Click on Custom and adjust the Width and Height. In the Preview section, click on the minus sign and adjust the map to fit the window. Copy the HTML code to embed in our Moodle course. Go back to the Moodle course and click on the configuration icon to embed the map. Complete the Block title. In the Content block, click on the HTML icon, paste the HTML code which was copied, and click on Update. Click on Save changes. The map will look as shown in the following screenshot:
Read more
  • 0
  • 0
  • 2904

article-image-moodle-makeover
Packt
26 Oct 2009
6 min read
Save for later

Moodle Makeover

Packt
26 Oct 2009
6 min read
What we will do, is: Do more than make each topic a long list of resources. Use the label resource and Moodle's indenting tool to change this: To this: Find out where we can get lots of free images for our courses. Explore different ways to use HTML to make our courses even more engaging. Include a talking character—an animated avatar—using Voki.com: Arrange Your Resources Why is it important to spend a little time arranging resources in a topic? Isn't it all eye candy? Let's take a look at my Topic 1: I've got a nice colorful title, some text to introduce the topic, and then a long list of resources—which, quite honestly looks just like the list of files in the shared drive I already use to distribute my documents and handouts to students. What if the topic looked like this: This is much more the effect we need. I've reordered my resources and included some labels, so that it is much easier for students to find a resource. In this section, we're going to learn how to bring some order into our topics. Putting Your Resources in Order One obvious difference between a shared drive and Moodle is that in Moodle, you can put the resources in the order you want, not the order the computer insists on (usually, numerical/alphabetical). However, in Moodle, any new resources you add are simply queued on to the end of the topic. This has meant that resources in my Getting Things Flying topic aren't exactly ordered in a sensible way—just the way I added them. I'm going to take action to remedy that now... Time for Action – Arrange Your Resources Remember that you need editing turned on before you start. Choose the resource you want to move. I'm going to move my Backyard ballistics links resource to the end of the topic. To start the process, I need to 'pick up' the resource. I click on the Move icon: This causes two things to happen. Firstly, the resource I want to move disappears. Don't worry—imagine you have it in your hand and you are ready to place it back into your course. Secondly, the boxes that have now appeared represent all the places to which you can move the resource that you are holding: Choose where you want to move the resource to. I want my list of links at the end, so I'm going to click on the box at the bottom. The boxes disappear and my resources have been shuffled: What Just Happened? A list o f resources in Moodle isn't simply a list of files, like you would find on a shared drive. One obvious difference is that in Moodle, you can arrange your resources to be listed in the order you want, and we've just seen how easy it is to achieve this. You can't find the Move icon? Your site may be configured so that you can drag and drop resources. In that case, instead of the Move icon you will see crosshairs next to your resource. To move the resource, click on the cross hairs and, keeping your finger pressed down on the left mouse butt on, drag the resource to its new location. Look for the line in the background—this tells you where your resource is going to be dropped to—then let go of the mouse butt on when you have found the spot. Now I've got my resources in the order I wanted, I have to say that my topic looks like just another resource dump—which is what I am trying to avoid. My resources would be much easier to use if I could introduce each of them with a short piece of text: Introducing a resource with a short introduction is a great way of improving the visual appeal of your course. The tool to achieve this is called a Label resource, and here's how to use it... Time for Action – Insert a Label I'm going to start the process of arranging my resource by having a short piece of text introducing the Backyard ballistics links resource. Make sure editing is turned on, click on Add a resource, and choose Insert a label. In the Editing Label page, enter your label text. When you are done, press the Save and return to course button. The new label is added to the end of the list of resources—which is obviously the wrong place for it. Click on the Move icon, next to the label you have just added: The page is re-displayed. Your new label disappears and lots of boxes have appeared. These boxes represent the places where your new label can go: Click on the relevant box to place your label. You're done! Remember: If you don't have a Move icon, you'll have crosshairs next to the label that you can click on to drag it to the right place. What Just Happened? After all the experience we have had with Moodle so far, using the label resource will be fairly straightforward. Judicious use of labels means our course topics don't have to be simply a long list of resources. Remember to treat labels as a way of leading the student towards and into a resource. Labels are not designed for content, so try to keep labels short—perhaps two or three sentences at the most. Labels are like the glue that holds topics together. You don't want your glue to be too thick. It's looking better, but my topic is still looking a little flat. You can indent your resources by clicking on the Move right icon next to the resource: Below is how things now look with a little indenting: Seeing the course from a student's point of viewAs a teacher, you will see a lot of options on the screen that your students won't. To get a clear idea of how a student will see the course, use the Switch role to… option at the top right of the screen. Choose Student from this list, and you will see the course as students see it.When you're done, click Return to my normal role and you'll get your normal view back. You will also need to Turn editing on to get the edit controls back.
Read more
  • 0
  • 0
  • 2888

article-image-less-css-preprocessor
Packt
21 May 2013
7 min read
Save for later

LESS CSS Preprocessor

Packt
21 May 2013
7 min read
(For more resources related to this topic, see here.) Installing LESS We're going to start the recipes in this book by looking at how we can get hold of LESS, and adding support for it to your website. LESS comes in two versions, depending on whether you want to use it client side or server side; for the purpose of this recipe, we're going to use it client side. The library is hosted on Google Code, and can be downloaded or included (as a CDN link) from http://cdnjs.cloudflare.com/ajax/libs/less.js/1.3.1/less. min.js. How to do it... The following steps will guide you in installing LESS: Let's get started by creating a new folder on your PC, let's call it test less projects. Crack open a normal text editor of your choice, save a copy of the code from the What you need for this book section in the preface of this book, and save it as test less include.html. Add the following in between the <body> tags in the code: <form action="">Name: <input type="text" class="input" />Password: <input type="password" class="input" /><input type="submit" value="This is a button" /></form> It shows a very plain, basic form, so let's fix that by starting to use LESS to provide some styling. Create a new document in your text editor, then add the following, and save it as include.less: @color-button: #d24444;#submitfrm {color:#fff;background:@color-button;border:1px solid @color-button - #222;padding:5px 12px;} Let's now add a link to this file to your main HTML file, so go ahead and alter your code accordingly: <link rel="stylesheet/less" type="text/css" href="include.less"> That's all that's required, so if you now open your browser, and view the file, you should see on screen the same as the following screenshot: How it works... This recipe was intended to serve as a very basic example of how you can use less.js. You will be already familiar with what most of the code does, with two exceptions (highlighted in the following code snippet): @color-button: #d24444;#submitfrm {color:#fff;background:@color-button;border:1px solid @color-button - #222;padding:5px 12px;} The first exception is simply setting a variable called color-button, which holds a value of #d24444; this is the red background you see on the button. There are a couple of points of interest here: All variables used in LESS must be preceded with an @ sign, to denote that they are variables Variables don't actually exist in the LESS library Huh? I hear you ask. That surely doesn't make sense! Well, let me explain: when using LESS, variables are actually classed as constants, as you can't reassign a new value to an existing predefined variable. There is nothing stopping you from using an existing variable to calculate a new value, but that value must be assigned to a new variable, or used to work out a value for a CSS style: background:@ color-button;border: 1px solid @color-button - #222;padding: 5px 12px; There's more... In order for the library to work properly, you need to first include links to your .less stylesheets, and set the rel tag to stylesheet/less, in order for them to work properly: <link rel="stylesheet/less" type="text/css" href="styles.less"> Note the use of the rel attribute on this link, you need to use the /less value, in order for LESS to work properly. If you are using HTML5 syntax, you don't need to include the type="text/less" and type="text/javascript" values. Next, you need to include LESS; you can either download it from the website and include it locally in the same way that you would include any JavaScript file, or use the following CDN link; in either case, you must include it after your .less stylesheet: <script src = "http://cdnjs.cloudflare.com/ajax/libs/less.js/1.3.1/less.min.js"></script> If you get a 406 error in your browser, you may need to set a MIME (or Internet Media Type, as it is now known), as the text/LESS tags may not work properly. We've seen how LESS can compile styles on the fly, but this may not be ideal if you have a very large site, or have a development process which doesn't allow the use of creating styles dynamically. This isn't an issue with LESS, as you can easily generate the stylesheet prior to including it within your site's pages. Precompiling LESS client side In the previous section, we looked at how you can use Less to dynamically generate your compiled stylesheet from within your site. This may not suit everyone's needs. Here, we will see some alternatives that allow us to precompile our CSS styles, so we can then include the finished results on our site. Getting ready Here we're going to use the open source application WinLESS to compile a LESS file into a normal CSS stylesheet. You can download a copy of the program from http://www.winless.org. You will also need your favorite text editor. We're going to create a typical .less file. How to do it... Open up the text editor of your choice, and add in the following lines; save it as testprecompile.less in the folder you created from the Installing LESS section: .border-radius(@radius: 3px) { -webkit-border-radius: @radius;-moz-border-radius: @radius; border-radius: @radius; }.box-shadow(@x : 2px, @y : 2px, @blur : 5px, @spread : 0, @color :rgba(0,0,0,.6)) {-webkit-box-shadow: @x @y @blur @spread @color;-moz-box-shadow: @x @y @blur @spread @color;box-shadow: @x @y @blur @spread @color;}div { @color: green; background: @color; width: 300px; height:300px; margin: 30px auto; .border-radius(10px); .box-shadow(); } Double-click on the WinLess_1.5.3.msi file you downloaded to install it, accept all defaults, and double-click on it to open the application. Click on the Add folder button, and select the folder you created in the first step, and click on OK to add it to the folder list of WinLess. Click on the Refresh folder button to update the list on the right-hand side as shown in the following screenshot: Click on Compile to generate the CSS file; if you open the resulting CSS file, you will see the generated code as follows: div {background: #008000;width: 300px;height: 300px;margin: 30px auto;-webkit-border-radius: 10px;-moz-border-radius: 10px;border-radius: 10px;-webkit-box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.6);-moz-box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.6);box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.6);} As you make further changes to the .less file, WinLess will automatically update the CSS file for you; it will remain in the same folder as the .less file, until you are ready to use it in a production environment. How it works... WinLess is GUI front-ends to the command-line version of LESS, lessc.cmd. The GUI takes the content of the .less file, parses it, and gives a .css file as the output with the compiled CSS styles. WinLess includes an option to maintain a list of files that it will automatically monitor, so that when any are changed, it will automatically update the contents of the equivalent CSS file with the appropriate changes. Summary In this article we saw how to install support for LESS and how to compile CSS styles before adding adding the code to your website. Resources for Article : Further resources on this subject: Drupal 6 Theming: Adding and Optimizing CSS Files [Article] Building our own Plone 3 Theme Add-on Product [Article] Creating Themes for a Report using BIRT [Article]
Read more
  • 0
  • 0
  • 2876

article-image-working-user-interface
Packt
16 Sep 2015
17 min read
Save for later

Working on the User Interface

Packt
16 Sep 2015
17 min read
In this article by Fabrizio Caldarelli, author of the book Yii By Example, will cover the following topics related to the user interface in this article: Customizing JavaScript and CSS Using AJAX Using the Bootstrap widget Viewing multiple models in the same view Saving linked models in the same view It is now time for you to learn what Yii2 supports in order to customize the JavaScript and CSS parts of web pages. A recurrent use of JavaScript is to handle AJAX calls, that is, to manage widgets and compound controls (such as a dependent drop-down list) from jQuery and Bootstrap. Finally, we will employ jQuery to dynamically create more models from the same class in the form, which will be passed to the controller in order to be validated and saved. (For more resources related to this topic, see here.) Customize JavaScript and CSS Using JavaScript and CSS is fundamental to customize frontend output. Differently from Yii1, where calling JavaScript and CSS scripts and files was done using the Yii::app() singleton, in the new framework version, Yii2, this task is part of the yiiwebView class. There are two ways to call JavaScript or CSS: either directly passing the code to be executed or passing the path file. The registerJs() function allows us to execute the JavaScript code with three parameters: The first parameter is the JavaScript code block to be registered The second parameter is the position where the JavaScript tag should be inserted (the header, the beginning of the body section, the end of the body section, enclosed within the jQuery load() method, or enclosed within the jQuery document.ready() method, which is the default) The third and last parameter is a key that identifies the JavaScript code block (if it is not provided, the content of the first parameter will be used as the key) On the other hand, the registerJsFile() function allows us to execute a JavaScript file with three parameters: The first parameter is the path file of the JavaScript file The second parameter is the HTML attribute for the script tag, with particular attention given to the depends and position values, which are not treated as tag attributes The third parameter is a key that identifies the JavaScript code block (if it's not provided, the content of the first parameter will be used as the key) CSS, similar to JavaScript, can be executed using the code or by passing the path file. Generally, JavaScript or CSS files are published in the basic/web folder, which is accessible without restrictions. So, when we have to use custom JavaScript or CSS files, it is recommended to put them in a subfolder of the basic/web folder, which can be named as css or js. In some circumstances, we might be required to add a new CSS or JavaScript file for all web application pages. The most appropriate place to put these entries is AppAsset.php, a file located in basic/assets/AppAsset.php. In it, we can add CSS and JavaScript entries required in web applications, even using dependencies if we need to. Using AJAX Yii2 provides appropriate attributes for some widgets to make AJAX calls; sometimes, however, writing a JavaScript code in these attributes will make code hard to read, especially if we are dealing with complex codes. Consequently, to make an AJAX call, we will use external JavaScript code executed by registerJs(). This is a template of the AJAX class using the GET or POST method: <?php $this->registerJs( <<< EOT_JS // using GET method $.get({ url: url, data: data, success: success, dataType: dataType }); // using POST method $.post({ url: url, data: data, success: success, dataType: dataType }); EOT_JS ); ?> An AJAX call is usually the effect of a user interface event (such as a click on a button, a link, and so on). So, it is directly connected to jQuery .on() event on element. For this reason, it is important to remember how Yii2 renders the name and id attributes of input fields. When we call Html::activeTextInput($model, $attribute) or in the same way use <?= $form->field($model, $attribute)->textInput() ?>. The name and id attributes of the input text field will be rendered as follows: id : The model class name separated with a dash by the attribute name in lowercase; for example, if the model class name is Room and the attribute is floor, the id attribute will be room-floor name: The model class name that encloses the attribute name, for example, if the model class name is Reservation and the attribute is price_per_day, the name attribute will be Reservation[price_per_day]; so every field owned by the Reservation model will be enclosed all in a single array In this example, there are two drop-down lists and a detail box. The two drop-down lists refer to customers and reservations; when user clicks on a customer list item, the second drop-down list of reservations will be filled out according to their choice. Finally, when a user clicks on a reservation list item, a details box will be filled out with data about the selected reservation. In an action named actionDetailDependentDropdown():   public function actionDetailDependentDropdown() { $showDetail = false; $model = new Reservation(); if(isset($_POST['Reservation'])) { $model->load( Yii::$app->request->post() ); if(isset($_POST['Reservation']['id'])&& ($_POST['Reservation']['id']!=null)) { $model = Reservation::findOne($_POST['Reservation']['id']); $showDetail = true; } } return $this->render('detailDependentDropdown', [ 'model' => $model, 'showDetail' => $showDetail ]); } In this action, we will get the customer_id and id parameters from a form based on the Reservation model data and if it are filled out, the data will be used to search for the correct reservation model to be passed to the view. There is a flag called $showDetail that displays the reservation details content if the id attribute of the model is received. In Controller, there is also an action that will be called using AJAX when the user changes the customer selection in the drop-down list:   public function actionAjaxDropDownListByCustomerId($customer_id) { $output = ''; $items = Reservation::findAll(['customer_id' => $customer_id]); foreach($items as $item) { $content = sprintf('reservation #%s at %s', $item->id, date('Y-m-d H:i:s', strtotime($item- >reservation_date))); $output .= yiihelpersHtml::tag('option', $content, ['value' => $item->id]); } return $output; } This action will return the <option> HTML tags filled out with reservations data filtered by the customer ID passed as a parameter. If the customer drop-down list is changed, the detail div will be hidden, an AJAX call will get all the reservations filtered by customer_id, and the result will be passed as content to the reservations drop-down list. If the reservations drop-down list is changed, a form will be submitted. Next in the form declaration, we can find the first of all the customer drop-down list and then the reservations list, which use a closure to get the value from the ArrayHelper::map() methods. We could add a new property in the Reservation model by creating a function starting with the prefix get, such as getDescription(), and put in it the content of the closure, or rather: public function getDescription() { $content = sprintf('reservation #%s at %s', $this>id, date('Y-m-d H:i:s', strtotime($this>reservation_date))); return $content; } Or we could use a short syntax to get data from ArrayHelper::map() in this way: <?= $form->field($model, 'id')->dropDownList(ArrayHelper::map( $reservations, 'id', 'description'), [ 'prompt' => '--- choose' ]); ?> Finally, if $showDetail is flagged, a simple details box with only the price per day of the reservation will be displayed. Using the Bootstrap widget Yii2 supports Bootstrap as a core feature. Bootstrap framework CSS and JavaScript files are injected by default in all pages, and we could use this feature even to only apply CSS classes or call our own JavaScript function provided by Bootstrap. However, Yii2 embeds Bootstrap as a widget, and we can access this framework's capabilities like any other widget. The most used are: Class name Description yiibootstrapAlert This class renders an alert Bootstrap component yiibootstrapButton This class renders a Bootstrap button yiibootstrapDropdown This class renders a Bootstrap drop-down menu component yiibootstrapNav This class renders a nav HTML component yiibootstrapNavBar This class renders a navbar HTML component For example, yiibootstrapNav and yiibootstrapNavBar are used in the default main template.   <?php NavBar::begin([ 'brandLabel' => 'My Company', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', ], ]); echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar- right'], 'items' => [ ['label' => 'Home', 'url' => ['/site/index']], ['label' => 'About', 'url' => ['/site/about']], ['label' => 'Contact', 'url' => ['/site/contact']], Yii::$app->user->isGuest ? ['label' => 'Login', 'url' => ['/site/login']] : ['label' => 'Logout (' . Yii::$app->user- >identity->username . ')', 'url' => ['/site/logout'], 'linkOptions' => ['data-method' => 'post']], ], ]); NavBar::end(); ?> Yii2 also supports, by itself, many jQuery UI widgets through the JUI extension for Yii 2, yii2-jui. If we do not have the yii2-jui extension in the vendor folder, we can get it from Composer using this command: php composer.phar require --prefer-dist yiisoft/yii2-jui In this example, we will discuss the two most used widgets: datepicker and autocomplete. Let's have a look at the datepicker widget. This widget can be initialized using a model attribute or by filling out a value property. The following is an example made using a model instance and one of its attributes: echo DatePicker::widget([ 'model' => $model, 'attribute' => 'from_date', //'language' => 'it', //'dateFormat' => 'yyyy-MM-dd', ]); And, here is a sample of the value property's use: echo DatePicker::widget([ 'name' => 'from_date', 'value' => $value, //'language' => 'it', //'dateFormat' => 'yyyy-MM-dd', ]); When data is sent via POST, the date_from and date_to fields will be converted from the d/m/y to the y-m-d format to make it possible for the database to save data. Then, the model object is updated through the save() method. Using the Bootstrap widget, an alert box will be displayed in the view after updating the model. Create the datePicker view: <?php use yiihelpersHtml; use yiiwidgetsActiveForm; use yiijuiDatePicker; ?> <div class="row"> <div class="col-lg-6"> <h3>Date Picker from Value<br />(using MM/dd/yyyy format and English language)</h3> <?php $value = date('Y-m-d'); echo DatePicker::widget([ 'name' => 'from_date', 'value' => $value, 'language' => 'en', 'dateFormat' => 'MM/dd/yyyy', ]); ?> </div> <div class="col-lg-6"> <?php if($reservationUpdated) { ?> <?php echo yiibootstrapAlert::widget([ 'options' => [ 'class' => 'alert-success', ], 'body' => 'Reservation successfully updated', ]); ?> <?php } ?> <?php $form = ActiveForm::begin(); ?> <h3>Date Picker from Model<br />(using dd/MM/yyyy format and italian language)</h3> <br /> <label>Date from</label> <?php // First implementation of DatePicker Widget echo DatePicker::widget([ 'model' => $reservation, 'attribute' => 'date_from', 'language' => 'it', 'dateFormat' => 'dd/MM/yyyy', ]); ?> <br /> <br /> <?php // Second implementation of DatePicker Widget echo $form->field($reservation, 'date_to')- >widget(yiijuiDatePicker::classname(), [ 'language' => 'it', 'dateFormat' => 'dd/MM/yyyy', ]) ?> <?php echo Html::submitButton('Send', ['class' => 'btn btn- primary']) ?> <?php $form = ActiveForm::end(); ?> </div> </div> The view is split into two columns, left and right. The left column simply displays a DataPicker example from the value (fixed to the current date). The right column displays an alert box if the $reservation model has been updated, and the next two kinds of widget declaration too; the first one without using $form and the second one using $form, both outputting the same HTML code. In either case, the DatePicker date output format is set to dd/MM/yyyy through the dateFormat property and the language is set to Italian through the language property. Multiple models in the same view Often, we can find many models of same or different class in a single view. First of all, remember that Yii2 encapsulates all the views' form attributes in the same container, named the same as the model class name. Therefore, when the controller receives the data, these will all be organized in a key of the $_POST array named the same as the model class name. If the model class name is Customer, every form input name attribute will be Customer[attributeA_of_model] This is built with: $form->field($model, 'attributeA_of_model')->textInput(). In the case of multiple models of the same class, the container will again be named as the model class name, but every attribute of each model will be inserted in an array, such as: Customer[0][attributeA_of_model_0] Customer[0][attributeB_of_model_0] … … … Customer[n][attributeA_of_model_n] Customer[n][attributeB_of_model_n] These are built with: $form->field($model, '[0]attributeA_of_model')->textInput(); $form->field($model, '[0]attributeB_of_model')->textInput(); … … … $form->field($model, '[n]attributeA_of_model')->textInput(); $form->field($model, '[n]attributeB_of_model')->textInput(); Notice that the array key information is inserted in the attribute name! So when data is passed to the controller, $_POST['Customer'] will be an array composed by the Customer models and every key of this array, for example, $_POST['Customer'][0] is a model of the Customer class. Let's see now how to save three customers at once. We will create three containers, one for each model class that will contain some fields of the Customer model. Create a view containing a block of input fields repeated for every model passed from the controller: <?php use yiihelpersHtml; use yiiwidgetsActiveForm; /* @var $this yiiwebView */ /* @var $model appmodelsRoom */ /* @var $form yiiwidgetsActiveForm */ ?> <div class="room-form"> <?php $form = ActiveForm::begin(); ?> <div class="model"> <?php for($k=0;$k<sizeof($models);$k++) { ?> <?php $model = $models[$k]; ?> <hr /> <label>Model #<?php echo $k+1 ?></label> <?= $form->field($model, "[$k]name")->textInput() ?> <?= $form->field($model, "[$k]surname")->textInput() ?> <?= $form->field($model, "[$k]phone_number")- >textInput() ?> <?php } ?> </div> <hr /> <div class="form-group"> <?= Html::submitButton('Save', ['class' => 'btn btn- primary']) ?> </div> <?php ActiveForm::end(); ?> </div> For each model, all the fields will have the same validator rules of the Customer class, and every single model object will be validated separately. Saving linked models in the same view It could be convenient to save different kind of models in the same view. This approach allows us to save time and to navigate from every single detail until a final item that merges all data is created. Handling different kind of models linked to each other it is not so different from what we have seen so far. The only point to take care of is the link (foreign keys) between models, which we must ensure is valid. Therefore, the controller action will receive the $_POST data encapsulated in the model's class name container; if we are thinking, for example, of the customer and reservation models, we will have two arrays in the $_POST variable, $_POST['Customer'] and $_POST['Reservation'], containing all the fields about the customer and reservation models. Then, all data must be saved together. It is advisable to use a database transaction while saving data because the action can be considered as ended only when all the data has been saved. Using database transactions in Yii2 is incredibly simple! A database transaction starts with calling beginTransaction() on the database connection object and finishes with calling the commit() or rollback() method on the database transaction object created by beginTransaction(). To start a transaction: $dbTransaction = Yii::$app->db->beginTransaction(); Commit transaction, to save all the database activities: $dbTransaction->commit(); Rollback transaction, to clear all the database activities: $dbTransaction->rollback(); So, if a customer was saved and the reservation was not (for any possible reason), our data would be partial and incomplete. Using a database transaction, we will avoid this danger. We now want to create both the customer and reservation models in the same view in a single step. In this way, we will have a box containing the customer model fields and a box with the reservation model fields in the view. Create a view the fields from the customer and reservation models: <?php use yiihelpersHtml; use yiiwidgetsActiveForm; use yiihelpersArrayHelper; use appmodelsRoom; ?> <div class="room-form"> <?php $form = ActiveForm::begin(); ?> <div class="model"> <?php echo $form->errorSummary([$customer, $reservation]); ?> <h2>Customer</h2> <?= $form->field($customer, "name")->textInput() ?> <?= $form->field($customer, "surname")->textInput() ?> <?= $form->field($customer, "phone_number")->textInput() ?> <h2>Reservation</h2> <?= $form->field($reservation, "room_id")- >dropDownList(ArrayHelper::map(Room::find()->all(), 'id', function($room, $defaultValue) { return sprintf('Room n.%d at floor %d', $room- >room_number, $room->floor); })); ?> <?= $form->field($reservation, "price_per_day")->textInput() ?> <?= $form->field($reservation, "date_from")->textInput() ?> <?= $form->field($reservation, "date_to")->textInput() ?> </div> <div class="form-group"> <?= Html::submitButton('Save customer and room', ['class' => 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div> We have created two blocks in the form to fill out the fields for the customer and the reservation. Now, create a new action named actionCreateCustomerAndReservation in ReservationsController in basic/controllers/ReservationsController.php:   public function actionCreateCustomerAndReservation() { $customer = new appmodelsCustomer(); $reservation = new appmodelsReservation(); // It is useful to set fake customer_id to reservation model to avoid validation error (because customer_id is mandatory) $reservation->customer_id = 0; if( $customer->load(Yii::$app->request->post()) && $reservation->load(Yii::$app->request->post()) && $customer->validate() && $reservation->validate() ) { $dbTrans = Yii::$app->db->beginTransaction(); $customerSaved = $customer->save(); if($customerSaved) { $reservation->customer_id = $customer->id; $reservationSaved = $reservation->save(); if($reservationSaved) { $dbTrans->commit(); } else { $dbTrans->rollback(); } } else { $dbTrans->rollback(); } } return $this->render('createCustomerAndReservation', [ 'customer' => $customer, 'reservation' => $reservation ]); } Summary In this article, we saw how to embed JavaScript and CSS in a layout and views, with file content or an inline block. This was applied to an example that showed you how to change the number of columns displayed based on the browser's available width; this is a typically task for websites or web apps that display advertising columns. Again on the subject of JavaScript, you learned how implement direct AJAX calls, taking an example where the reservation detail was dynamically loaded from the customers dropdown list. Next we looked at Yii's core user interface library, which is built on Bootstrap and we illustrated how to use the main Bootstrap widgets natively, together with DatePicker, probably the most commonly used jQuery UI widget. Finally, the last topics covered were multiple models of the same and different classes. We looked at two examples on these topics: the first one to save multiple customers at the same time and the second to create a customer and reservation in the same view. Resources for Article: Further resources on this subject: Yii: Adding Users and User Management to Your Site [article] Meet Yii [article] Creating an Extension in Yii 2 [article]
Read more
  • 0
  • 0
  • 2869

article-image-moodle-19-testing-and-assessment-advanced-options-quiz
Packt
23 Dec 2010
7 min read
Save for later

Moodle 1.9 Testing and Assessment: Advanced Options in Quiz

Packt
23 Dec 2010
7 min read
  Moodle 1.9 Testing and Assessment Develop and evaluate quizzes and tests using Moodle modules Create and evaluate interesting and interactive tests using a variety of Moodle modules Create simple vocabulary or flash card tests and complex tests by setting up a Lesson module Motivate your students to excel through feedback and by keeping their grades online A well-structured practical guide packed with illustrative examples and screenshots           Read more about this book       (For more resources on Moodle 1.9, see here.) Adding images to multiple-choice questions You are not going to always want simple text-based questions or answers. One common type of question that instructors frequently use is the image-based question. This item incorporates an image into the question. These questions are easy to create and can offer new dimensions for questions, as well as make the questions and test much more interesting to students. You can add images to any question or any field that allows you to use the rich-text editor, but we are going to use a single-answer, multiple choice question. We will follow the same basic steps as before. Step 1 We need to create a new multiple-choice question. When we are editing the question, we need to add the question name. We then need to add the question text. The question text we will be using for ours will be Which holiday is this girl celebrating? Step 2 We now go to the toolbar and click on the Insert Image icon. It is the icon that looks like a framed picture of a mountain, located two places to the left of the smiley face icon. Once we click on this icon, a pop-up menu will appear, as shown in the next screenshot: Here we have a few options in regards to how to use images and how they will be displayed in the question. Image URL & Alternate text If we use this option, we are able to take images directly from the Internet and use them for our tests. To use it we first need to have the address where the image is found. We are not looking for the address of the site here, but just the image. If you simply link to the web page, it will not work. To get just the image address, click on the image and you should get a menu with one of the options being View Image. Select View Image and you will be taken to a different page with only that image. This is the address you want to use. Once you have the image address, you copy and paste it to the Image URL text area.With the image address entered, we need to give the image a title in the Alternate text area. You can use anything you'd like here, but I tend to use the image name itself if it describes the image. If not, I create a short descriptive text of the image, something like "Girl celebrating Halloween". After you have entered text in both the Image URL and the Alternate text, click on the OK button and the image will be added to your question. It is important to note that if the website you pulled the image from removes it or changes its location, it will not be available for the question. It is therefore advisable to download the image, so that it will always be available to you. When you have finished adding responses and saving the question, you will see something like the following screenshot: Source: Image: Tina Phillips / FreeDigitalPhotos.net Now, looking back at the options available in the Insert image pop-up, you see three formatting options directly under the Image URL and Alternate text box where we were just working. They are called: Layout, Spacing, and Size. Layout In this fieldset, we are given ways to alter the Alignment and the Border thickness. Note that the image may be displayed differently on different browsers, although the CSS of the theme you are using will usually provide the appropriate margins and padding Alignment There are several options available here that show how the text and the image will be displayed. The full list is shown in the next screenshot: Most of these options are self-explanatory: Left will place the image to the left of the text, Right will place the image to the right of the text, and so on. However, there are a few possibly new terms. Texttop, Baseline, and Absbottom are HTML terms that many people might be unsure of. Texttop simply means that the very top of the tallest text (for example, l, b) will be aligned with the top of the image. This function works same as Top with some browsers. Baseline means that the imaginary line that all letters sit on will be aligned with the bottom of the image. In most browsers today, this functions the same as Bottom. Absbottom means that the letters that go below the baseline are aligned with the bottom of the image (for example, g, j). The top option, Not Set will place the image wherever the cursor is, without any special guide as to how it should be displayed. Border thickness The image you put into the question should look identical to the image you chose to use. If you are placing this image inside of text, or the edges are indistinct, or you simply want to frame it, use Border Thickness By placing a number in the Border thickness box, we will create a black border around the image. A small number will give a narrow border and a bigger number will give a thicker one. Here are three images showing the difference in borders. The first is set with a border of 0, the second has a border of 5, and the third with 10. You will notice that the image size itself is the same, but the border causes the viewable area of the image to compress Source: Images courtesy of: freeimages.co.uk Spacing There are two spacing options available, Horizontal and Vertical. The larger the number entered, the more space there is between the text and the images. Horizontal This setting allows you to set the horizontal distance between the image and the text surrounding it. This option can be useful if you need to have the image set apart from the text in the question or explanation. Vertical This setting is like the horizontal setting. It allows you to set the vertical distance between text and the image. This option can be useful if you need to have set distances between the text or have multiple images in a list with text surrounding them. Size The two options here are Width and Height. These two settings allow you to alter the size of the image; smaller numbers will make the image smaller and probably easier to work with. Note that the actual images are not resized. For the best result, first resize the images on your computer to the size you want them to be. Width This setting allows you to alter the width of the image. Altering this setting without altering the height will produce narrow or wide images, depending on whether you adjust the value up or down. Height This setting allows you to alter the height of the image. This option functions just like Width, and will allow you to produce images that are vertically stretched or shrunk. File Browser In this space, you will see any images that have been uploaded to the course. As you can see in the previous screenshot, it is empty, which tells us that there aren't pictures available in the course yet. If you look below File Browser, you will see four options for images uploaded to the course. You can Delete, Move, Zip, or Rename any images that have already been uploaded into the course. Preview This is where you can view any images that have been added to the course. This feature can be useful if you have a lot of images and tend to forget which images are which.
Read more
  • 0
  • 0
  • 2866
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-documenting-our-application-apache-struts-2-part-2
Packt
15 Oct 2009
9 min read
Save for later

Documenting our Application in Apache Struts 2 (part 2)

Packt
15 Oct 2009
9 min read
Documenting web applications Documenting an entire web application can be surprisingly tricky because of the many different layers involved. Some web application frameworks support automatic documentation generation better than others. It's preferable to have fewer disparate parts. For example, Lisp, Smalltalk, and some Ruby frameworks are little more than internal DSLs that can be trivially redefined to produce documentation from the actual application code. In general, Java frameworks are more difficult to limit to a single layer. Instead, we are confronted with HTML, JSP, JavaScript, Java, the framework itself, its configuration methodologies (XML, annotations, scripting languages, etc.), the service layers, business logic, persistence layers, and so on? Complete documentation generally means aggregating information from many disparate sources and presenting them in a way that is meaningful to the intended audience. High-level overviews The site map is obviously a reasonable overview of a web application. A site map may look like a simple hierarchy chart, showing a simple view of a site's pages without showing all of the possible links between pages, how a page is implemented, and so on. This diagram was created by hand and shows only the basic outline of the application flow. It represents minor maintenance overhead since it would need to be updated when there are any changes to the application. Documenting JSPs There doesn't seem to be any general-purpose JSP documentation methodology. It's relatively trivial to create comments inside a JSP page using JSP comments or a regular Javadoc comment inside a scriptlet. Pulling these comments out is then a matter of some simple parsing. This may be done by using one of our favorite tools, regular expressions, or using more HTML-specific parsing and subsequent massaging. Where it gets tricky is when we want to start generating documentation that includes elements such as JSP pages, which may be included using many different mechanisms—static includes, <jsp:include.../> tags, Tiles, SiteMesh, inserted via Ajax, and so on. Similarly, generating connections between pages is fraught with custom cases. We might use general-purpose HTML links, Struts 2 link tags, attach a link to a page element with JavaScript, ad infinitum/nauseum. When we throw in the (perhaps perverse) ability to generate HTML using Java, we have a situation where creating a perfectly general-purpose tool is a major undertaking. However, we can fairly easily create a reasonable set of documentation that is specific to our framework by parsing configuration files (or scanning a classpath for annotations), understanding how we're linking the server-side to our presentation views, and performing (at least limited) HTML/JSP parsing to pull out presentation-side dependencies, links, and anything that we want documented. Documenting JavaScript If only there was a tool such as Javadoc for JavaScript. The JsDoc Toolkit provides Javadoc-like functionality for JavaScript, with additional features to help handle the dynamic nature of JavaScript code. Because of the dynamic nature, we (as developers) must remain diligent in both in how we write our JavaScript and how we document it. Fortunately, the JsDoc Toolkit is good at recognizing current JavaScript programming paradigms (within reason), and when it can't, provides Javadoc-like tags we can use to give it hints. For example, consider our JavaScript Recipe module where we create several private functions intended for use only by the module, and return a map of functions for use on the webpage. The returned map itself contains a map of validation functions. Ideally, we'd like to be able to document all of the different components. Because of the dynamic nature of JavaScript, it's more difficult for tools to figure out the context things should belong to. Java is much simpler in this regard (which is both a blessing and a curse), so we need to give JsDoc hints to help it understand our code's layout and purpose. A high-level flyby of the Recipe module shows a layout similar to the following: var Recipe = function () { var ingredientLabel; var ingredientCount; // ... function trim(s) { return s.replace(/^s+|s+$/g, ""); } function msgParams(msg, params) { // ... } return { loadMessages: function (msgMap) { // ... }, prepare: function (label, count) { // ... }, pageValidators: { validateIngredientNameRequired: function (form) { // ... }, // ... } }; }(); We see several documentable elements: the Recipe module itself, private variables, private functions, and the return map which contains both functions and a map of validation functions. JsDoc accepts a number of Javadoc-like document annotations that allow us to control how it decides to document the JavaScript elements. The JavaScript module pattern, exemplified by an immediately-executed function, is understood by JsDoc through the use of the @namespace annotation. /** * @namespace * Recipe module. */ var Recipe = function () { // ... }(); We can mark private functions with the @private annotation as shown next: /** * @private * Trims leading/trailing space. */ function trim(s) { return s.replace(/^s+|s+$/g, ""); } It gets interesting when we look at the map returned by the Recipe module: return /** @lends Recipe */ { /** * Loads message map. * * <p> * This is generally used to pass in text resources * retrieved via <s:text.../> or <s:property * value="getText(...)"/> tags on a JSP page in lieu * of a normalized way for JS to get Java I18N resources * </p> */ loadMessages: function (msgMap) { _msgMap = msgMap; }, // ... The @lends annotation indicates that the functions returned by the Recipe module belong to the Recipe module. Without the @lends annotation, JsDoc doesn't know how to interpret the JavaScript in the way we probably intend the JavaScript to be used, so we provide a little prodding. The loadMessages() function itself is documented as we would document a Java method, including the use of embedded HTML. The other interesting bit is the map of validation functions. Once again, we apply the @namespace annotation, creating a separate set of documentation for the validation functions, as they're used by our validation template hack and not directly by our page code. /** * @namespace * Client-side page validators used by our template hack. * ... */ pageValidators: { /** * Insures each ingredient with a quantity * also has a name. * * @param {Form object} form * @type boolean */ validateIngredientNameRequired: function (form) { // ... Note also that we can annotate the type of our JavaScript parameters inside curly brackets. Obviously, JavaScript doesn't have typed parameters. We need to tell it what the function is expecting. The @type annotation is used to document what the function is expected to return. It gets a little trickier if the function returns different types based on arbitrary criteria. However, we never do that because it's hard to maintain. JsDoc has the typical plethora of command-line options, and requires the specification of the application itself (written in JavaScript, and run using Rhino) and the templates defining the output format. An alias to run JsDoc might look like the following, assuming the JsDoc installation is being pointed at by the ${JSDOC} shell variable: alias jsdoc='java -jar ${JSDOC}/jsrun.jar ${JSDOC}/app/run.js -t=${JSDOC}/templates/jsdoc' The command line to document our Recipe module (including private functions using the -p options) and to write the output to the jsdoc-out folder, will now look like the following: jsdoc -p -d=jsdoc-out recipe.js The homepage looks similar to a typical JavaDoc page, but more JavaScript-like: A portion of the Recipe module's validators, marked by a @namespace annotation inside the @lends annotation of the return map, looks like the one shown in the next image (the left-side navigation has been removed): We can get a pretty decent and accurate JavaScript documentation using JsDoc, with only a minimal amount of prodding to help with the dynamic aspects of JavaScript, which is difficult to figure out automatically. Documenting interaction Documenting interaction can be surprisingly complicated, particularly in today's highly-interactive Web 2.0 applications. There are many different levels of interactivity taking place, and the implementation may live in several different layers, from the JavaScript browser to HTML generated deep within a server-side framework. UML sequence diagrams may be able to capture much of that interactivity, but fall somewhat short when there are activities happening in parallel. AJAX, in particular, ends up being a largely concurrent activity. We might send the AJAX request, and then do various things on the browser in anticipation of the result. More UML and the power of scribbling The UML activity diagram is able to capture this kind of interactivity reasonably well, as it allows a single process to be split into multiple streams and then joined up again later. As we look at a simple activity diagram, we'll also take a quick look at scribbling, paper, whiteboards, and the humble digital camera. Don't spend so much time making pretty pictures! One of the hallmarks of lightweight, agile development is that we don't spend all of our time creating the World's Most Perfect Diagram™. Instead, we create just enough documentation to get our points across. One result of this is that we might not use a $1,000 diagramming package to create all of our diagrams. Believe it or not, sometimes just taking a picture of a sketched diagram from paper or a whiteboard is more than adequate to convey our intent, and is usually much quicker than creating a perfectly-rendered software-driven diagram. Yes, the image above is a digital camera picture of a piece of notebook paper with a rough activity diagram. The black bars here are used to indicate a small section of parallel functionality, a server-side search and some activity on the browser. The browser programming is informally indicated by the black triangles. In this case, it might not even be worth sketching out. However, for moderately more complicated usage cases, particularly when there is a lot of both server- and client-side activity, a high-level overview is often worth the minimal effort. The same digital camera technique is also very helpful in meetings where various documentation might be captured on a whiteboard. The resulting images can be posted to a company wiki, used in informal specifications, and so on.
Read more
  • 0
  • 0
  • 2864

article-image-how-create-lesson-moodle-2
Packt
24 Jun 2011
7 min read
Save for later

How to Create a Lesson in Moodle 2

Packt
24 Jun 2011
7 min read
  History Teaching with Moodle 2 Create a History course in Moodle packed with lessons and activities to make learning and teaching History interactive and fun  Approaching the lesson We plan to introduce our Year 7 History class to the idea of the Doomsday Book as a means by which William reinforced his control over the country. William was naturally curious about the country he had just conquered. He was particularly keen to find out how much it was worth. He despatched officials to every village with detailed questions to ask about the land that they worked on and the animals that they farmed with. He also sent soldiers who threatened to kill people who lied. All of the records from these village surveys were collated into the Doomsday Book. Many Saxons detested the process and the name of the book is derived from this attitude of loathing towards something they regarded as intrusive and unfair. William died before the process could be completed. Clear lesson objectives can be stated at the start of the lesson. Students would be expected to work through each page and answer questions identical to those found in the Quiz module. The lesson gives students the opportunity to return to a page if the required level of understanding has not been achieved. The lesson questions help students to reach an understanding at their own pace. The short video clips we intend to use will come from the excellent National Archive website. It has links to short sequences of approximately ninety seconds in which actors take on the role of villagers and commissioners and offer a variety of opinions about the nature and purpose of the survey that they are taking part in. At the end of the lesson, we want the students to have an understanding of: The purpose of the Domesday Book How the information was compiled A variety of attitudes towards the whole process Our starting point is to create a flow diagram that captures the routes a student might take through the lesson: The students will see the set of objectives, a short introduction to the Doomsday Book, and a table of contents. They can select the videos in any order. When they have watched each video and answered the questions associated with the content they will be asked to write longer answers to a series of summative questions. These answers are marked individually by the teacher who thus gets a good overall idea of how well the students have absorbed the information. The assessment of these questions could easily include our essay outcomes marking scale. The lesson ends when the student has completed all of the answers. The lesson requires: A branch table (the table of contents). Four question pages based upon a common template. One end of branch page. A question page for the longer answers. An end of lesson page. The lesson awards marks for the correct answers to questions on each page in much the same way as if they were part of a quiz. Since we are only adding one question per page the scores for these questions are of less significance than a student's answers to the essay questions at the end of the lesson. It is after all, these summative questions that allow the students to demonstrate their understanding of the content they have been working with. Moodle allows this work to be marked in exactly the same way as if it was an essay. This time it will be in the form of an online essay and will take up its place in the Gradebook. We are, therefore, not interested in a standard mark for the students' participation in the lesson and when we set the lesson up, this will become apparent through the choices we make.   Setting up a lesson It is important to have a clear idea of the lesson structure before starting the creation of the lesson. We have used paper and pen to create a flow diagram. We know which images, videos, and text are needed on each page and have a clear idea of the formative and summative questions that will enable us to challenge our students and assess how well they have understood the significance of the Doomsday Book. We are now in a position to create the lesson: Enter the Year 7 History course and turn on editing. In Topic 1, select Add an Activity and click Lesson. In the Name section, enter an unambiguous name for the lesson as this is the text that students will click on to enter the lesson. Enter the values as shown in the following screenshot: In the General section, we do not want to impose a time limit on the lesson. We do need to state how many options there are likely to be on each question page. For multiple choice questions, there are usually four options. In the Grade section, we want the essay that they compose at the end of the lesson to be marked in the same way that other essays have been marked. In the Grade options, our preference is to avoid using the lesson questions as an assessment activity. We want it to be a practice lesson where students can work through the activities without needing to earn a score. We have turned off scoring. The students' final essay submission will be marked in line with our marking policy. Students can retake it as many times as they want to. In the Flow control section, we have clicked the Show advanced button to see all of the options available. We want students to be able to navigate the pages to check answers and go back to review answers if necessary. They can take the lesson as often as they want as we intend it to be used for revision purposes for a timed essay or in the summer examination. We have ignored the opportunity to add features such as menus and progress bars as we will be creating our own navigation system. This section also concerns the look and feel of the pages if set to a slide show, an option we are not planning to use. We are planning to create a web link on each page rather than have students download files so we will not be using the Popup to file or web page option. If you are concerned about the stability of your Internet connection for the weblinks to videos you plan to show, there is an alternative option. This would involve downloading the files to your computer and converting them to .flv files. They can then be uploaded to the file picker in the usual way and a link can be created to each one using the Choose a file button shown here. Moodle's video player would play the videos and you would not be reliant on an unstable Internet connection to see the results. The Dependent on section allows further restrictions to be imposed that are not appropriate for this lesson. We do however, want to mark the essay that will be submitted in accordance with the custom marking scheme developed earlier in the course. The box in the Outcomes section must be checked. Clicking the Save and return to course button ensures that the newly created lesson, The Domesday Book, awaits in Topic 1.  
Read more
  • 0
  • 0
  • 2844

article-image-building-your-first-liferay-site
Packt
09 Dec 2011
10 min read
Save for later

Building your First Liferay Site

Packt
09 Dec 2011
10 min read
(For more resources on Liferay, see here.) Designing the site—Painting the full picture Whenever we get the requirements of the portal, we should first ask ourselves, how would the portal look when it goes live? This one small question will open a door to a lot of other questions and a lot of information which will be required to implement the portal. You should always think of the end state of the portal and then start painting the complete picture of the portal. This approach is known as Beginning with the end! Now, as we have just discussed the approach we should take while starting the site design, let's understand what all information we can retrieve or get when we ask this question to ourselves. We will discuss about four main components of the Liferay Portal design. Users No matter what the size of the portal is—small, medium, or large—it will always be designed for the users. Users are in the centre of any portal application. Let's think of a very common portal . Just imagine that you have to implement this portal. You are sitting in your nice comfy rocking chair and thinking of the users of this portal. What all questions would you ask yourself (or the client, if he/she is with you) about the users of this portal? Who will be using this portal? Will all the users of this portal have same privileges? Or some of the users will have more privileges than the others? Can we collect the users into any specific group? Are these users organized in any kind of hierarchy? Can the users leave or join this portal at a will? and so on. Let's discuss about the answers of the preceding questions and the information we can retrieve from the answers. If we want to provide an answer to the first question in only one word, then it can be—Users. It is quite obvious that the portal will be used by the users. However, if we go into the detail of this question we can get an answer like—all the employees of CNN, users from all over the world, John Walter who will be responsible for administration of the entire portal, and so on. So answer to this question will give us the information about all the players associated with the portal. If all the users of the portal have the same privileges, then it's pretty obvious that every user will be able to perform the same function in the portal. However, this may not be the case with our portal, http://www.cnn.com. Here, we have end users who will come to the portal and will access the information; we can also have a group of internal users who can create the content. Similarly, there can be a group who can approve the content and other group can publish the content; there can also be users who are responsible for user management and one or more users who are responsible for portal management. So this kind of question will give us the information about different roles and permissions associated with each role in our portal. It will also give us the information that which user should be associated with what kind of role. This information is very useful when we are working on the security piece of the portal. If the answer of the third question is Yes then we can either create a user group in our portal or group the users into a specific role. This question will give us the information about user grouping in the portal. Now, answer to the last two questions will be discussed in more detail in this article. However, these questions will help us to determine if we should use an organization or community or mix of both in our portal. Every Liferay portal must have at least one organization or community. Once we get the information about the users in our portal, we should think of the content next. Content No portal can exist without any kind of content. The content can be a static HTML, a static article, a video, an audio, podcast, document, image, and so on. To make the portal more effective, we have to manage the content properly. We will continue with our example of : What kind of questions can we ask to ourselves or to the client about the content? What are the types of the content we will use in the portal? Where are we going to store the content? To Liferay database or some other external database? Do we have to create the content from scratch? Do we need to migrate existing content to Liferay? And a few more… I am sure you must be visiting many portals every day. Can you think of the possible answers to the preceding questions? Also, think of the information which can be retrieved from those answers. The answer to the first question can be—document, images, web content, video, podcast, and so on. This answer will give us an idea about the content types which need to be implemented in the portal. Some of the contents like web content and documents can be available out of the box in Liferay; while other content types like video and podcast may not be available out of the box. This information will enable us to determine the types of content and effort required to create the new content. The second question is a bit tricky. By default, Liferay stores the content into database. However, if the client wants we can store the content in some shared location as well. For example, storing documents into file system. Also, it requires high availability. You can refer to wiki about this on . An answer to this question will give us information like if we need to add any additional hardware or not, if we should do any specific configuration to meet the requirements, and so on. Answers to third and fourth questions will be mainly used for the effort estimation purpose. If a portal like site is using a huge amount of content and all of the content has to be built from scratch then it may take a good amount of time. If the content is already available, we need to consider the effort of migrating and organizing the content. We can also think of other questions like requirement of workflow, type of the flow, if staging is required for the content or not, and so on. All of the preceding questions will give us a good picture about the content to be created or used in our portal. Once we are thorough with this section, it becomes easy to appoint someone to do content management design for your portal. Applications We have discussed about the user and the content of the portal. However, what about the applications which will be hosted on the portal? We cannot imagine a portal without any application nowadays. A portal can contain different applications like forum, wiki, blog, document viewer, video player, and so on. Let's get a list of questions which you should ask yourself while designing the portal: What are the different applications required for this portal? Do we have any application available out of the box in Liferay? Do we need to modify/extend any existing application available in Liferay? Do we have to create any new application for the portal? If yes, what is the complexity of this application? Liferay ships with more than 60 applications pre-bundled known as portlets. These applications are very commonly used in many of the portals. When we ask the preceding questions to ourselves, we get the following information: Number of applications required in the portal How many applications are available out of the box? If we have more applications available OOTB (out of the box) then it can reduce the development time Scope of the project. Do we need any integration with external system or not? Kind of applications we have to develop from scratch Once we go through the preceding set of questions, it becomes very easy to get a picture of the applications required in our portal. It will also provide us information about the efforts required to implement the portal. So, if you are managing a portal development project, you should definitely have this information ready before starting the project. Security Security is one of the most important aspects of any portal. When we think about security of any portal, we must consider access to the content and the applications on the portal. You must have come across many of the portals so far. Some of the portals allow you to create your account freely; some of the portals require an authorization before creating the account while some other portals don't allow creating an account at all. Also, there are some portals which display the same information to all the users while other portals display certain information to members only. To put this in a nutshell, each of the portal has its own security policy and it operates based on that policy only. Once we have discussed/thought about users, content, and application in portal design, we should consider the security aspect of the portal. Now, let's think of some of the questions which we should normally ask to ourselves/client while considering security aspect of the portal. Can everyone freely create an account with the portal? Do we need to migrate the users from an existing user base like LDAP? Can everyone access the same information or we need to display certain information to portal members only? Can all the members of the portal access all the applications with the same privileges or certain users have more privileges over other members? And so on… When we get answers to the preceding questions, we get following information about the portal security: If everyone can create an account with the portal, then in that case we need to provide the create account functionality to the users. Also, we don't need to do any authorization on account creation. If the answer to the first question is NO, then we need to either provide some kind of authorization on account creation or we need to remove the account creation facility completely If we have to migrate the users from an existing user base, then we have to think about the migration and integration. Liferay provides integration with LDAP. If the user base is not present, then we will end up creating all the accounts manually or provide users an ability to create their accounts If all the users (including non-logged in users) can access the same information then we will keep all the information on public pages but if we want certain information to be accessed by members only, then we might consider putting that information on the pages which can be accessed only after logging in If all the members of the portal can access the same information with same privileges then we will not need any special role in the portal. However, if a certain group or a set of users have more privileges over the other—like only content creators can create content—then we will have to create a role and provide the required permission to the role When we think of the security of the portal, we are thinking about users and their access, applications and access to those applications, and other security-related aspects of the portal. It is very important to think about the security before implementing the portal to prevent unauthorized and unauthenticated access to the portal and applications within the portal.
Read more
  • 0
  • 0
  • 2837

article-image-documenting-our-application-apache-struts-2-part-1
Packt
15 Oct 2009
12 min read
Save for later

Documenting our Application in Apache Struts 2 (part 1)

Packt
15 Oct 2009
12 min read
Documenting Java Everybody knows the basics of documenting Java, so we won't go into much detail. We'll talk a bit about ways of writing code whose intention is clear, mention some Javadoc tricks we can use, and highlight some tools that can help keep our code clean. Clean code is one of the most important ways we can document our application. Anything we can do to increase readability will reduce confusion later (including our own). Self-documenting code We've all heard the myth of self-documenting code. In theory, code is always clear enough to be easily understood. In reality, this isn't always the case. However, we should try to write code that is as self-documenting as possible. Keeping non-code artifacts in sync with the actual code is difficult. The only artifact that survives a project is the executable, which is created from code, not comments. This is one of the reasons for writing self-documenting code. (Annotations, XDoclet, and so on, make that somewhat less true.) There are little things we can do throughout our code to make our code read as much like our intent as possible and make extraneous comments just that: extraneous. Document why, not what Over-commenting wastes everybody's time. Time is wasted in writing a comment, reading it, keeping that comment in sync with the code, and, most importantly, a lot of time is wasted when a comment is not accurate. Ever seen this? a += 1; // increment a This is the most useless comment in the world. Firstly, it's really obvious we're incrementing something, regardless of what that something is. If the person reading our code doesn't know what += is, then we have more serious problems than them not knowing that we're incrementing, say, an array index. Secondly, if a is an array index, we should probably use either a more common array index or make it obvious that it's an array index. Using i and j is common for array indices, while idx or index is less common. It may make sense to be very explicit in variable naming under some circumstances. Generally, it's nice to avoid names such as indexOfOuterArrayOfFoobars. However, with a large loop body it might make sense to use something such as num or currentIndex, depending on the circumstances. With Java 1.5 and its support for collection iteration, it's often possible to do away with the index altogether, but not always. Make your code read like the problem Buzzphrases like Domain Specific Languages (DSLs) and Fluent Interfaces are often heard when discussing how to make our code look like our problem. We don't necessarily hear about them as much in the Java world because other languages support their creation in more "literate" ways. The recent interest in Ruby, Groovy, Scala, and other dynamic languages have brought the concept back into the mainstream. A DSL, in essence, is a computer language targeted at a very specific problem. Java is an example of a general-purpose language. YACC and regular expressions are examples of DSLs that are targeted at creating parsers and recognizing strings of interest respectively. DSLs may be external, where the implementing language processes the DSL appropriately, as well as internal, where the DSL is written in the implementing language itself. An internal DSL can also be thought of as an API or library, but one that reads more like a "little language". Fluent interfaces are slightly more difficult to define, but can be thought of as an internal DSL that "flows" when read aloud. This is a very informal definition, but will work for our purposes Java can actually be downright hostile to some common DSL and fluent techniques for various reasons, including the expectations of the JavaBean specification. However, it's still possible to use some of the techniques to good effect. One typical practice of fluent API techniques is simply returning the object instance in object methods. For example, following the JavaBean specification, an object will have a setter for the object's properties. For example, a User class might include the following: public class User {private String fname;private String lname;public void setFname(String fname) { this.fname = fname; }public void setLname(String lname) { this.lname = lname; }} Using the class is as simple as we'd expect it to be: User u = new User();u.setFname("James");u.setLname("Gosling"); Naturally, we might also supply a constructor that accepts the same parameters. However, it's easy to think of a class that has many properties making a full constructor impractical. It also seems like the code is a bit wordy, but we're used to this in Java. Another way of creating the same functionality is to include setter methods that return the current instance. If we want to maintain JavaBean compatibility, and there are reasons to do so, we would still need to include normal setters, but can still include "fluent" setters as shown here: public User fname(String fname) {this.fname = fname;return this;}public User lname(String lname) {this.lname = lname;return this;} This creates (what some people believe is) more readable code. It's certainly shorter: User u = new User().fname("James").lname("Gosling"); There is one potential "gotcha" with this technique. Moving initialization into methods has the potential to create an object in an invalid state. Depending on the object this may not always be a usable solution for object initialization. Users of Hibernate will recognize the "fluent" style, where method chaining is used to create criteria. Joshua Flanagan wrote a fluent regular expression interface, turning regular expressions (already a domain-specific language) into a series of chained method calls: Regex socialSecurityNumberCheck =new Regex(Pattern.With.AtBeginning.Digit.Repeat.Exactly(3).Literal("-").Repeat.Optional.Digit.Repeat.Exactly(2).Literal("-").Repeat.Optional.Digit.Repeat.Exactly(4).AtEnd); Whether or not this particular usage is an improvement is debatable, but it's certainly easier to read for the non-regex folks. Ultimately, the use of fluent interfaces can increase readability (by quite a bit in most cases), may introduce some extra work (or completely duplicate work, like in the case of setters, but code generation and/or IDE support can help mitigate that), and may occasionally be more verbose (but with the benefit of enhanced clarity and IDE completion support). Contract-oriented programming Aspect-oriented programming (AOP) is a way of encapsulating cross-cutting functionality outside of the mainline code. That's a mouthful, but essentially it means is that we can remove common code that is found across our application and consolidate it in one place. The canonical examples are logging and transactions, but AOP can be used in other ways as well. Design by Contract (DbC) is a software methodology that states our interfaces should define and enforce precise specifications regarding operation. "Design by Contract" is a registered trademark of Interactive Software Engineering Inc. Other terms include Programming by Contract (PbC) or Contract Oriented Programming (COP). How does COP help create self-documenting code? Consider the following portion of a stack implementation: public void push(final Object o) {stack.add(o);} What happens if we attempt to push a null? Let's assume that for this implementation, we don't want to allow pushing a null onto the stack. /*** Pushes non-null objects on to stack.*/public void push(final Object o) {if (o == null) return;stack.add(o);} Once again, this is simple enough. We'll add the comment to the Javadocs stating that null objects will not be pushed (and that the call will fail/return silently). This will become the "contract" of the push method—captured in code and documented in Javadocs. The contract is specified twice—once in the code (the ultimate arbiter) and again in the documentation. However, the user of the class does not have proof that the underlying implementation actually honors that contract. There's no guarantee that if we pass in a null, it will return silently without pushing anything. The implied contract can change. We might decide to allow pushing nulls. We might throw an IllegalArgumentException or a NullPointerException on a null argument. We're not required to add a throwsclause to the method declaration when throwing runtime exceptions. This means further information may be lost in both the code and the documentation. Eiffel has language-level support for COP with the require/do/ensure/end construct. It goes beyond the simple null check in the above code. It actively encourages detailed pre- and post-condition contracts. An implementation's push() method might check the remaining stack capacity before pushing. It might throw exceptions for specific conditions. In pseudo-Eiffel, we'd represent the push() method in the following way: push (o: Object) require o /= null do -- push end A stack also has an implied contract. We assume (sometimes naively) that once we call the push method, the stack will contain whatever we pushed. The size of the stack will have increased by one, or whatever other conditions our stack implementation requires. Java, of course, doesn't have built-in contracts. However, it does contain a mechanism that can be used to get some of the benefits for a conceptually-simple price. The mechanism is not as complete, or as integrated, as Eiffel's version. However, it removes contract enforcement from the mainline code, and provides a way for both sides of the software to specify, accept, and document the contracts themselves. Removing the contract information from the mainline code keeps the implementation clean and makes the implementation code easier to understand. Having programmatic access to the contract means that the contract could be documented automatically rather than having to maintain a disconnected chunk of Javadoc. SpringContracts SpringContracts is a beta-level Java COP implementation based on Spring's AOP facilities, using annotations to state pre- and post-contract conditions. It formalizes the nature of a contract, which can ease development. Let's consider our VowelDecider that was developed through TDD. We can also use COP to express its contract (particularly the entry condition). This is a method that doesn't alter state, so post conditions don't apply here. Our implementation of VowelDecider ended up looking (more or less) like this: public boolean decide(final Object o) throws Exception {if ((o == null) || (!(o instanceof String))) {throw new IllegalArgumentException("Argument must be a non-null String.");}String s = (String) o;return s.matches(".*[aeiouy]+.*");} Once we remove the original contract enforcement code, which was mixed with the mainline code, our SpringContracts @Precondition annotation looks like the following: @Precondition(condition="arg1 != null && arg1.class.name == 'java.lang.String'",message="Argument must be a non-null String")public boolean decide(Object o) throws Exception {String s = (String) o;return s.matches(".*[aeiouy]+.*");} The pre-condition is that the argument must not be null and must be (precisely) a string. (Because of SpringContracts' Expression Language, we can't just say instanceof String in case we want to allow string subclasses.) We can unit-test this class in the same way we tested the TDD version. In fact, we can copy the tests directly. Running them should trigger test failures on the null and non-string argument tests, as we originally expected an IllegalArgumentException. We'll now get a contract violation exception from SpringContracts. One difference here is that we need to initialize the Spring context in our test. One way to do this is with JUnit's @BeforeClass annotation, along with a method that loads the Spring configuration file from the classpath and instantiates the decider as a Spring bean. Our class setup now looks like this: @BeforeClass public static void setup() {appContext = new ClassPathXmlApplicationContext("/com/packt/s2wad/applicationContext.xml");decider = (VowelDecider)appContext.getBean("vowelDecider");} We also need to configure SpringContracts in our Spring configuration file. Those unfamiliar with Spring's (or AspectJ's) AOP will be a bit confused. However, in the end, it's reasonably straightforward, with a potential "gotcha" regarding how Spring does proxying. <aop:aspectj-autoproxy proxy-target-class="true"/><aop:config><aop:aspect ref="contractValidationAspect"><aop:pointcut id="contractValidatingMethods"expression="execution(*com.packt.s2wad.example.CopVowelDecider.*(..))"/><aop:around pointcut-ref="contractValidatingMethods"method="validateMethodCall"/></aop:aspect></aop:config><bean id="contractValidationAspect"class="org.springcontracts.dbc.interceptor.ContractValidationInterceptor"/><bean id="vowelDecider"class="com.packt.s2wad.example.CopVowelDecider" /> The SpringContracts documentation goes into it a bit more and the Spring documentation contains a wealth of information regarding how AOP works in Spring. The main difference between this and the simplest AOP setup is that our autoproxy target must be a class, which requires CGLib. This could also potentially affect operation. The only other modification is to change the exception we're expecting to SpringContract's ContractViolationCollectionException, and our test starts passing. These pre- and post-condition annotations use the @Documented meta-annotation, so the SpringContracts COP annotations will appear in the Javadocs. It would also be possible to use various other means to extract and document contract information. Getting into details This mechanism, or its implementation, may not be a good fit for every situation. Runtime performance is a potential issue. As it's just some Spring magic, it can be turned off by a simple configuration change. However, if we do, we'll lose the value of the on-all-the-time contract management. On the other hand, under certain circumstances, it may be enough to say that once the contracts are consistently honored under all of the test conditions, the system is correct enough to run without them. This view holds the contracts more as an acceptance test, rather than as run-time checking. Indeed, there is an overlap between COP and unit testing as the way to keep code honest. As unit tests aren't run all the time, it may be reasonable to use COP as a temporary runtime unit test or acceptance test.
Read more
  • 0
  • 0
  • 2808
article-image-model-view-controller-pattern-and-configuring-web-scripts-alfresco
Packt
30 Aug 2010
13 min read
Save for later

The Model-View-Controller pattern and Configuring Web Scripts with Alfresco

Packt
30 Aug 2010
13 min read
(For more resources on Alfresco, see here.) One way of looking at the Web Scripts framework is as a platform for implementing RESTful Web Services. Although, as we have seen, your service won't actually be RESTful unless you follow the relevant guiding principles, Web Scripts technology alone does not make your services RESTful as if by magic. Another way of looking at it is as an implementation of the Model-View-Controller, or MVC pattern. Model-View-Controller is a long-established pattern in Computer Science, often used when designing user-facing, data-oriented applications. MVC stipulates that users of the application send commands to it by invoking the controller component, which acts on some sort of data model, then selects an appropriate view for presenting the model to the users. While the applicability of MVC to Web application has often been debated, it is still a useful framework for partitioning concerns and responsibilities and for describing the roles of the various components of the Alfresco Web Scripts framework. In the latter, the role of controller is carried out by the scripting component. It should be stressed that, in the MVC pattern, the controller's role is purely that of governing the user interaction by selecting an appropriate model and a corresponding view for presentation, possibly determining which user actions are applicable given the present state of the application. It is not the controller's role to carry out any kind of business logic or to operate on the model directly. Rather, the controller should always delegate the execution of data manipulation operations and queries to a suitable business logic or persistence layer. In the context of Alfresco Web Scripts, this means that your controller script should avoid doing too many things by using the repository APIs directly. It is the responsibility of the controller to: Validate user inputs Possibly convert them to data types suitable for the underlying logic layers Delegate operations to those layers Take data returned by them Use the data to prepare a model for the view to display and nothing more All complex operations and direct manipulations of repository objects should ideally be carried out by code that resides somewhere else, like in Java Beans or JavaScript libraries, which are included by the present script. In practice, many Web Scripts tend to be quite small and simple, so this strict separation of concerns is not always diligently applied. However, as the size and complexity of controller scripts grows, it is considered as a good practice to modularize an application's logic in order to make it easier to follow and to maintain. Some people also have a preference for the relative safety of a static language like Java, compared to JavaScript, and for the use of modern Java IDEs. Therefore, it is frequent to see Web Scripts applications that place the very minimum of logic in controller scripts that use Java Beans to carry out more complex tasks. Coming to the view, which in Alfresco Web Scripts is implemented as FreeMarker templates, it should be noted that in a departure from the "pure" MVC pattern, the freedom accorded to the controller itself of choice between different possible views is rather limited as which view to use is determined exclusively by selecting a template for the specific output format requested by the user through the format specification in the request URL. The model that the view can access is also only partially the responsibility of the controller. Whereas the latter can add more objects to the model available to the view, it cannot reduce the visibility of the predefined, root-scoped objects. It is therefore possible for the view to perform quite a bit of logic without even having a controller to do it. This is why Web Scripts without a controller are acceptable. Whether this is a good practice or not is open to debate. The following diagram illustrates the steps that are involved when a Web Script is executed: The diagram can be explained as follows: An HTTP request, specifying a method and a URI is received. The dispatcher uses the HTTP method and the URI to select a Web Script to execute and executes the controller script. The controller script accesses the repository services by means of the Alfresco JavaScript API. The model is populated and passed to the FreeMarker template engine for rendering. FreeMarker renders a response using the appropriate template. The response is returned to the client. URL matching We've already seen how the dispatcher selects a particular Web Script by matching the URL of the HTTP request against the value of the url element in the descriptors of the registered Web Scripts. There is actually a bit more to this process than simple, exact matching, as we are going to see. First, let's have a look at the structure of a Web Script's request URL: http[s]://<host>:<port>/[<contextPath>/]/<servicePath>[/ <scriptPath>][?<scriptArgs>] The meaning of host and port should be obvious. contextPath is the name of the web application context, that is, where your application is deployed in your application server or Servlet container. It will often be alfresco, but could be share, as the Share application is able to host Web Scripts. It could be missing, if the application is deployed in the root context, or it could really be anything you want. The value of servicePath will usually be either service or wcservice. Using the former, if the Web Script requires authentication, this is performed using the HTTP Basic method. This means that the browser will pop up a username/password dialog box. When the latter is used, authentication is performed by the Alfresco Explorer (also known as Web Client). This means that no further authentication is required if you are already logged into the Explorer, otherwise you will be redirected to the Explorer login page. scriptPath is the part of the URL that is matched against what is specified in the descriptor. Arguments can optionally be passed to the script by specifying them after the question mark, as with any URL. With this in mind, let's look at the value of the <url> element in the descriptor. This must be a valid URI template, according to the JSR-311 specification. Basically, a URI template is a (possibly relative) URI, parts of which are tokens enclosed between curly braces, such as: /one/two/three /api/login/ticket/{ticket} /api/login?u={username}&pw={password?} Tokens stand for variable portions of the URI and match any value for a path element or a parameter. So, the first template in the previous list only matches /one/two/three exactly, or more precisely: http[s]://<host>:<port>/[<contextPath>/]/<servicePath>/one/two/three The second template here matches any URI that begins with /api/login/ticket/, whereas the third matches the /api/login URI when there is a u parameter present and possibly a pw parameter as well. The ? symbol at the end of a token indicates that the parameter or path element in question is not mandatory. Actually, the mandatory character of a parameter is not enforced by Alfresco, but using the question mark is still valuable for documentation purposes to describe what the Web Script expects to receive. We can now precisely describe the operation of the dispatcher as follows: When the dispatcher needs to select a Web Script to execute, it will select the one matching the specific HTTP method used by the request and whose URI template more specifically matches the script path and arguments contained in the request URL. A Web Script descriptor can also have more than one URI template specified in its descriptor, simply by having more than one <url> element. All of them are consulted for matching. The actual values of the path elements specified as tokens are available to the script as entries in the url.templateArgs map variable. For instance, when the /x/foo URL is matched by the /x/{token} template, the value of the expression url. templateArgs["token"] will be equal to foo. Values of request arguments are accessible from the script or template as properties of the args object, such as args.u and args.pw for the third example here. The format requested, which can be specified in the URL by means of the filename extension or of a format argument, need not be specified in the URI template. Authentication In the last version of our Web Script, we specified a value of user for the <authentication> element. When you use this value, users are required to authenticate when they invoke the Web Script's URL, but they can use any valid credentials. When a value of none is present, the Web Script will not require any authentication and will effectively run anonymously. This tends to not be very useful, as all operations using repository objects will require authentication anyway. If you require no authentication, but try to access the repository anyway, the script will throw an exception. A value of guest requires authentication as the guest user. This can be used for scripts accessed from the Explorer, where users are automatically logged in as guest, unless they log in with a different profile. A value of admin requires authentication as a user with the administrator role, typically admin. Run as Scripts can be run as if they were invoked by a user, other than the one who actually provided the authentication credentials. In order to do this, you need to add a runAs attribute to the <authentication> element: <authentication runAs="admin">user</authentication> This can be used, as in the previous example, to perform operations which require administrator privileges without actually logging in as an admin. As this can be a security risk, only scripts loaded from the Java classpath, and not those loaded from the Data Dictionary, can use this feature. The Login service Web Scripts that render as HTML and are therefore intended to be used by humans directly can either use HTTP Basic authentication or Alfresco Explorer authentication, as it is assumed that some person will fill in a login dialog with his username and password. When a script is meant to implement some form of Web Service that is intended for consumption by another application, HTTP Basic or form-based authentication is not always convenient. For this reason, Alfresco provides the login service, which can be invoked using the following URL: http[s]://<host>:<port>/[<contextPath>/]/service/api/login?u={username }&pw={password?} If authentication is successful, the script returns an XML document with the following type of content: <ticket>TICKET_024d0fd815fe5a2762e40350596a5041ec73742a</ticket> Applications can use the value of the ticket element in subsequent requests in order to avoid having to provide user credentials with each request, simply by adding an alf_ticket=TICKET_024d0fd815fe5a2762e40350596a5041ec73742a argument to the URL. As the username and the password are included, unencrypted, in the request URL, it is recommended that any invocations of the login service be carried out over HTTPS. Transactions Possible values of the transaction element are: none/li> required/li> requiresnew When none is used, scripts are executed without any transactional support. Since most repository operations require a transaction to be active, using none will result in an error whenever the script tries to call repository APIs. required causes the execution of the script to be wrapped in a transaction, which is the normal thing to do. If a transaction is already active when the script is invoked, no new transaction is started. requiresnew, on the other hand, always initiates a new transaction, even if one is already active. Requesting a specific format The format element in the Web Script descriptor indicates how clients are expected to specify which rendering format they require. This is what the element looks like: <format [default="default format"]>extension|argument</format> A value of extension indicates that clients should specify the format as a filename extension appended to the Web Script's path. For example: http://localhost:8080/alfresco/service/myscript.html http://localhost:8080/alfresco/service/myscript.xml A value of argument indicates that the format specification is to be sent as the value of the format URL parameter: http://localhost:8080/alfresco/service/myscript?format=html http://localhost:8080/alfresco/service/myscript?format=xml When the client fails to specify a particular format, the value of the default attribute is taken as the format to use. Once a format has been determined, the corresponding template is selected for rendering the model, after the script finishes its execution, on the basis of the template's filename, which must be of the form: <basename>.<method>.<format>.ftl Status Sometimes it can be necessary for the Web Script to respond to a request with an HTTP status code other than the usual 200 OK status, which indicates that the request has been processed successfully. There might also be a requirement that the response body be different depending on the status code, like, for instance, when you want to display a specific message to indicate that some resource could not be found, together with a status code of 404 Not Found. You can easily do this by manipulating the status object: if (document != null){ status.code = 404 status.message = "No such file found." status.redirect = true} You need to set the value of status.redirect to true in order for Alfresco to use an alternative error handling template. When you do this, the Web Scripts framework goes looking for a template with a file name of <basename>.<method>.<format>.<code>.ftl, like, for instance, myscript.get.html.404.ftl and uses it, if found, instead of the usual myscript.get.html.ftl. In this template, you can access the following properties of the status variable to customize your output: Property name Meaning status.code Numeric value of the HTTP status code (for example, 404) status.codeName String value of the status code (for example, Not Found) status.message Possibly set by the script status.exception The exception that caused this status If your script sets a status code between 300 and 399, which usually means a redirection, you can set the value of status.location to control the value of the location HTTP header: status.code = 301; // Moved permanentlystatus.location = 'http://some.where/else'
Read more
  • 0
  • 0
  • 2761

article-image-android-application-testing-tdd-and-temperature-converter
Packt
27 Jun 2011
7 min read
Save for later

Android application testing: TDD and the temperature converter

Packt
27 Jun 2011
7 min read
Getting started with TDD Briefly, Test Driven Development is the strategy of writing tests along the development process. These test cases are written in advance of the code that is supposed to satisfy them. A single test is added, then the code needed to satisfy the compilation of this test and finally the full set of test cases is run to verify their results. This contrasts with other approaches to the development process where the tests are written at the end when all the coding has been done. Writing the tests in advance of the code that satisfies them has several advantages. First, is that the tests are written in one way or another, while if the tests are left till the end it is highly probable that they are never written. Second, developers take more responsibility for the quality of their work. Design decisions are taken in single steps and finally the code satisfying the tests is improved by refactoring it. This UML activity diagram depicts the Test Driven Development to help us understand the process: The following sections explain the individual activities depicted in this activity diagram. Writing a test case We start our development process with writing a test case. This apparently simple process will put some machinery to work inside our heads. After all, it is not possible to write some code, test it or not, if we don't have a clear understanding of the problem domain and its details. Usually, this step will get you face to face with the aspects of the problem you don't understand, and you need to grasp if you want to model and write the code. Running all tests Once the test is written the obvious following step is to run it, altogether with other tests we have written so far. Here, the importance of an IDE with built-in support of the testing environment is perhaps more evident than in other situations and this could cut the development time by a good fraction. It is expected that firstly, our test fails as we still haven't written any code! To be able to complete our test, we usually write additional code and take design decisions. The additional code written is the minimum possible to get our test to compile. Consider here that not compiling is failing. When we get the test to compile and run, if the test fails then we try to write the minimum amount of code necessary to make the test succeed. This may sound awkward at this point but the following code example in this article will help you understand the process. Optionally, instead of running all tests again you can just run the newly added test first to save some time as sometimes running the tests on the emulator could be rather slow. Then run the whole test suite to verify that everything is still working properly. We don't want to add a new feature by breaking an existing one. Refactoring the code When the test succeeds, we refactor the code added to keep it tidy, clean, and minimal. We run all the tests again, to verify that our refactoring has not broken anything and if the tests are again satisfied, and no more refactoring is needed we finish our task. Running the tests after refactoring is an incredible safety net which has been put in place by this methodology. If we made a mistake refactoring an algorithm, extracting variables, introducing parameters, changing signatures or whatever your refactoring is composed of, this testing infrastructure will detect the problem. Furthermore, if some refactoring or optimization could not be valid for every possible case we can verify it for every case used by the application and expressed as a test case. What is the advantage? Personally, the main advantage I've seen so far is that you focus your destination quickly and is much difficult to divert implementing options in your software that will never be used. This implementation of unneeded features is a wasting of your precious development time and effort. And as you may already know, judiciously administering these resources may be the difference between successfully reaching the end of the project or not. Probably, Test Driven Development could not be indiscriminately applied to any project. I think that, as well as any other technique, you should use your judgment and expertise to recognize where it can be applied and where not. But keep this in mind: there are no silver bullets. The other advantage is that you always have a safety net for your changes. Every time you change a piece of code, you can be absolutely sure that other parts of the system are not affected as long as there are tests verifying that the conditions haven't changed. Understanding the testing requirements To be able to write a test about any subject, we should first understand the Subject under test. We also mentioned that one of the advantages is that you focus your destination quickly instead of revolving around the requirements. Translating requirements into tests and cross-referencing them is perhaps the best way to understand the requirements, and be sure that there is always an implementation and verification for all of them. Also, when the requirements change (something that is very frequent in software development projects), we can change the tests verifying these requirements and then change the implementation to be sure that everything was correctly understood and mapped to code. Creating a sample project—the Temperature Converter Our examples will revolve around an extremely simple Android sample project. It doesn't try to show all the fancy Android features but focuses on testing and gradually building the application from the test, applying the concepts learned before. Let's pretend that we have received a list of requirements to develop an Android temperature converter application. Though oversimplified, we will be following the steps you normally would to develop such an application. However, in this case we will introduce the Test Driven Development techniques in the process. The list of requirements Most usual than not, the list of requirements is very vague and there is a high number of details not fully covered. As an example, let's pretend that we receive this list from the project owner: The application converts temperatures from Celsius to Fahrenheit and vice-versa The user interface presents two fields to enter the temperatures, one for Celsius other for Fahrenheit When one temperature is entered in one field the other one is automatically updated with the conversion If there are errors, they should be displayed to the user, possibly using the same fields Some space in the user interface should be reserved for the on screen keyboard to ease the application operation when several conversions are entered Entry fields should start empty Values entered are decimal values with two digits after the point Digits are right aligned Last entered values should be retained even after the application is paused User interface concept design Let's assume that we receive this conceptual user interface design from the User Interface Design team: Creating the projects Our first step is to create the project. As we mentioned earlier, we are creating a main and a test project. The following screenshot shows the creation of the TemperatureConverter project (all values are typical Android project values): When you are ready to continue you should press the Next > button in order to create the related test project. The creation of the test project is displayed in this screenshot. All values will be selected for you based on your previous entries:
Read more
  • 0
  • 0
  • 2755

article-image-so-what-markdown
Packt
02 Sep 2013
3 min read
Save for later

So, what is Markdown?

Packt
02 Sep 2013
3 min read
(For more resources related to this topic, see here.) Markdown is a lightweight markup language that simplifies the workflow of web writers. It was created in 2004 by John Gruber with contributions and feedback from Aaron Swartz. Markdown was described by John Gruber as: "A text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML)." Markdown is two different things: A simple syntax to create documents in plain text A software tool written in Perl that converts the plain text formatting to HTML Markdown's formatting syntax was designed with simplicity and readability as a design goal. We add rich formatting to plain text without considering that we are writing using a markup language. The main features of Markdown Markdown is: Easy to use: Markdown has an extremely simple syntax that you can learn quickly Fast: Writing is much faster than with HTML, we can dramatically reduce the time we spend crafting HTML tags Clean: We can clearly read and write documents that are always translated into HTML without mistakes or errors Flexible: It is suitable for many things such as writing on the Internet, e-mails, creating presentations Portable: Documents are just plain text; we can edit Markdown with any basic text editor in any operating system Made for writers: Writers can focus on distraction-free writing Here, we can see a quick comparison of the same document between HTML and Markdown. This is the final result that we achieve in both cases: The following code is written in HTML: <h1>Markdown</h1><p>This a <strong>simple</strong> example of Markdown.</p><h2>Features:</h2><ul><li>Simple</li><li>Fast</li><li>Portable</li></ul><p>Check the <a href="http://daringfireball.net/projects/markdown/">official website</a>.</p> The following code is an equivalent document written in Markdown: # Markdown This a **simple** example of Markdown. ## Features: - Simple - Fast - Portable Check the [official website]. [official website]:http://daringfireball.net/projects/markdown/ summary In this article, we learned the basics of Markdown and got to know its features. We also saw how convenient Markdown is, thus proving the fact that it's made for writers. Resources for Article: Further resources on this subject: Generating Reports in Notebooks in RStudio [Article] Database, Active Record, and Model Tricks [Article] Formatting and Enhancing Your Moodle Materials: Part 1 [Article]
Read more
  • 0
  • 0
  • 2691
article-image-android-application-testing-adding-functionality-ui
Packt
27 Jun 2011
10 min read
Save for later

Android Application Testing: Adding Functionality to the UI

Packt
27 Jun 2011
10 min read
  Android Application Testing Guide Build intensively tested and bug free Android applications  The user interface is in place. Now we start adding some basic functionality. This functionality will include the code to handle the actual temperature conversion. Temperature conversion From the list of requirements from the previous article we can obtain this statement: When one temperature is entered in one field the other one is automatically updated with the conversion. Following our plan we must implement this as a test to verify that the correct functionality is there. Our test would look something like this: @UiThreadTest public final void testFahrenheitToCelsiusConversion() { mCelsius.clear(); mFahrenheit.clear(); final double f = 32.5; mFahrenheit.requestFocus(); mFahrenheit.setNumber(f); mCelsius.requestFocus(); final double expectedC = TemperatureConverter.fahrenheitToCelsius(f); final double actualC = mCelsius.getNumber(); final double delta = Math.abs(expectedC - actualC); final String msg = "" + f + "F -> " + expectedC + "C but was " + actualC + "C (delta " + delta + ")"; assertTrue(msg, delta < 0.005); } Firstly, as we already know, to interact with the UI changing its values we should run the test on the UI thread and thus is annotated with @UiThreadTest. Secondly, we are using a specialized class to replace EditText providing some convenience methods like clear() or setNumber(). This would improve our application design. Next, we invoke a converter, named TemperatureConverter, a utility class providing the different methods to convert between different temperature units and using different types for the temperature values. Finally, as we will be truncating the results to provide them in a suitable format presented in the user interface we should compare against a delta to assert the value of the conversion. Creating the test as it is will force us to follow the planned path. Our first objective is to add the needed code to get the test to compile and then to satisfy the test's needs. The EditNumber class In our main project, not in the tests one, we should create the class EditNumber extending EditText as we need to extend its functionality. We use Eclipse's help to create this class using File | New | Class or its shortcut in the Toolbars. This screenshot shows the window that appears after using this shortcut: The following table describes the most important fields and their meaning in the previous screen:     Field Description Source folder: The source folder for the newly-created class. In this case the default location is fine. Package: The package where the new class is created. In this case the default package com.example.aatg.tc is fine too. Name: The name of the class. In this case we use EditNumber. Modifiers: Modifiers for the class. In this particular case we are creating a public class. Superclass: The superclass for the newly-created type. We are creating a custom View and extending the behavior of EditText, so this is precisely the class we select for the supertype. Remember to use Browse... to find the correct package. Which method stubs would you like to create? These are the method stubs we want Eclipse to create for us. Selecting Constructors from superclass and Inherited abstract methods would be of great help. As we are creating a custom View we should provide the constructors that are used in different situations, for example when the custom View is used inside an XML layout. Do you want to add comments? Some comments are added automatically when this option is selected. You can configure Eclipse to personalize these comments. Once the class is created we need to change the type of the fields first in our test: public class TemperatureConverterActivityTests extends ActivityInstrumentationTestCase2<TemperatureConverterActivity> { private TemperatureConverterActivity mActivity; private EditNumber mCelsius; private EditNumber mFahrenheit; private TextView mCelsiusLabel; private TextView mFahrenheitLabel; ... Then change any cast that is present in the tests. Eclipse will help you do that. If everything goes well, there are still two problems we need to fix before being able to compile the test: We still don't have the methods clear() and setNumber() in EditNumber We don't have the TemperatureConverter utility class To create the methods we are using Eclipse's helpful actions. Let's choose Create method clear() in type EditNumber. Same for setNumber() and getNumber(). Finally, we must create the TemperatureConverter class. Be sure to create it in the main project and not in the test project. Having done this, in our test select Create method fahrenheitToCelsius in type TemperatureConverter. This fixes our last problem and leads us to a test that we can now compile and run. Surprisingly, or not, when we run the tests, they will fail with an exception: 09-06 13:22:36.927: INFO/TestRunner(348): java.lang. ClassCastException: android.widget.EditText 09-06 13:22:36.927: INFO/TestRunner(348): at com.example.aatg. tc.test.TemperatureConverterActivityTests.setUp( TemperatureConverterActivityTests.java:41) 09-06 13:22:36.927: INFO/TestRunner(348): at junit.framework. TestCase.runBare(TestCase.java:125) That is because we updated all of our Java files to include our newly-created EditNumber class but forgot to change the XMLs, and this could only be detected at runtime. Let's proceed to update our UI definition: <com.example.aatg.tc.EditNumber android_layout_height="wrap_content" android_id="@+id/celsius" android_layout_width="match_parent" android_layout_margin="@dimen/margin" android_gravity="right|center_vertical" android_saveEnabled="true" /> That is, we replace the original EditText by com.example.aatg.tc.EditNumber which is a View extending the original EditText. Now we run the tests again and we discover that all tests pass. But wait a minute, we haven't implemented any conversion or any handling of values in the new EditNumber class and all tests passed with no problem. Yes, they passed because we don't have enough restrictions in our system and the ones in place simply cancel themselves. Before going further, let's analyze what just happened. Our test invoked the mFahrenheit.setNumber(f) method to set the temperature entered in the Fahrenheit field, but setNumber() is not implemented and it is an empty method as generated by Eclipse and does nothing at all. So the field remains empty. Next, the value for expectedC—the expected temperature in Celsius is calculated invoking TemperatureConverter.fahrenheitToCelsius(f), but this is also an empty method as generated by Eclipse. In this case, because Eclipse knows about the return type it returns a constant 0. So expectedC becomes 0. Then the actual value for the conversion is obtained from the UI. In this case invoking getNumber() from EditNumber. But once again this method was automatically generated by Eclipse and to satisfy the restriction imposed by its signature, it must return a value that Eclipse fills with 0. The delta value is again 0, as calculated by Math.abs(expectedC – actualC). And finally our assertion assertTrue(msg, delta < 0.005) is true because delta=0 satisfies the condition, and the test passes. So, is our methodology flawed as it cannot detect a simple situation like this? No, not at all. The problem here is that we don't have enough restrictions and they are satisfied by the default values used by Eclipse to complete auto-generated methods. One alternative could be to throw exceptions at all of the auto-generated methods, something like RuntimeException("not yet implemented") to detect its use when not implemented. But we will be adding enough restrictions in our system to easily trap this condition. TemperatureConverter unit tests It seems, from our previous experience, that the default conversion implemented by Eclipse always returns 0, so we need something more robust. Otherwise this will be only returning a valid result when the parameter takes the value of 32F. The TemperatureConverter is a utility class not related with the Android infrastructure, so a standard unit test will be enough to test it. We create our tests using Eclipse's File | New | JUnit Test Case, filling in some appropriate values, and selecting the method to generate a test as shown in the next screenshot. Firstly, we create the unit test by extending junit.framework.TestCase and selecting com.example.aatg.tc.TemperatureConverter as the class under test: Then by pressing the Next > button we can obtain the list of methods we may want to test: We have implemented only one method in TemperatureConverter, so it's the only one appearing in the list. Other classes implementing more methods will display all the options here. It's good to note that even if the test method is auto-generated by Eclipse it won't pass. It will fail with the message Not yet implemented to remind us that something is missing. Let's start by changing this: /** * Test method for {@link com.example.aatg.tc. TemperatureConverter#fahrenheitToCelsius(double)}. */ public final void testFahrenheitToCelsius() { for (double c: conversionTableDouble.keySet()) { final double f = conversionTableDouble.get(c); final double ca = TemperatureConverter.fahrenheitToCelsius(f); final double delta = Math.abs(ca - c); final String msg = "" + f + "F -> " + c + "C but is " + ca + " (delta " + delta + ")"; assertTrue(msg, delta < 0.0001); } } Creating a conversion table with values for different temperature conversion we know from other sources would be a good way to drive this test. private static final HashMap<Double, Double> conversionTableDouble = new HashMap<Double, Double>(); static { // initialize (c, f) pairs conversionTableDouble.put(0.0, 32.0); conversionTableDouble.put(100.0, 212.0); conversionTableDouble.put(-1.0, 30.20); conversionTableDouble.put(-100.0, -148.0); conversionTableDouble.put(32.0, 89.60); conversionTableDouble.put(-40.0, -40.0); conversionTableDouble.put(-273.0, -459.40); } We may just run this test to verify that it fails, giving us this trace: junit.framework.AssertionFailedError: -40.0F -> -40.0C but is 0.0 (delta 40.0)at com.example.aatg.tc.test.TemperatureConverterTests. testFahrenheitToCelsius(TemperatureConverterTests.java:62) at java.lang.reflect.Method.invokeNative(Native Method) at android.test.AndroidTestRunner.runTest(AndroidTestRunner. java:169) at android.test.AndroidTestRunner.runTest(AndroidTestRunner. java:154) at android.test.InstrumentationTestRunner.onStart( InstrumentationTestRunner.java:520) at android.app.Instrumentation$InstrumentationThread.run( Instrumentation.java:1447) Well, this was something we were expecting as our conversion always returns 0. Implementing our conversion, we discover that we need some ABSOLUTE_ZERO_F constant: public class TemperatureConverter { public static final double ABSOLUTE_ZERO_C = -273.15d; public static final double ABSOLUTE_ZERO_F = -459.67d; private static final String ERROR_MESSAGE_BELOW_ZERO_FMT = "Invalid temperature: %.2f%c below absolute zero"; public static double fahrenheitToCelsius(double f) { if (f < ABSOLUTE_ZERO_F) { throw new InvalidTemperatureException( String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, f, 'F')); } return ((f - 32) / 1.8d); } } Absolute zero is the theoretical temperature at which entropy would reach its minimum value. To be able to reach this absolute zero state, according to the laws of thermodynamics, the system should be isolated from the rest of the universe. Thus it is an unreachable state. However, by international agreement, absolute zero is defined as 0K on the Kelvin scale and as -273.15°C on the Celsius scale or to -459.67°F on the Fahrenheit scale. We are creating a custom exception, InvalidTemperatureException, to indicate a failure providing a valid temperature to the conversion method. This exception is created simply by extending RuntimeException: public class InvalidTemperatureException extends RuntimeException { public InvalidTemperatureException(String msg) { super(msg); } } Running the tests again we now discover that testFahrenheitToCelsiusConversion test fails, however testFahrenheitToCelsius succeeds. This tells us that now conversions are correctly handled by the converter class but there are still some problems with the UI handling this conversion. A closer look at the failure trace reveals that there's something still returning 0 when it shouldn't. This reminds us that we are still lacking a proper EditNumber implementation. Before proceeding to implement the mentioned methods, let's create the corresponding tests to verify what we are implementing is correct.
Read more
  • 0
  • 0
  • 2689

article-image-getting-started-adobe-premiere-pro-cs6-hotshot
Packt
11 Jul 2013
14 min read
Save for later

Getting Started with Adobe Premiere Pro CS6 Hotshot

Packt
11 Jul 2013
14 min read
(For more resources related to this topic, see here.) Getting the story right! This is basic housekeeping and ignoring it is like making your own editing life much more frustrating. So take a deep breath, think of calm blue oceans, and begin by getting this project organized. First you need to set the Timeline correctly and then you will create a short storyboard of the interview; again you will do this by focusing on the beginning, middle, and end of the story. Always start this way as a good story needs these elements to make sense. For frame-accurate editing it's advisable to use the keyboard as much as possible, although some actions will need to be performed with the mouse. Towards the end of this task you will cover some new ground as you add and expand Timeline tracks in preparation for the tasks ahead. Prepare for Lift Off Once you have completed all the preparations detailed in the Mission Checklist section, you are ready to go. Launch Premiere Pro CS6 in the usual way and then proceed to the first task. Engage Thrusters First you will open the project template, save it as a new file, and then create a three-clip sequence; the rough assembly of your story. Once done, perform the following steps: When the Recent Projects splash screen appears, select Hotshots Template – Montage. Wait for the project to finish loading and save this as Hotshots – Interview Project. Close any sequences open on the Timeline. Select Editing Optimized Workspace. Select the Project panel and open the Video bin without creating a separate window. If you would like Premiere Pro to always open a bin without creating a separate window, select Edit | Preferences | General from the menu. When the General Options window displays, locate the Bins option area and change the Double-Click option to Open in Place. Import all eight video files into the Video folder inside the Project 3 folder. Create a new sequence. Pick any settings at random, you will correct this in the next step. Rename the sequence as Project 3. Match the Timeline settings with any clip from the Video bin, and then delete the clip from the Timeline. Set the Project panel as the active panel and switch to List View if it is not already displayed. Create the basic elements of a short story for this scene using only three of the available clips in the Video bin. To do this, hold down the Ctrl or command key and click on the clips named ahead. Make sure you click on them in the same order as they are presented here: Intro_Shot.avi Two_Shot.avi Exit_Shot.avi Ensure the Timeline indicator is at the start of the Timeline and then click on the Automate to Sequence icon. When the Automate To Sequence window appears, change Ordering to Selection Order and leave Placement as the default (Sequentially). Uncheck the Apply Default Audio Transition , Apply Default Video Transition, and Ignore Audio checkboxes. Click on OK or press Enter on the keyboard to complete this action. Right-click on the Video 1 track and select Add Tracks from the context menu. When the Add Tracks window appears, set the number of video tracks to be added as 2 and the number of audio tracks to be added as 0. Click on OK or press Enter to confirm these changes. Dial open the Audio 1 track (hint – small triangle next to Audio 1), then expand the Audio 1 track by placing the cursor at the bottom of the Audio 1 area, and clicking on it, and dragging it downwards. Stop before the Master audio track disappears below the bottom of the Timeline panel. The Master audio track is used to control the output of all the audio tracks present on the Timeline; this is especially useful when you come to prepare your timeline for exporting to DVD. The Master audio track also allows you to view the left and right audio channels of your project. More details on the use of the Master audio track can be found in the Premiere Pro reference guide, which can be downloaded from http://helpx.adobe.com/pdf/premiere_pro_reference.pdf. Make sure the Timeline panel is active and zoom in to show all the clips present (hint – press backslash). You should end this section with a Timeline that looks something like the following screenshot. Save your project (Press Ctrl + S or command + S) before moving on to the next task. Objective Complete - Mini Debriefing How did you do? Review the shortcuts listed next. Did you remember them all? In this task you should have automatically matched up the Timeline to the clips with one drag-and-drop, plus a delete. You should have then sent three clips from the Project panel to the Timeline using the Automate to Sequence function. Finally you should have added two new video tracks and expanded the Audio 1 track. Keyboard shortcuts covered in this task are as follows: (backslash): Zoom the Timeline to show all populated clips Ctrl or command + double-click: Open bin without creating a separate Project panel (also see the tip after step 3 in the Engage Thrusters section) Ctrl or command + N: Create a new sequence Ctrl or command + (backslash): Create new bin in the Project panel Ctrl or command + I: Open the Import window Shift + 1: Set the Project panel as active Shift + 3: Set Timeline as active Classified Intel In this project, the Automate to Timeline function is being used to create a rough assembly of three clips. These are placed on the Timeline in the order that you clicked on them in the project bin. This is known as the selection order and allows the Automate to Timeline function to ignore the clips-relative location in the project bin. This is not a practical work flow if you have too many clips in your Project panel (how would you remember the selection order of twenty clips?). However, for a small number of clips, this is a practical workflow to quickly and easily send a rough draft of your story to the Timeline in just a few clicks. If you remember nothing else from this book, always remember how to correctly use Automate To Timeline! Extracting audio fat Raw material from every interview ever filmed will have lulls and pauses, and some stuttering. People aren't perfect and time spent trying to get lines and timing just right can lead to an unfortunate waste of filming time. As this performance is not live, you, the all-seeing editor, have the power to cut those distracting lulls and pauses, keeping the pace on beat and audience's attention on track. In this task you will move through the Timeline, cutting out some of the audio fat using Premiere Pro's Extract function, and to get this frame accurate, you will use as many keyboard shortcuts as possible. Engage Thrusters You will now use the Extract function to remove "dead" audio areas from the Timeline. Perform the following steps: Set the Timeline panel as active then play the timeline back by pressing the L key once. Make a mental note of the silences that occur in the first clip (Intro_Shot.avi). Return the Timeline indicator to the start of the Timeline using the Home key. Zoom in on the Timeline by pressing the + (plus) key on the main keyboard area. Do this until your Timeline looks something like the screenshot just after the following tip: To zoom in and out of the Timeline use the + (plus) and - (minus) keys in the main keyboard area, not the ones in the number pad area. Pressing the plus or minus key in the number area allows you to enter an exact number of frames into whichever tool is currently active. You should be able to clearly see the first area of silence starting at around 06;09 on the Timeline. Use the J, K, and L keyboard shortcuts to place the Timeline indicator at this point. Press the I key to set an In point here, then move the Timeline indicator to the end of the silence (around 08;17), and press the O key to set an Out point. Press the # (hash) key on your keyboard to remove the marked section of silence using Premiere Pro's Extract function. Important information on Sync Locking tracks The above step will only work if you have the Sync Lock icons toggled on for both the Video 1 and Audio 1 tracks. The Sync Lock icon controls which Timeline tracks will be altered when using a function such as Extract. For example; if the Sync Lock icon was toggled off for the Audio 1 track, then only the video would be extracted, which is counterproductive to what you are trying to achieve in this task! By default each new project should open with the Sync Lock icon toggled on for all video and audio tracks that already exist on the Timeline, and those added at a later point in the project. More information on Sync Lock can be found in the Premiere Pro reference guide (tinyurl.com/cz5fvh9). Repeat steps 5 and 6 to remove silences from the following Timeline areas (you should judge these points for yourself rather than slavishly following the suggestions given next): i. Set In point at 07;11 and Out point at 08;10. ii.Press # (hash). iii.Set In point at 11;05 and Out point at 12;13. iv.Press # (hash). Play back the Timeline to make sure you haven't extracted away too much audio and clipped the end of a sentence. Use the Trim tool to restore the full sentence. You may have spotted other silences on the Timeline; for the moment leave them alone. You will deal with these using other methods later in this project. Save the project before moving on to the next section. Objective Complete - Mini Debriefing At the end of this section you should have successfully removed three areas of silence from the Intro_Shot.avi clip. You did this using the Extract function, an elegant way of removing unwanted areas from your clips. You may also have refreshed your working knowledge of the Trim tool. If this still feels a lit le alien to you, don't worry, you will have a chance to practice trimming skills later in this project. Classified Intel Extract is another cunningly simple function that does exactly what it says; it extracts a section of footage from the Timeline, and then closes the gap created by this ac i on. In one step it replicates the razor cut and ripple delete. Creating a J-cut (away) One of the most common video techniques used in interviews and documentaries (not to mention a number of films) is called a J-cut. This describes cutting away some of the video, while leaving the audio beneath intact. The deleted video area is then replaced with alternative footage. This creates a voice-over effect that allows for a seamless transfer between the alternative viewpoints and the original speaker. In this task you will create a J-cut by replacing the video at the start of Intro_Shot.avi, leaving the voice of the newsperson and replacing his image with cutaway shots of what he is describing. You will make full use of four-point edits. Engage Thrusters Create J-cuts and cutaway shots using work flows you should now be familiar with. Perform the following steps to do so: Send the Cutaways_1.avi clip from the Project panel to the Source Monitor. In the Source Monitor, create an In point at 00;00 and an Out point just before the shot changes (around 04;24). Switch to the Timeline and send the Timeline indicator to the start of the Timeline (00;00). Create an In point here. Use a keyboard shortcut of your choice to identify the point just before the newsperson mentions the "Local village shop". (hint – roughly at 06;09). Create an Out point here. You want to create a J-cut, which means protecting the audio track that is already on the Timeline. To do this click once on the Audio 1 track header so it turns dark gray. Switch back to the Source Monitor and send the marked Cutaways_1.avi clip to the Timeline using the Overwrite function (hint – press the '.' (period) key). When the Fit Clip window appears, select Change Clip Speed (Fit to Fill), and click on OK or press Enter on the keyboard. The village scene cutaway shot should now appear on Video 1, but Audio 1 should retain the newsperson's dialog. His inserted village scene clip will have also slowed slightly to match what's being said by the newsperson. Repeat steps 2 to 7 to place the Cutaways_1.avi clip that shows the shot of the village shop, to match the village church and the village pub on the Timeline with the newsperson's dialog. The following are some suggestions on times, but try to do this step first of all without looking too closely at them: For the village shop cutaway, set the Source Monitor In point at 05;00 and Out point at 09;24. Set the Timeline In point at 06;10 and Out point at 07;13. Switch back to Source Monitor. Send the clip in the Overwrite mode and set Change Clip Speed to Fit to Fill. For the village church cutaway, set the Source Monitor In point at 10;00 and Out point at 14;24. Set the Timeline In point at 07;14 and Out point at 09;03. Switch back to Source Monitor. Send the clip in the Overwrite mode and set Change Clip Speed to Fit to Fill. For the pub cutaway, send Reconstruction_1.avi to the Source Monitor. Set the Source Monitor In point at 04;11 and Out point at 04;17. Set the Timeline In point at 09;04 and Out point at 12;00. Switch back to Source Monitor. Send the clip in the Overwrite mode and set Change Clip Speed to Fit to Fill. The last cutaway shot here is part of the reconstruction reel and has been used because your camera person was unable (or forgot) to film a cutaway shot of the pub. This does sometimes happen and then it's down to you, the editor in charge, to get the piece on air with as few errors as possible. To do this you may find yourself scavenging footage from any of the other clips. In this case you have used just seven frames of Reconstruction_1.avi, but using the Premiere Pro feature, Fit to Fill , you are able to match the clip to the duration of the dialogue, saving your camera person from a production meeting dressing down! Review your edit decisions and use the Trim tool or the Undo command to alter edit points that you feel need adjustments. As always, being an editor is about experimentation, so don't be afraid to try something out of the box, you never know where it might lead. Once you are happy with your edit decisions, render any clips on the Timeline that display a red line above them. You should end up with a Timeline that looks something like the following screenshot; save your project before moving on to the next section. Objective Complete - Mini Debriefing In this task you have learned how to piece together cutaway shots to match the voice-over, creating an effective J-cut, as seen in the way the dialog seamlessly blends between the pub cutaway shot and the news reporter finishing his last sentence. You also learned how to scavenge source material from other reels in order to find the necessary shot to match the dialog. Classified Intel The last set of time suggestions given in this task allow the pub cutaway shot to run over the top of the newsperson saying "And now, much to the surprise…". This is an editorial decision that you can make on whether or not this cutaway should run over the dialog. It is simply a matter of taste, but you are the editor and the final decision is yours! In this article, we learned how to extract audio fat and create a J-cut. Resources for Article : Further resources on this subject: Responsive Design with Media Queries [Article] Creating a Custom HUD [Article] Top features you'll want to know about [Article]
Read more
  • 0
  • 0
  • 2684
Modal Close icon
Modal Close icon