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
All 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 - Web Development

1797 Articles
article-image-planning-your-site-adobe-muse
Packt
27 Sep 2012
11 min read
Save for later

Planning Your Site in Adobe Muse

Packt
27 Sep 2012
11 min read
Page layouts The layout of your website can be a deciding factor on whether your visitors will stay on your website or leave with an impatient click. You could think of the layout as a map. If it's easy for the visitors to "read" the map, they are more likely to stick around and find the content you're providing. Let's take a look at some of the typical layouts we see on the Web today. Bread and butter layouts When we're designing a layout for a web page, there are a number of sections that we need to include. These sections can be broken into the following: Consistent content: This does not change throughout the site. Examples of this type of content are logos, navigation bars, and footers. Changing content: This is the part of the page that changes throughout the site, usually the main content. In some situations, the content of the sidebar may also change. A web designer's job is to create a layout that keeps the visitor focused on the content while keeping it nice and easy to navigate around the site. Some examples of conventional or bread and butter site layouts are shown in the following figure: You have a very short amount of time to capture a visitor's attention. So by choosing one of these basic layouts, you're using a tried and tested setup, which many web users will feel at home with. Don't worry that these layouts look "boxy". You can use images, colors, and typefaces, which complement the purpose of your site to completely disguise the fact that every web page is essentially made up of boxes. The bread and butter layouts featured previously are well-tested guides; however, there is absolutely no obligation for you to use one of these. What appears on a typical web page? So we've seen some basic layouts. Now we'll look at some of the elements that appear on (nearly) every web page. Logo The logo is the part of a company's overall branding and identity, and appears at the top of each page on the site along with the company name and tagline, just as it would on printed forms of marketing, such as business cards, brochures, and letterheads. This identity block increases brand recognition and ensures users know that the pages they're viewing are part of a single site. Frequently, the logo is also a link back to the home page of the site. Navigation bar The navigation for your site should be easy to use and easy to find. Just like the logo, it should appear near the top of the page. You may decide to use a horizontal menu across the top of the page, a vertical menu in a sidebar, or a combination of the two. Either way, your main navigation should be visible "above the fold", that is, any area of a web page that can be viewed without visitors having to scroll. Content Content is the King. This is what your visitors have come for. If the visitors can't find what they're looking for, they will move on very quickly. The main content is an important focal point in your design; don't waste time fling it with unnecessary "stuff". Footer Sitting at the bottom of the page, the footer usually holds copyright information, contact links information, and legalities of the site. Some designers have become very imaginative with footers and use this area to hold additional links, tweets, and "about me" information. The footer clearly separates the main content from the end of the page and indicates to users that they're at the bottom of the page. In the following screenshot, you can see a page from the Apple website, which is highly regarded for its aesthetic design. Each section is clearly delineated. If you keep in mind the idea of your site's layout as a map, then you can determine where you want to lead your visitors on the site. Wireframes Wireframing is an important part of the design process for both simple and complex projects. If you're creating a website for a client, a wireframe is a great tool for communicating your ideas visually at an early stage rather than just having a verbal description. If you're creating a website for yourself, the wireframe helps to clarify what is required on each page of your website. It can be considered an overlap between the planning process and the design process. Creating a simple wireframe ensures that your page designs take into account all of the elements you'll add to your pages and where they will be positioned. Wireframes are cost-effective because the time spent in the initial stages potentially saves you from losing much more time revising the design at a later stage. Wireframes can be created in several ways, including pen and paper and computer-based tools. When it comes to computer-based applications for wireframing, there are many options available. Some designers use Photoshop, Illustrator, or even InDesign to put together their wireframes. Specific wireframing software packages that are popular with web designers include Balsamiq and OmniGraffe. Wireframes and Mockups and Prototypes. Oh my! You may hear web designers refer to wireframes, mockups, and prototypes. Although these terms are sometimes used interchangeably, it's important to understand that they are three different things. A wireframe is a basic illustration showing the structure and components of a web page. A mockup is an image file focusing on the design elements in the site. It contains the graphics and other page elements that make up the web page but may contain dummy text and images. A prototype is an almost-complete or semi-functional web page, constructed with HTML and CSS. Prototypes give the client (or yourself) the ability to click around and check out how the final site will work. What to include in a wireframe? Think about which design elements will appear on each page of your website. As mentioned already, most websites will have elements such as logos, navigation, search bars, and footers in consistent positions throughout the site. Next, think about any extra elements that may be specific to individual pages. These include graphics and dynamic widgets. Once you know what's required, you can start to create your wireframe based on these elements. Some designers like to create their wireframes with the "big picture" in mind. Once the basic layout is in place, they get feedback from the client and revise the wireframe if necessary. Others like to create a very detailed wireframe for each page on the site, including every single design element on the list before showing it to the client. Wireframes let us try out several different ideas before settling on our favorite design, which can then be brought forward to the mockup stage. Obviously our focus in this book is on using Muse, but I would urge you not to rule out using paper sketches. It's a great way to quickly get ideas out of your head and into a tangible, visible layout. Web.without.words (www.webwithoutwords.com) is an interesting website dedicated to showing popular and well-known sites as wireframes. The text and images on each site are blocked out and it's a nice way to look at web pages and see how they can be broken down into simple boxes without getting caught up in the content. Wireframes with Muse So what are the advantages of using Muse to create our wireframes? Well, Muse not only lets you create wireframes, but it also allows you to quickly create prototypes using those wireframes. This means you can show clients the functionality of the website with the basic layout. The prototype produced by Muse can be reviewed on any web browser giving the client a good idea of how the site will appear. This kind of early testing can help alleviate time-consuming problems further down the line of the design process. We're going to prepare a site and wireframe now for a fictitious website about windsurfing. First, we'll create a new site, and then add pages in the Plan view. Site structure with Plan view. Let's start by creating a new site. Open Muse. Choose File | New Site. In the New Site dialog box, set Page Width to 960 and Min Height to 800 pixels. Set Margins to 0 all around and Padding Top and Bottom to 10 pixels each. Set the number of Columns to 16. The columns appear as guidelines on the page and we use them to help us align the design elements on our layout. Note that Gutter is set to 20 by default, leave this as it is. The Column Width is calculated by Muse and you should see a value of 41 appear automatically in that field. Remember that all of these values can be changed later if necessary. Click on OK. The Plan view opens and you'll see a thumbnail representing the Home page at the top left, and a thumbnail representing the A-Master page on the bottom pane. Save your site right away by selecting File | Save Site. Give it a descriptive name you'll recognize, such as Windsurf.muse. To create new pages, click on the plus (+) sign to the right of or below the existing pages, and then click on the page's name field to type its name. Click on the plus sign to the right of the Home page and name the new page Gear. Click on the plus sign below the Gear page to add a subpage and name that page Sails. Click on the plus sign to the right of the Sails page and name the new page Boards. Sails and Boards are now on the same level and are subpages of the Gear page. Click on the plus sign to the right of the Gear page and name the new page Learning. Click on the plus sign to the right of Learning and add one more page called Contact. Your Plan view should now look like the following screenshot: Working with thumbnails in the Plan view It's easy to add, delete, reposition, or duplicate pages when working in the Plan view. Right-click (Win) or Ctrl + click (Mac) on a thumbnail to see a contextual menu. This menu provides every option for managing your pages. In the previous screenshot, you can see the menu that appears when you right-click/Ctrl + click.   New Child Page: This option creates a new blank page at a lower level as the current thumbnail. New Sibling Page: This option creates a new blank page at the same level as the current thumbnail. Duplicate Page: This option makes an exact copy of the current page. This is most useful when you have added content and applied some formatting. Delete Page: This option gets rid of the page. Rename Page: This option allows us to change the name of the page. Go to Page: This option opens up the current page in the Design view. Page Properties: This option opens the Page Properties dialog box allowing you to set properties for the current page only. Reset Page Properties: This option reverts to the original settings for the page. Export Page: This option allows you to export your page as HTML and CSS. Menu Options: This option allows you to choose how the page will be included (or not included) in the automatically-created menu. Masters: This option lets you choose which Master design will be applied to the page. The context menu is not the only way to get to these options, for example the most common tasks in the Plan view can be completed as follows: You can rename a page by double-clicking on the page name You can delete a page by hovering your mouse over the thumbnail and then clicking on the x icon that appears in the top-right corner To reposition a page in your site map hierarchy, you can drag-and-drop a thumbnail on the same level or on a sublevel. Spend a couple of minutes adding, deleting, and repositioning pages so that you get a feel of creating the site structure. You'll find the Plan view to be intuitive to use and extremely fast for creating site maps. You can choose Edit | Undo to undo any of the steps you've taken. Muse tracks all the page names, and later in the design process it allows us to create menus quickly using menu widgets. All links created in the Plan view are maintained and are updated automatically if we make a change to the site structure. You can come back to the Plan view at any point during your web design process.
Read more
  • 0
  • 0
  • 2726

article-image-wpf-45-application-and-windows
Packt
24 Sep 2012
14 min read
Save for later

WPF 4.5 Application and Windows

Packt
24 Sep 2012
14 min read
Creating a window Windows are the typical top level controls in WPF. By default, a MainWindow class is created by the application wizard and automatically shown upon running the application. In this recipe, we'll take a look at creating and showing other windows that may be required during the lifetime of an application. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a new class derived from Window and show it when a button is clicked: Create a new WPF application named CH05.NewWindows. Right-click on the project node in Solution explorer, and select Add | Window…: In the resulting dialog, type OtherWindow in the Name textbox and click on Add. A file named OtherWindow.xaml should open in the editor. Add a TextBlock to the existing Grid, as follows: <TextBlock Text="This is the other window" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" /> Open MainWindow.xaml. Add a Button to the Grid with a Click event handler: <Button Content="Open Other Window" FontSize="30" Click="OnOpenOtherWindow" /> In the Click event handler, add the following code: void OnOpenOtherWindow(object sender, RoutedEventArgs e) { var other = new OtherWindow(); other.Show(); } Run the application, and click the button. The other window should appear and live happily alongside the main window: How it works... A Window is technically a ContentControl, so can contain anything. It's made visible using the Show method. This keeps the window open as long as it's not explicitly closed using the classic close button, or by calling the Close method. The Show method opens the window as modeless—meaning the user can return to the previous window without restriction. We can click the button more than once, and consequently more Window instances would show up. There's more... The first window shown can be configured using the Application.StartupUri property, typically set in App.xaml. It can be changed to any other window. For example, to show the OtherWindow from the previous section as the first window, open App.xaml and change the StartupUri property to OtherWindow.xaml: StartupUri="OtherWindow.xaml" Selecting the startup window dynamically Sometimes the first window is not known in advance, perhaps depending on some state or setting. In this case, the StartupUri property is not helpful. We can safely delete it, and provide the initial window (or even windows) by overriding the Application.OnStartup method as follows (you'll need to add a reference to the System.Configuration assembly for the following to compile): protected override void OnStartup(StartupEventArgs e) {    Window mainWindow = null;    // check some state or setting as appropriate          if(ConfigurationManager.AppSettings["AdvancedMode"] == "1")       mainWindow = new OtherWindow();    else       mainWindow = new MainWindow();    mainWindow.Show(); } This allows complete flexibility in determining what window or windows should appear at application startup. Accessing command line arguments The WPF application created by the New Project wizard does not expose the ubiquitous Main method. WPF provides this for us – it instantiates the Application object and eventually loads the main window pointed to by the StartupUri property. The Main method, however, is not just a starting point for managed code, but also provides an array of strings as the command line arguments passed to the executable (if any). As Main is now beyond our control, how do we get the command line arguments? Fortunately, the same OnStartup method provides a StartupEventArgs object, in which the Args property is mirrored from Main. The downloadable source for this chapter contains the project CH05.CommandLineArgs, which shows an example of its usage. Here's the OnStartup override: protected override void OnStartup(StartupEventArgs e) { string text = "Hello, default!"; if(e.Args.Length > 0) text = e.Args[0]; var win = new MainWindow(text); win.Show(); } The MainWindow instance constructor has been modified to accept a string that is later used by the window. If a command line argument is supplied, it is used. Creating a dialog box A dialog box is a Window that is typically used to get some data from the user, before some operation can proceed. This is sometimes referred to as a modal window (as opposed to modeless, or non-modal). In this recipe, we'll take a look at how to create and manage such a dialog box. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a dialog box that's invoked from the main window to request some information from the user: Create a new WPF application named CH05.Dialogs. Add a new Window named DetailsDialog.xaml (a DetailsDialog class is created). Visual Studio opens DetailsDialog.xaml. Set some Window properties: FontSize to 16, ResizeMode to NoResize, SizeToContent to Height, and make sure the Width is set to 300: ResizeMode="NoResize" SizeToContent="Height" Width="300" FontSize="16" Add four rows and two columns to the existing Grid, and add some controls for a simple data entry dialog as follows: <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Text="Please enter details:" Grid.ColumnSpan="2" Margin="4,4,4,20" HorizontalAlignment="Center"/> <TextBlock Text="Name:" Grid.Row="1" Margin="4"/> <TextBox Grid.Column="1" Grid.Row="1" Margin="4" x_Name="_name"/> <TextBlock Text="City:" Grid.Row="2" Margin="4"/> <TextBox Grid.Column="1" Grid.Row="2" Margin="4" x_Name="_city"/> <StackPanel Grid.Row="3" Orientation="Horizontal" Margin="4,20,4,4" Grid.ColumnSpan="2" HorizontalAlignment="Center"> <Button Content="OK" Margin="4"  /> <Button Content="Cancel" Margin="4" /> </StackPanel> This is how it should look in the designer: The dialog should expose two properties for the name and city the user has typed in. Open DetailsDialog.xaml.cs. Add two simple properties: public string FullName { get; private set; } public string City { get; private set; } We need to show the dialog from somewhere in the main window. Open MainWindow.xaml, and add the following markup to the existing Grid: <Grid.RowDefinitions>     <RowDefinition Height="Auto" />     <RowDefinition /> </Grid.RowDefinitions> <Button Content="Enter Data" Click="OnEnterData"         Margin="4" FontSize="16"/> <TextBlock FontSize="24" x_Name="_text" Grid.Row="1"     VerticalAlignment="Center" HorizontalAlignment="Center"/> In the OnEnterData handler, add the following: private void OnEnterData(object sender, RoutedEventArgs e) { var dlg = new DetailsDialog(); if(dlg.ShowDialog() == true) { _text.Text = string.Format( "Hi, {0}! I see you live in {1}.", dlg.FullName, dlg.City); } } Run the application. Click the button and watch the dialog appear. The buttons don't work yet, so your only choice is to close the dialog using the regular close button. Clearly, the return value from ShowDialog is not true in this case. When the OK button is clicked, the properties should be set accordingly. Add a Click event handler to the OK button, with the following code: private void OnOK(object sender, RoutedEventArgs e) { FullName = _name.Text; City = _city.Text; DialogResult = true; Close(); } The Close method dismisses the dialog, returning control to the caller. The DialogResult property indicates the returned value from the call to ShowDialog when the dialog is closed. Add a Click event handler for the Cancel button with the following code: private void OnCancel(object sender, RoutedEventArgs e) { DialogResult = false; Close(); } Run the application and click the button. Enter some data and click on OK: You will see the following window: How it works... A dialog box in WPF is nothing more than a regular window shown using ShowDialog instead of Show. This forces the user to dismiss the window before she can return to the invoking window. ShowDialog returns a Nullable (can be written as bool? in C#), meaning it can have three values: true, false, and null. The meaning of the return value is mostly up to the application, but typically true indicates the user dismissed the dialog with the intention of making something happen (usually, by clicking some OK or other confirmation button), and false means the user changed her mind, and would like to abort. The null value can be used as a third indicator to some other application-defined condition. The DialogResult property indicates the value returned from ShowDialog because there is no other way to convey the return value from the dialog invocation directly. That's why the OK button handler sets it to true and the Cancel button handler sets it to false (this also happens when the regular close button is clicked, or Alt + F4 is pressed). Most dialog boxes are not resizable. This is indicated with the ResizeMode property of the Window set to NoResize. However, because of WPF's flexible layout, it certainly is relatively easy to keep a dialog resizable (and still manageable) where it makes sense (such as when entering a potentially large amount of text in a TextBox – it would make sense if the TextBox could grow if the dialog is enlarged). There's more... Most dialogs can be dismissed by pressing Enter (indicating the data should be used) or pressing Esc (indicating no action should take place). This is possible to do by setting the OK button's IsDefault property to true and the Cancel button's IsCancel property to true. The default button is typically drawn with a heavier border to indicate it's the default button, although this eventually depends on the button's control template. If these settings are specified, the handler for the Cancel button is not needed. Clicking Cancel or pressing Esc automatically closes the dialog (and sets DiaglogResult to false). The OK button handler is still needed as usual, but it may be invoked by pressing Enter, no matter what control has the keyboard focus within the Window. The CH05.DefaultButtons project from the downloadable source for this chapter demonstrates this in action. Modeless dialogs A dialog can be show as modeless, meaning it does not force the user to dismiss it before returning to other windows in the application. This is done with the usual Show method call – just like any Window. The term dialog in this case usually denotes some information expected from the user that affects other windows, sometimes with the help of another button labelled "Apply". The problem here is mostly logical—how to convey the information change. The best way would be using data binding, rather than manually modifying various objects. We'll take an extensive look at data binding in the next chapter. Using the common dialog boxes Windows has its own built-in dialog boxes for common operations, such as opening files, saving a file, and printing. Using these dialogs is very intuitive from the user's perspective, because she has probably used those dialogs before in other applications. WPF wraps some of these (native) dialogs. In this recipe, we'll see how to use some of the common dialogs. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a simple image viewer that uses the Open common dialog box to allow the user to select an image file to view: Create a new WPF Application named CH05.CommonDialogs. Open MainWindow.xaml. Add the following markup to the existing Grid: <Grid.RowDefinitions>     <RowDefinition Height="Auto" />     <RowDefinition /> </Grid.RowDefinitions> <Button Content="Open Image" FontSize="20" Click="OnOpenImage"         HorizontalAlignment="Center" Margin="4" /> <Image Grid.Row="1" x_Name="_img" Stretch="Uniform" /> Add a Click event handler for the button. In the handler, we'll first create an OpenFileDialog instance and initialize it (add a using to the Microsoft.Win32 namespace): void OnOpenImage(object sender, RoutedEventArgs e) { var dlg = new OpenFileDialog { Filter = "Image files|*.png;*.jpg;*.gif;*.bmp", Title = "Select image to open", InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.MyPictures) }; Now we need to show the dialog and use the selected file (if any): if(dlg.ShowDialog() == true) { try { var bmp = new BitmapImage(new Uri(dlg.FileName)); _img.Source = bmp; } catch(Exception ex) { MessageBox.Show(ex.Message, "Open Image"); } } Run the application. Click the button and navigate to an image file and select it. You should see something like the following: How it works... The OpenFileDialog class wraps the Win32 open/save file dialog, providing easy enough access to its capabilities. It's just a matter of instantiating the object, setting some properties, such as the file types (Filter property) and then calling ShowDialog. This call, in turn, returns true if the user selected a file and false otherwise (null is never returned, although the return type is still defined as Nullable for consistency). The look of the Open file dialog box may be different in various Windows versions. This is mostly unimportant unless some automated UI testing is done. In this case, the way the dialog looks or operates may have to be taken into consideration when creating the tests. The filename itself is returned in the FileName property (full path). Multiple selections are possible by setting the MultiSelect property to true (in this case the FileNames property returns the selected files). There's more... WPF similarly wraps the Save As common dialog with the SaveFileDialog class (in the Microsoft.Win32 namespace as well). Its use is very similar to OpenFileDialog (in fact, both inherit from the abstract FileDialog class). What about folder selection (instead of files)? The WPF OpenFileDialog does not support that. One solution is to use Windows Forms' FolderBrowseDialog class. Another good solution is to use the Windows API Code Pack described shortly. Another common dialog box WPF wraps is PrintDialog (in System.Windows.Controls). This shows the familiar print dialog, with options to select a printer, orientation, and so on. The most straightforward way to print would be calling PrintVisual (after calling ShowDialog), providing anything that derives from the Visual abstract class (which include all elements). General printing is a complex topic and is beyond the scope of this book. What about colors and fonts? Windows also provides common dialogs for selecting colors and fonts. However, these are not wrapped by WPF. There are several alternatives: Use the equivalent Windows Forms classes (FontDialog and ColorDialog, both from System.Windows.Forms) Wrap the native dialogs yourself Look for alternatives on the Web The first option is possible, but has two drawbacks: first, it requires adding reference to the System.Windows.Forms assembly; this adds a dependency at compile time, and increases memory consumption at run time, for very little gain. The second drawback has to do with the natural mismatch between Windows Forms and WPF. For example, ColorDialog returns a color as a System.Drawing.Color, but WPF uses System.Windows.Media.Color. This requires mapping a GDI+ color (WinForms) to WPF's color, which is cumbersome at best. The second option of doing your own wrapping is a non-trivial undertaking and requires good interop knowledge. The other downside is that the default color and font common dialogs are pretty old (especially the color dialog), so there's much room for improvement. The third option is probably the best one. There are more than a few good candidates for color and font pickers. For a color dialog, for example, you can use the ColorPicker or ColorCanvas provided with the Extended WPF toolkit library on CodePlex (http://wpftoolkit.codeplex.com/). Here's how these may look (ColorCanvas on the left-hand side, and one of the possible views of ColorPicker on the right-hand side): The Windows API Code Pack The Windows API Code Pack is a Microsoft project on CodePlex (http://archive.msdn.microsoft.com/WindowsAPICodePack) that provides many .NET wrappers to native Windows features, in various areas, such as shell, networking, Windows 7 features (this is less important now as WPF 4 added first class support for Windows 7), power management, and DirectX. One of the Shell features in the library is a wrapper for the Open dialog box that allows selecting a folder instead of a file. This has no dependency on the WinForms assembly.
Read more
  • 0
  • 0
  • 6547

article-image-extgwt-rich-internet-application-crafting-ui-real-estate
Packt
14 Sep 2012
3 min read
Save for later

ExtGWT Rich Internet Application: Crafting UI Real Estate

Packt
14 Sep 2012
3 min read
(For more resources on ExtGwt, see here.) Introduction Layouts are a fundamental part of the GXT library. They provide the ability to create flexible and beautiful application UIs easily. However, with this power comes a level of complexity. A solid understanding of layouts is the key to using the library effectively. With GWT Panels, the panel itself is responsible for creating the panel's markup and inserting its children at the appropriate location, and creating appropriate markup as changes are made. Unlike GWT Panels, LayoutContainer (a concrete GXT container with support for layouts) does not physically connect its child components to the container's DOM. The Document Object Model is used to represent an HTML document in a tree-like structure in the browser's memory. We can dynamically change the content of the HTML page by manipulating the DOM. Rather, it is the job of the layout to both build the internal structure of the container, and to connect its child widgets. In order for a GXT container's HTML to be rendered, the container's layout() method must execute. This is different from GWT panels, in which the HTML is rendered when the components are attached to the panel. There are several ways in which the layout can execute. For now, let's go with the simplest case in which the layout executes when the container is attached. Attached is a GWT term that indicates that the widget is part of the browser's DOM. Attaching and detaching could be a subject on its own, so let's just assume it means when the widget is added to and removed from the page. When we add a container to RootPanel (for example, RootPanel.get(). add(container)), the container will be attached, and the container's layout will execute, generating the needed HTML markup. If we add another component to the now rendered container, (container.add(new Label("New Item"))) we will have to manually execute/ refresh the container (container.layout()) for the additions (as well as removals) to be effected. This sort of Lazy-Rendering is the default behavior of GXT as of 2.2.3 with GXT 3 planning to use the same approach as GWT itself. Many GXT layouts can be used in conjunction with LayoutData, which are configuration objects assigned to each child widget within a container, and provides the layout object with additional information to be used when executing the layout. Aside from a layout being executed when the container is attached, or when layout() is called manually on the container, there are two other ways in which a layout will be executed. After a container executes its layout, it looks and sees if any of its children are containers. When it finds a child container, it then executes its layout. So as long as there is a chain of containers, the execution of layouts will cascade to the child containers. This is a very important concept as you can lay out a top-level container, and the child containers will have a chance to adjust their layouts as well. A container's layout will also execute when its size is adjusted. This is default behavior, and can be disabled. This is another important concept as it means that if a container's size is changed, the layout has a chance to update based on the container's new size.
Read more
  • 0
  • 0
  • 1294
Visually different images

Packt
11 Sep 2012
7 min read
Save for later

Getting Started with RapidWeaver

Packt
11 Sep 2012
7 min read
In this article by Joe Workman, the author of RapidWeaver Beginner's Guide, we will learn the basics of RapidWeaver. Mainly, we will cover the following topics: What is RapidWeaver? Installing RapidWeaver Creating our first web page Publishing our website on the Internet So strap your seat belts on and let's have some fun! What is RapidWeaver? RapidWeaver is a web development and design application for Mac that was developed by Realmac Software. It allows you to build stunning, professional websites very easily. RapidWeaver has both the novice and professional web designer covered. If you don't know (or don't want to know) how to code, RapidWeaver supports full code-free creation of your website; from blogs to site maps, photo albums to contact forms, you can build your entire website without a single line of code! Without a doubt, RapidWeaver appeals to the aspiring novice web designer. However, it does not forget about the geeky, code loving, power users! And in case you were wondering…yeah, that includes me! RapidWeaver gives us geeks full access to peek under the hood. You can effortlessly add your own HTML or PHP file to any page. You can customize the look and feel with your own CSS file. For example, maybe you would like to add your own JavaScript for the latest and greatest animations out there; not a problem, RapidWeaver has got you covered. We even have full access to the amazing WebKit Developer Tools from directly inside the application. As RapidWeaver has all of these advanced features, it really serves as a catalyst to help an aspiring, novice web designer become a geeky, code loving, power user. RapidWeaver's theme engine is a godsend for those users who are design challenged. However, it's also for those who don't want to spend time developing a site theme as they can leverage the work that some amazing theme developers have already done. Yeah, this includes me too! RapidWeaver ships with over 45 stunning themes built-in. This means that you can have a website that was designed by some world-class web designers. Each theme can be customized to your liking with just a few clicks. If you ever get tired of how your website looks, you can change your theme as often as you like. And your website content will remain 100 percent intact. Once you have your website fully constructed, RapidWeaver makes it very simple to publish your website online. It will be able to publish to pretty much every web host around through its native support for both FTP and SFTP. You will be able to publish your website for the world to see with a single click. iWeb versus RapidWeaver versus Dreamweaver RapidWeaver is most commonly compared with both iWeb and Dreamweaver. While there are definitely direct feature comparisons, we are trying to compare apples with oranges. RapidWeaver is a great tool that falls somewhere between iWeb at one end of the scale and Dreamweaver at the other end. Apple's iWeb was their first foray into personal web development software. In true Apple fashion, the application was extremely user friendly and developed beautiful websites. However, the application was really geared towards users who wanted to create a small website to share family photos and maybe have a blog. iWeb was not very extensible at all. If you ever wanted to try to steer outside the bounds of the default templates, you had to drive directly into full custom HTML. One of the biggest downsides that I came across was that once you choose the look and feel of your site, there was no going back. If you wanted to change the theme of your website, you had to redo every single page manually! For those of you who love the drag-and-drop abilities of iWeb, look no further than the RapidWeaver Stacks plugin from YourHead Software. Apple has acknowledged iWeb's shortcomings by pretty much removing iWeb from its lineup. You cannot purchase iWeb from Apple's Mac App Store. Furthermore, if you look at Apple's iLife page on their website, all traces of iWeb have been removed—if this is not a clear sign of iWeb's future, I don't know what is. Now, let's jump to the opposite end of the spectrum with Adobe Dreamweaver. Dreamweaver has a much steeper learning curve than RapidWeaver (not to mention a much steeper price tag). Dreamweaver has a lot of capability for site management and can be used collaboratively on projects, and is designed to play well with Adobe's other design software. The Adobe Creative Suite with Dreamweaver is the package of choice for very large organizational websites being developed and managed by a team, or for complex dynamic sites. I am talking about websites such as http://www.apple.com or http://www.nytimes.com. For individual and small to mid-sized business websites, I can't think of a reason why one would prefer Dreamweaver to RapidWeaver. So as I stated at the beginning, RapidWeaver provides a perfect middle ground for novice web designers and geeky code lovers! It's more than an app So far, I have talked about the RapidWeaver application itself. However, RapidWeaver is so much more than just an application. The user community that has been built around the RapidWeaver product is like nothing I have seen with any other application. The RapidWeaver forums hosted by Realmac are by far the most active and useful forums that I have seen. Users and developers spend countless hours helping each other with tips and tricks on design, code, and product support. It's a worldwide community that is truly active 24/7. You can find the forums at http://forums.realmacsoftware.com. A part of the success of the strong RapidWeaver community is the strong third-party developers that exist. RapidWeaver provides a strong and flexible platform for developers to extend the application beyond its default feature set. There are currently three primary ways to extend your RapidWeaver application: Themes, Plugins, and Stacks. As you may guess, third-party theme developers design custom themes that go above and beyond the themes that ship out of the box with RapidWeaver. With the number of amazing theme developers out there, it would be impossible not to develop a site that fits your style and looks amazing. RapidWeaver ships with 11 page styles out of the box. Blog Contact Form File Sharing HTML Code iFrame Movie Album Offsite Page Photo Album QuickTime Sitemap Styled Text However, RapidWeaver plugins can create even more page styles for you. There are a plethora of different page plugins from calendars to file uploads, and shopping carts to image galleries. To illustrate the power of RapidWeaver's platform, YourHead Software developed the Stacks plugin for fluid page layout. The Stacks plugin created an entire new class of third-party RapidWeaver developer: the stack developer! A stack is simply a widget that can be used as a building block to construct your web page. There are stacks for just about anything: animated banners, menu systems, photo galleries, or even full-blown blog integrations. If you can dream it up, there is probably a stack for it! If you have visited my website, then you should know that my origins in the RapidWeaver community are as a Stacks Developer. I think that Stacks is amazing and should probably be the first plugin that you should consider acquiring. Realmac Software has added a section on their website in order to make it easier for users to explore and locate useful third-party add-ons. So make sure that you go check it out and peruse through all the great themes, plugins, and stacks! You can browse the add-ons at http://www.realmacsoftware.com/addons.
Read more
  • 0
  • 0
  • 4088

article-image-getting-started-with-rapidweaver
Packt
09 Sep 2012
7 min read
Save for later

Getting Started withRapidWeaver

Packt
09 Sep 2012
7 min read
In this article by Joe Workman, the author of RapidWeaver Beginner's Guide, we will learn the basics of RapidWeaver. Mainly, we will cover the following topics: What is RapidWeaver? Installing RapidWeaver Creating our first web page Publishing our website on the Internet So strap your seat belts on and let's have some fun! What is RapidWeaver? RapidWeaver is a web development and design application for Mac that was developed by Realmac Software. It allows you to build stunning, professional websites very easily. RapidWeaver has both the novice and professional web designer covered. If you don't know (or don't want to know) how to code, RapidWeaver supports full code-free creation of your website; from blogs to site maps, photo albums to contact forms, you can build your entire website without a single line of code! Without a doubt, RapidWeaver appeals to the aspiring novice web designer. However, it does not forget about the geeky, code loving, power users! And in case you were wondering…yeah, that includes me! RapidWeaver gives us geeks full access to peek under the hood. You can effortlessly add your own HTML or PHP file to any page. You can customize the look and feel with your own CSS file. For example, maybe you would like to add your own JavaScript for the latest and greatest animations out there; not a problem, RapidWeaver has got you covered. We even have full access to the amazing WebKit Developer Tools from directly inside the application. As RapidWeaver has all of these advanced features, it really serves as a catalyst to help an aspiring, novice web designer become a geeky, code loving, power user. RapidWeaver's theme engine is a godsend for those users who are design challenged. However, it's also for those who don't want to spend time developing a site theme as they can leverage the work that some amazing theme developers have already done. Yeah, this includes me too! RapidWeaver ships with over 45 stunning themes built-in. This means that you can have a website that was designed by some world-class web designers. Each theme can be customized to your liking with just a few clicks. If you ever get tired of how your website looks, you can change your theme as often as you like. And your website content will remain 100 percent intact. Once you have your website fully constructed, RapidWeaver makes it very simple to publish your website online. It will be able to publish to pretty much every web host around through its native support for both FTP and SFTP. You will be able to publish your website for the world to see with a single click. iWeb versus RapidWeaver versus Dreamweaver RapidWeaver is most commonly compared with both iWeb and Dreamweaver. While there are definitely direct feature comparisons, we are trying to compare apples with oranges. RapidWeaver is a great tool that falls somewhere between iWeb at one end of the scale and Dreamweaver at the other end. Apple's iWeb was their first foray into personal web development software. In true Apple fashion, the application was extremely user friendly and developed beautiful websites. However, the application was really geared towards users who wanted to create a small website to share family photos and maybe have a blog. iWeb was not very extensible at all. If you ever wanted to try to steer outside the bounds of the default templates, you had to drive directly into full custom HTML. One of the biggest downsides that I came across was that once you choose the look and feel of your site, there was no going back. If you wanted to change the theme of your website, you had to redo every single page manually! For those of you who love the drag-and-drop abilities of iWeb, look no further than the RapidWeaver Stacks plugin from YourHead Software. Apple has acknowledged iWeb's shortcomings by pretty much removing iWeb from its lineup. You cannot purchase iWeb from Apple's Mac App Store. Furthermore, if you look at Apple's iLife page on their website, all traces of iWeb have been removed—if this is not a clear sign of iWeb's future, I don't know what is. Now, let's jump to the opposite end of the spectrum with Adobe Dreamweaver. Dreamweaver has a much steeper learning curve than RapidWeaver (not to mention a much steeper price tag). Dreamweaver has a lot of capability for site management and can be used collaboratively on projects, and is designed to play well with Adobe's other design software. The Adobe Creative Suite with Dreamweaver is the package of choice for very large organizational websites being developed and managed by a team, or for complex dynamic sites. I am talking about websites such as http://www.apple.com or http://www.nytimes.com. For individual and small to mid-sized business websites, I can't think of a reason why one would prefer Dreamweaver to RapidWeaver. So as I stated at the beginning, RapidWeaver provides a perfect middle ground for novice web designers and geeky code lovers! It's more than an app So far, I have talked about the RapidWeaver application itself. However, RapidWeaver is so much more than just an application. The user community that has been built around the RapidWeaver product is like nothing I have seen with any other application. The RapidWeaver forums hosted by Realmac are by far the most active and useful forums that I have seen. Users and developers spend countless hours helping each other with tips and tricks on design, code, and product support. It's a worldwide community that is truly active 24/7. You can find the forums at http://forums.realmacsoftware.com. A part of the success of the strong RapidWeaver community is the strong third-party developers that exist. RapidWeaver provides a strong and flexible platform for developers to extend the application beyond its default feature set. There are currently three primary ways to extend your RapidWeaver application: Themes, Plugins, and Stacks. As you may guess, third-party theme developers design custom themes that go above and beyond the themes that ship out of the box with RapidWeaver. With the number of amazing theme developers out there, it would be impossible not to develop a site that fits your style and looks amazing. RapidWeaver ships with 11 page styles out of the box. Blog Contact Form File Sharing HTML Code iFrame Movie Album Offsite Page Photo Album QuickTime Sitemap Styled Text However, RapidWeaver plugins can create even more page styles for you. There are a plethora of different page plugins from calendars to file uploads, and shopping carts to image galleries. To illustrate the power of RapidWeaver's platform, YourHead Software developed the Stacks plugin for fluid page layout. The Stacks plugin created an entire new class of third-party RapidWeaver developer: the stack developer! A stack is simply a widget that can be used as a building block to construct your web page. There are stacks for just about anything: animated banners, menu systems, photo galleries, or even full-blown blog integrations. If you can dream it up, there is probably a stack for it! If you have visited my website, then you should know that my origins in the RapidWeaver community are as a Stacks Developer. I think that Stacks is amazing and should probably be the first plugin that you should consider acquiring. Realmac Software has added a section on their website in order to make it easier for users to explore and locate useful third-party add-ons. So make sure that you go check it out and peruse through all the great themes, plugins, and stacks! You can browse the add-ons at http://www.realmacsoftware.com/addons.
Read more
  • 0
  • 0
  • 3350

article-image-loading-submitting-and-validating-forms-using-ext-js-4
Packt
31 Aug 2012
25 min read
Save for later

Working with forms using Ext JS 4

Packt
31 Aug 2012
25 min read
Ext JS 4 is Sencha’s latest JavaScript framework for developing cross-platform web applications. Built upon web standards, Ext JS provides a comprehensive library of user interface widgets and data manipulation classes to turbo-charge your application’s development. In this article, written by Stuart Ashworth and Andrew Duncan, the authors of Ext JS 4 Web Application Development Cookbook, we will cover: Constructing a complex form layout Populating your form with data Submitting your form's data Validating form fields with VTypes Creating custom VTypes Uploading files to the server Handling exceptions and callbacks This article introduces forms in Ext JS 4. We begin by creating a support ticket form in the first recipe. To get the most out of this article you should be aware that this form is used by a number of recipes throughout the article. Instead of focusing on how to configure specific fields, we demonstrate more generic tasks for working with forms. Specifically, these are populating forms, submitting forms, performing client-side validation, and handling callbacks/exceptions. Constructing a complex form layout In the previous releases of Ext JS, complicated form layouts were quite difficult to achieve. This was due to the nature of the FormLayout, which was required to display labels and error messages correctly, and how it had to be combined with other nested layouts. Ext JS 4 takes a different approach and utilizes the Ext.form.Labelable mixin, which allows form fields to be decorated with labels and error messages without requiring a specific layout to be applied to the container. This means we can combine all of the layout types the framework has to offer without having to overnest components in order to satisfy the form field's layout requirements. We will describe how to create a complex form using multiple nested layouts and demonstrate how easy it is to get a form to look exactly as we want. Our example will take the structure of a Support Ticket Request form and, once we are finished, it will look like the following screenshot: (Move the mouse over the image to enlarge.) How to do it... We start this recipe by creating a simple form panel that will contain all of the layout containers and their fields: var formPanel = Ext.create('Ext.form.Panel', { title: 'Support Ticket Request', width: 650, height: 500, renderTo: Ext.getBody(), style: 'margin: 50px', items: [] }); Now, we will create our first set of fields— the FirstName and LastName fields. These will be wrapped in an Ext.container.Container component, which is given an hbox layout so our fields appear next to each other on one line: var formPanel = Ext.create('Ext.form.Panel', { title: 'Support Ticket Request', width: 650, height: 500, renderTo: Ext.getBody(), style: 'margin: 50px', items: [{ xtype: 'container', layout: 'hbox', items: [{ xtype: 'textfield', fieldLabel: 'First Name', name: 'FirstName', labelAlign: 'top', cls: 'field-margin', flex: 1 }, { xtype: 'textfield', fieldLabel: 'Last Name', name: 'LastName', labelAlign: 'top', cls: 'field-margin', flex: 1 }] }] }); We have added a CSS class (field-margin) to each field, to provide some spacing between them. We can now add this style inside <style> tags in the head of our document: <style type="text/css"> .field-margin { margin: 10px; }</style> Next, we create a container with a column layout to position our e-mail address and telephone number fields. We nest our telephone number fields in an Ext.form.FieldContainer class , which we will discuss later in the recipe: items: [ ... { xtype: 'container', layout: 'column', items: [{ xtype: 'textfield', fieldLabel: 'Email Address', name: 'EmailAddress', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.6 }, { xtype: 'fieldcontainer', layout: 'hbox', fieldLabel: 'Tel. Number', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.4, items: [{ xtype: 'textfield', name: 'TelNumberCode', style: 'margin-right: 5px;', flex: 2 }, { xtype: 'textfield', name: 'TelNumber', flex: 4 }] }] } ... ] The text area and checkbox group are created and laid out in a similar way to the previous sets, by using an hbox layout: items: [ ... { xtype: 'container', layout: 'hbox', items: [{ xtype: 'textarea', fieldLabel: 'Request Details', name: 'RequestDetails', labelAlign: 'top', cls: 'field-margin', height: 250, flex: 2 }, { xtype: 'checkboxgroup', name: 'RequestType', fieldLabel: 'Request Type', labelAlign: 'top', columns: 1, cls: 'field-margin', vertical: true, items: [{ boxLabel: 'Type 1', name: 'type1', inputValue: '1' }, { boxLabel: 'Type 2', name: 'type2', inputValue: '2' }, { boxLabel: 'Type 3', name: 'type3', inputValue: '3' }, { boxLabel: 'Type 4', name: 'type4', inputValue: '4' }, { boxLabel: 'Type 5', name: 'type5', inputValue: '5' }, { boxLabel: 'Type 6', name: 'type6', inputValue: '6' }], flex: 1 }] } ... ] Finally, we add the last field, which is a file upload field, to allow users to provide attachments: items: [ ... { xtype: 'filefield', cls: 'field-margin', fieldLabel: 'Attachment', width: 300 } ... ] How it works... All Ext JS form fields inherit from the base Ext.Component class and so can be included in all of the framework's layouts. For this reason, we can include form fields as children of containers with layouts (such as hbox and column layouts) and their position and size will be calculated accordingly. Upgrade Tip: Ext JS 4 does not have a form layout meaning a level of nesting can be removed and the form fields' labels will still be displayed correctly by just specifying the fieldLabel config. The Ext.form.FieldContainer class used in step 4 is a special component that allows us to combine multiple fields into a single container, which also implements the Ext.form. Labelable mixin . This allows the container itself to display its own label that applies to all of its child fields while also giving us the opportunity to configure a layout for its child components. Populating your form with data After creating our beautifully crafted and user-friendly form we will inevitably need to populate it with some data so users can edit it. Ext JS makes this easy, and this recipe will demonstrate four simple ways of achieving it. We will start by explaining how to populate the form on a field-by-field basis, then move on to ways of populating the entire form at once. We will also cover populating it from a simple object, a Model instance, and a remote server call. Getting ready We will be using the form created in this article's first recipe as our base for this section, and many of the subsequent recipes in this article, so please look back if you are not familiar with it. All the code we will write in this recipe should be placed under the definition of this form panel. You will also require a working web server for the There's More example, which loads data from an external file. How to do it... We'll demonstrate how to populate an entire form's fields in bulk and also how to populate them individually. Populating individual fields We will start by grabbing a reference to the first name field using the items property's get method. The items property contains an instance of Ext.util. MixedCollection, which holds a reference to each of the container's child components. We use its get method to retrieve the component at the specified index: var firstNameField = formPanel.items.get(0).items.get(0); Next, we use the setValue method of the field to populate it: firstNameField.setValue('Joe'); Populating the entire form To populate the entire form, we must create a data object containing a value for each field. The property names of this object will be mapped to the corresponding form field by the field's name property. For example, the FirstName property of our requestData object will be mapped to a form field with a name property value of FirstName: var requestData = { FirstName: 'Joe', LastName: 'Bloggs', EmailAddress: '[email protected]', TelNumberCode: '0777', TelNumber: '7777777', RequestDetails: 'This is some Request Detail body text', RequestType: { type1: true, type2: false, type3: false, type4: true, type5: true, type6: false } }; We then call the setValues method of the form panel's Ext.form.Basic instance, accessed through the getForm method, passing it our requestData variable: formPanel.getForm().setValues(requestData); How it works... Each field contains a method called setValue , which updates the field's value with the value that is passed in. We can see this in action in the first part of the How to do it section. A form panel contains an internal instance of the Ext.form.Basic class (accessible through the getForm method ), which provides all of the validation, submission, loading, and general field management that is required by a form. This class contains a setValues method , which can be used to populate all of the fields that are managed by the basic form class. This method works by simply iterating through all of the fields it contains and calling their respective setValue methods. This method accepts either a simple data object, as in our example, whose properties are mapped to fields based on the field's name property. Alternatively, an array of objects can be supplied, containing id and value properties, with the id mapping to the field's name property. The following code snippet demonstrates this usage: formPanel.getForm().setValues([{id: 'FirstName', value: 'Joe'}]);   There's more... Further to the two previously discussed methods there are two others that we will demonstrate here. Populating a form from a Model instance Being able to populate a form directly from a Model instance is extremely useful and is very simple to achieve. This allows us to easily translate our data structures into a form without having to manually map it to each field. We initially define a Model and create an instance of it (using the data object we used earlier in the recipe): Ext.define('Request', { extend: 'Ext.data.Model', fields: [ 'FirstName', 'LastName', 'EmailAddress', 'TelNumberCode', 'TelNumber', 'RequestDetails', 'RequestType' ] }); var requestModel = Ext.create('Request', requestData); Following this we call the loadRecord method of the Ext.form.Basic class and supply the Model instance as its only parameter. This will populate the form, mapping each Model field to its corresponding form field based on the name: formPanel.getForm().loadRecord(requestModel); Populating a form directly from the server It is also possible to load a form's data directly from the server through an AJAX call. Firstly, we define a JSON file, containing our request data, which will be loaded by the form: { "success": true, "data": { "FirstName": "Joe", "LastName": "Bloggs", "EmailAddress": "[email protected]", "TelNumberCode": "0777", "TelNumber": "7777777", "RequestDetails": "This is some Request Detail body text", "RequestType": { "type1": true, "type2": false, "type3": false, "type4": true, "type5": true, "type6": false } } } Notice the format of the data: we must provide a success property to indicate that the load was successful and put our form data inside a data property. Next we use the basic form's load method and provide it with a configuration object containing a url property pointing to our JSON file: formPanel.getForm().load({ url: 'requestDetails.json' }); This method automatically performs an AJAX request to the specified URL and populates the form's fields with the data that was retrieved. This is all that is required to successfully load the JSON data into the form. The basic form's load method accepts similar configuration options to a regular AJAX request Submitting your form's data Having taken care of populating the form it's now time to look at sending newly added or edited data back to the server. As with form population you'll learn just how easy this is with the Ext JS framework. There are two parts to this example. Firstly, we will submit data using the options of the basic form that wraps the form panel. The second example will demonstrate binding the form to a Model and saving our data. Getting ready We will be using the form created in the first recipe as our base for this section, so refer to the Constructing a complex form layout recipe, if you are not familiar with it. How to do it... Add a function to submit the form: var submitForm = function(){ formPanel.getForm().submit({ url: 'submit.php' }); }; Add a button to the form that calls the submitForm function: var formPanel = Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Submit Form', handler: submitForm }], items: [ ... ] }); How it works... As we learned in the previous recipe, a form panel contains an internal instance of the Ext.form.Basic class (accessible through the getForm method). The submit method in Ext.form.Basic is a shortcut to the Ext.form.action.Submit action. This class handles the form submission for us. All we are required to do is provide it with a URL and it will handle the rest. It's also possible to define the URL in the configuration for the Ext.form.Panel.. Before submitting, it must first gather the data from the form. The Ext.form.Basic class contains a getValues method, which is used to gather the data values for each form field. It does this by iterating through all fields in the form making a call to their respective getValue methods. There's more... The previous recipe demonstrated how to populate the form from a Model instance. Here we will take it a step further and use the same Model instance to submit the form as well. Submitting a form from a Model instance Extend the Model with a proxy and load the data into the form: xt.define('Request', { extend: 'Ext.data.Model', fields: ['FirstName', 'LastName', 'EmailAddress', 'TelNumberCode', 'TelNumber', 'RequestDetails', 'RequestType'], proxy: { type: 'ajax', api: { create: 'addTicketRequest.php', update: 'updateTicketRequest.php' }, reader: { type: 'json' } } }); var requestModel = Ext.create('Request', { FirstName: 'Joe', LastName: 'Bloggs', EmailAddress: '[email protected]' }); formPanel.getForm().loadRecord(requestModel); Change the submitForm function to get the Model instance, update the record with the form data, and save the record to the server: var submitForm = function(){ var record = formPanel.getForm().getRecord(); formPanel.getForm().updateRecord(record); record.save(); }; Validating form fields with VTypes In addition to form fields' built-in validation (such as allowBlank and minLength), we can apply more advanced and more extensible validation by using VTypes. A VType (contained in the Ext.form.field.VTypes singleton) can be applied to a field and its validation logic will be executed as part of the field's periodic validation routine. A VType encapsulates a validation function, an error message (which will be displayed if the validation fails), and a regular expression mask to prevent any undesired characters from being entered into the field. This recipe will explain how to apply a VType to the e-mail address field in our example form, so that only properly formatted e-mail addresses are deemed valid and an error will be displayed if it doesn't conform to this pattern. How to do it... We will start by defining our form and its fields. We will be using our example form that was created in the first recipe of this article as our base. Now that we have a form we can add the vtype configuration option to our e-mail address field: { xtype: 'textfield', fieldLabel: 'Email Address', name: 'EmailAddress', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.6, vtype: 'email' } That is all we have to do to add e-mail address validation to a field. We can see the results in the following screenshot, with an incorrectly formatted e-mail address on the left and a valid one on the right: How it works... When a field is validated it runs through various checks. When a VType is defined the associated validation routine is executed and will flag the field invalid or not . As previously mentioned, each VType has an error message coupled with it, which is displayed if it is found to be invalid, and a mask expression which prevents unwanted characters being entered. Unfortunately, only one VType can be applied to a field and so, if multiple checks are required, a custom hybrid may need to be created. See the next recipe for details on how to do this. There's more... Along with the e-mail VType, the framework provides three other VTypes that can be applied straight out of the box. These are: alpha: this restricts the field to only alphabetic characters alphnum: this VType allows only alphanumeric characters url: this ensures that the value is a valid URL Creating custom VTypes We have seen in the previous recipe how to use VTypes to apply more advanced validation to our form's fields. The built-in VTypes provided by the framework are excellent but we will often want to create custom implementations to impose more complex and domain specific validation to a field. We will walkthrough creating a custom VType to be applied to our telephone number field to ensure it is in the format that a telephone number should be. Although our telephone number field is split into two (the first field for the area code and the second for the rest of the number), for this example we will combine them so our VType is more comprehensive. For this example, we will be validating a very simple, strict telephone number format of "0777-777-7777". How to do it... We start by defining our VType's structure. This consists of a simple object literal with three properties. A function called telNumber and two strings called telNumberText (which will contain the error message text) and telNumberMask (which holds a regex to restrict the characters allowed to be entered into the field) respectively. var telNumberVType = { telNumber: function(val, field){ // function executed when field is validated // return true when field's value (val) is valid return true; }, telNumberText: 'Your Telephone Number must only include numbers and hyphens.', telNumberMask: /[d-]/ }; Next we define the regular expression that we will use to validate the field's value. We add this as a variable to the telNumber function: telNumber: function(val, field){ var telNumberRegex = /^d{4}-d{3}-d{4}$/; return true; } Once this has been done we can add the logic to this telNumber function that will decide whether the field's current value is valid. This is a simple call to the regular expression string's test method, which returns true if the value matches or false if it doesn't: telNumber: function(val, field){ var telNumberRegex = /^d{4}-d{3}-d{4}$/; return telNumberRegex.test(val); } The final step to defining our new VType is to apply it to the Ext.form.field. VTypes singleton, which is where all of the VTypes are located and where our field's validation routine will go to get its definition: Ext.apply(Ext.form.field.VTypes, telNumberVType); Now that our VType has been defined and registered with the framework, we can apply it to the field by using the vtype configuration option. The result can be seen in the following screenshot: { xtype: 'textfield', name: 'TelNumber', flex: 4, vtype: 'telNumber' } How it works... A VType consists of three parts: The validity checking function The validation error text A keystroke filtering mask (optional) VTypes rely heavily on naming conventions so they can be executed dynamically within a field's validation routine. This means that each of these three parts must follow the standard convention. The validation function's name will become the name used to reference the VType and form the prefix for the other two properties. In our example, this name was telNumber, which can be seen referencing the VType in Step 5. The error text property is then named with the VType's name prefixing the word Text (that is, telNumberText ). Similarly, the filtering mask is the VType's name followed by the word Mask (that is, telNumberMask ). The final step to create our VType is to merge it into the Ext.form.field.VTypes singleton allowing it to be accessed dynamically during validation. The Ext.apply function does this by merging the VType's three properties into the Ext.form.field.VTypes class instance. When the field is validated, and a vtype is defined, the VType's validation function is executed with the current value of the field and a reference to the field itself being passed in. If the function returns true then all is well and the routine moves on. However, if it evaluates to false the VType's Text property is retrieved and pushed onto the errors array. This message is then displayed to the user as our screenshot shown earlier. This process can be seen in the code snippet as follows, taken directly from the framework: if (vtype) { if(!vtypes[vtype](value, me)){ errors.push(me.vtypeText || vtypes[vtype +'Text']); } } There's more... It is often necessary to validate fields based on the values of other fields as well as their own. We will demonstrate this by creating a simple VType for validating that a confirm password field's value matches the value entered in an initial password field. We start by creating our VType structure as we did before: Ext.apply(Ext.form.field.VTypes, { password: function(val, field){ return false; }, passwordText: 'Your Passwords do not match.' }); We then complete the validation logic. We use the field's up method to get a reference to its parent form. Using that reference, we get the values for all of the form's fields by using the getValues method : password: function(val, field){ var parentForm = field.up('form'); // get parent form // get the form's values var formValues = parentForm.getValues(); return false; } The next step is to get the first password field's value. We do this by using an extra property ( firstPasswordFieldName) that we will specify when we add our VType to the confirm password field. This property will contain the name of the initial password field (in this example Password ). We can then compare the confirm password's value with the retrieved value and return the outcome: password: function(val, field){ var parentForm = field.up('form'); // get parent form // get the form's values var formValues = parentForm.getValues(); // get the value from the configured 'First Password' field var firstPasswordValue = formValues[field.firstPasswordFieldName]; // return true if they match return val === firstPasswordValue; } The VType is added to the confirm password field in exactly the same way as before but we must include the extra firstPasswordFieldName option to link the fields together: { xtype: 'textfield', fieldLabel: 'Confirm Password', name: 'ConfirmPassword', labelAlign: 'top', cls: 'field-margin', flex: 1, vtype: 'password', firstPasswordFieldName: 'Password' } Uploading files to the server Uploading files is very straightforward with Ext JS 4. This recipe will demonstrate how to create a basic file upload form and send the data to your server: Getting Ready This recipe requires the use of a web server for accepting the uploaded file. A PHP file is provided to handle the file upload; however, you can integrate this Ext JS code with any server-side technology you wish. How to do it... Create a simple form panel. Ext.create('Ext.form.Panel', { title: 'Document Upload', width: 400, bodyPadding: 10, renderTo: Ext.getBody(), style: 'margin: 50px', items: [], buttons: [] }); In the panel's items collection add a file field: Ext.create('Ext.form.Panel', { ... items: [{ xtype: 'filefield', name: 'document', fieldLabel: 'Document', msgTarget: 'side', allowBlank: false, anchor: '100%' }], buttons: [] }); Add a button to the panel's buttons collection to handle the form submission: Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Upload Document', handler: function(){ var form = this.up('form').getForm(); if (form.isValid()) { form.submit({ url: 'upload.php', waitMsg: 'Uploading...' }); } } }] }); How it works... Your server-side code should handle these form submissions in the same way they would handle a regular HTML file upload form. You should not have to do anything special to make your server-side code compatible with Ext JS. The example works by defining an Ext.form.field.File ( xtype: 'filefield' ), which takes care of the styling and the button for selecting local files. The form submission handler works the same way as any other form submission; however, behind the scenes the framework tweaks how the form is submitted to the server. A form with a file upload field is not submitted using an XMLHttpRequest object—instead the framework creates and submits a temporary hidden <form> element whose target is referenced to a temporary hidden <iframe>. The request header's Content-Type is set to multipart/form. When the upload is finished and the server has responded, the temporary form and <iframe> are removed. A fake XMLHttpRequest object is then created containing a responseText property (populated from the contents of the <iframe> ) to ensure that event handlers and callbacks work as if we were submitting the form using AJAX. If your server is responding to the client with JSON, you must ensure that the response Content-Type header is text/html. There's more... It's possible to customize your Ext.form.field.File. Some useful config options are highlighted as follows: buttonOnly: Boolean Setting buttonOnly: true removes the visible text field from the file field. buttonText: String If you wish to change the text in the button from the default of "Browse…" it's possible to do so by setting the buttonText config option. buttonConfig: Object Changing the entire configuration of the button is done by defining a standard Ext.button. Button config object in the buttonConfig option. Anything defined in the buttonText config option will be ignored if you use this. Handling exception and callbacks This recipe demonstrates how to handle callbacks when loading and submitting forms. This is particularly useful for two reasons: You may wish to carry our further processing once the form has been submitted (for example, display a thank you message to the user) In the unfortunate event when the submission fails, it's good to be ready and inform the user something has gone wrong and perhaps perform extra processing The recipe shows you what to do in the following circumstances: The server responds informing you the submission was successful The server responds with an unusual status code (for example, 404 , 500 , and so on) The server responds informing you the submission was unsuccessful (for example, there was a problem processing the data) The form is unable to load data because the server has sent an empty data property The form is unable to submit data because the framework has deemed the values in the form to be invalid Getting ready The following recipe requires you to submit values to a server. An example submit.php file has been provided. However, please ensure you have a web server for serving this file. How to do it... Start by creating a simple form panel: var formPanel = Ext.create('Ext.form.Panel', { title: 'Form', width: 300, bodyPadding: 10, renderTo: Ext.getBody(), style: 'margin: 50px', items: [], buttons: [] }); Add a field to the form and set allowBlank to false: var formPanel = Ext.create('Ext.form.Panel', { ... items: [{ xtype: 'textfield', fieldLabel: 'Text field', name: 'field', allowBlank: false }], buttons: [] }); Add a button to handle the forms submission and add success and failure handlers to the submit method's only parameter: var formPanel = Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Submit', handler: function(){ formPanel.getForm().submit({ url: 'submit.php', success: function(form, action){ Ext.Msg.alert('Success', action.result.message); }, failure: function(form, action){ if (action.failureType === Ext.form.action.Action. CLIENT_INVALID) { Ext.Msg.alert('CLIENT_INVALID', 'Something has been missed. Please check and try again.'); } if (action.failureType === Ext.form.action.Action. CONNECT_FAILURE) { Ext.Msg.alert('CONNECT_FAILURE', 'Status: ' + action.response.status + ': ' + action.response.statusText); } if (action.failureType === Ext.form.action.Action. SERVER_INVALID) { Ext.Msg.alert('SERVER_INVALID', action.result. message); } } }); } }] }); When you run the code, watch for the different failureTypes or the success callback: CLIENT_INVALID is fired when there is no value in the text field. The success callback is fired when the server returns true in the success property. Switch the response in submit.php file and watch for SERVER_INVALID failureType. This is fired when the success property is set to false. Finally, edit url: 'submit.php' to url: 'unknown.php' and CONNECT_FAILURE will be fired. How it works... The Ext.form.action.Submit and Ext.form.action.Load classes both have a failure and success function. One of these two functions will be called depending on the outcome of the action. The success callback is called when the action is successful and the success property is true. The failure callback , on the other hand, can be extended to look for specific reasons why the failure occurred (for example, there was an internal server error, the form did not pass client-side validation, and so on). This is done by looking at the failureType property of the action parameter. Ext.form.action.Action has four failureType static properties: CLIENT_INVALID, SERVER_INVALID, CONNECT_FAILURE, and LOAD_FAILURE, which can be used to compare with what has been returned by the server. There's more... A number of additional options are described as follows: Handling form population failures The Ext.form.action.Action.LOAD_FAILURE static property can be used in the failure callback when loading data into your form. The LOAD_FAILURE is returned as the action parameter's failureType when the success property is false or the data property contains no fields. The following code shows how this failure type can be caught inside the failure callback function: failure: function(form, action){ ... if(action.failureType == Ext.form.action.Action.LOAD_FAILURE){ Ext.Msg.alert('LOAD_FAILURE', action.result.message); } ... } An alternative to CLIENT_INVALID The isValid method in Ext.form.Basic is an alternative method for handling client-side validation before the form is submitted. isValid will return true when client-side validation passes: handler: function(){ if (formPanel.getForm().isValid()) { formPanel.getForm().submit({ url: 'submit.php' }); } }   Further resources on this subject: Ext JS 4: Working with the Grid Component [Article] Ext JS 4: Working with Tree and Form Components [Article] Infinispan Data Grid: Infinispan and JBoss AS 7 [Article]
Read more
  • 0
  • 0
  • 7014
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 €14.99/month. Cancel anytime
article-image-publishing-project-various-formats-using-adobe-captivate-6
Packt
27 Aug 2012
16 min read
Save for later

Publishing the project in various formats using Adobe Captivate 6

Packt
27 Aug 2012
16 min read
Publishing to Flash In the history of Captivate, publishing to Flash has always been the primary publishing option. Even though HTML5 publishing is a game changer, publishing to Flash still is an important capability of Captivate. Remember that this publishing format is currently the only one that supports every single feature, animation, and object of Captivate. In the following exercise, we will publish our movie in Flash format using the default options: Return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can also use the File | Publish menu. The Publish dialog box opens, as shown in the following screenshot:   The Publish dialog box is divided into four main areas: The Publish Format area (1) – This is where we choose the format in which we want to publish our movies. Basically, we can choose between three options: SWF/HTML5, Media, and Print. The other options (E-mail, FTP, and so on) are actually suboptions of the SWF/HTML5, Media, and Print formats. The Output Format Options area (2) – The content of this area depends on the format chosen in the Publish Format (1) area. The Project Information area (3) – This area is a summary of the main project preferences and metadata. Clicking on the links of this area will bring us back to the various project preferences boxes. The Advanced Options area (4) – This area provides some additional advanced publishing options. We will now move on to the actual publication of the project in Flash Format. In the Publish Format area, make sure the chosen format is SWF/HTML5. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_flash. Click on the Browse button situated just below the Folder field and choose to publish your movie in the Chapter06/Publish folder of your exercises folder. Make sure the Publish to Folder checkbox is selected. Take a quick look at the remaining options, but leave them all at their current settings. Click on the Publish button at the bottom-right corner of the Publish dialog box. When Captivate has finished publishing the movie, an information box appears on the screen asking if you want to view the output. Click on No to discard the information box and return to Captivate. We will now use the Finder (Mac) or the Windows Explorer (Windows) to take a look at the files Captivate has generated. Use the Finder (Mac) or the Windows Explorer (Window) to browse to the Chapter06/Publish folder of your exercises. Because we selected the Publish to Folder checkbox in the Publish dialog, Captivate has automatically created the encoderDemo_800_flash subfolder in the Chapter06/ Publish folder. Open the encoderDemo_800_flash subfolder to inspect its content. encoderDemo_800_flash.swf – This is the main Flash file containing the compiled version of the .cptx project encoderDemo_800_flash.html – This file is an HTML page used to embed the Flash file standard.js – is a JavaScript file used to make the Flash player work well within the HTML page demo_en.flv – is the video file used on slide 2 of the movie captivate.css – provides the necessary style rules to ensure the proper formatting of the HTML page If we want to embed the compiled Captivate movie in an existing HTML page, only the .swf file (plus, in this case, the .flv video) is needed. The HTML editor (such as Adobe Dreamweaver) will recreate the necessary HTML, JavaScript, and CSS files. Captivate and Dreamweaver Adobe Dreamweaver CS6 is the HTML editor of the Creative Suite and the industry leading solution for authoring professional web pages. Inserting a Captivate file in a Dreamweaver page is dead easy! First, move or copy the main Flash file (.swf) as well as the needed support files (in our case the .flv video file), if any, somewhere in the root folder of the Dreamweaver site. When done, use the Files panel of Dreamweaver to drag-and-drop the main swf file on the HTML page. That's it! We will now test the movie in a web browser. This is an important test as it recreates the conditions in which our students will experience our movie once in production. Double-click on the encoderDemo_800_flash.html file to open it in a web browser. Enjoy the fnal version of the demonstration that we have created together! Now that we have experienced the workfow of publishing our project to Flash with the default options, we will add some changes into the mix and create a scalable version of our project. Scalable HTML content One of the solutions about choosing the right size for our project is to use the new Scalable HTML content option of Captivate 6. Thanks to this new option, our eLearning content will be automatically resized to fit the screen on which it is viewed. Let's experiment with this option hands-on, using the following steps: If needed, return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can also use the File | Publish menu. In the Publish Format area, make sure the chosen format is Flash(.swf) Options area. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_flashScalable. Click on the Browse button situated just below the Folder field and ensure that the publish folder still is the Chapter06/Publish folder of your exercises. Make sure the Publish to Folder checkbox is selected. In the Advanced Options section (lower-right corner of the Publish dialog), select the Scalable HTML content checkbox. Leave the remaining options at their current value and click on the Publish button at the bottom-right corner of the Publish dialog box. A message informs you that object refection is not supported in scalable content. We used object refection on slide 3 to enhance the AMELogo image. Click on Yes to discard the message and start the publishing process. When Captivate has fnished publishing the movie, an information box appears on the screen asking if you want to view the output. Click on Yes to discard the information box and open the published movie in the default web browser. During the playback, use your mouse to resize your browser window and notice how our movie is also resized in order to ft the browser window. Also notice that the refection effect we used on the AMELogo image has been discarded. Publishing to HTML5 Publishing to HTML5 is the killer new feature of Captivate 6. One of the main goals of HTML5 is to provide a plugin free paradigm. It means that the interactivity and strong visual experience brought to the Internet by the plugins should now be supported natively by the browsers and their underlying technologies (mainly HTML, CSS, and JavaScript) without the need for an extra third-party plugin. Because a plugin is no longer necessary to deliver rich interactive content, any modern browser should be capable of rendering our interactive eLearning courses. And that includes the browsers installed on mobile devices, such as Tablets and Smartphones. This is an enormous change, not only for the industry, but also for us, the Captivate users and eLearning developers. Thanks to HTML5, our students will be able to enjoy our eLearning content across all their devices. The door is open for the next revolution of our industry: the mLearning (for Mobile Learning) revolution. Blog posts To get a better idea of what's at stake with HTML5 in eLearning and mLearning, I recommend these two blog posts, available at http://blogs.adobe.com/captivate/2011/11/the-how-why-of-ipads-html5-mobile-devices-in-elearning-training-education.html by Allen Partridge on the official Adobe Captivate blog and http://rjacquez.com/the-m-in-mlearning-means-more/ by RJ Jacquez. Using the HTML5 Tracker At the time of this writing (June 2012), HTML5 is still under development. Some parts of the HTML5 specification are already final and well implemented in the browsers while other parts of the specification are still under discussion. Consequently, some features of Captivate that are supported in Flash are not yet supported in HTML5. In the following exercise, we will use the HTML5 tracker to better understand what features of our Encoder Demonstration are supported in HTML5: If needed, return to the encoderDemo_800.cptx file. Use the Window | HTML5 Tracker to open the HTML5 Tracker floating panel. The HTML5 Tracker informs us that some features that we used in this project are not (yet) supported in HTML5, as shown in the following screenshot: On slide 1 and slide 22, the Text Animations are not supported in HTML5. Same thing for the three orange arrow animations we inserted on slide 5. Close the HTML5 Tracker panel. A comprehensive list of all the objects and features that are not yet supported in the HTML5 output is available in the offcial Captivate Help at http://help.adobe.com/en_US/captivate/cp/using/WS16484b78be4e1542-74219321367c91074e-8000.html. Make sure you read that page before publishing your projects in HTML5. In the next exercise, we will publish a second version of our Encoder Demonstration using the new HTML5 publishing option. Publishing the project in HTML5 The process of publishing the project to HTML5 is very similar to the process of publishing the project to Flash. Perform the following steps to publish the project in HTML5: If needed, return to the encoderDemo_800.cptx file. Click on the Publish icon or use the File | Publish menu item to open the Publish dialog box. In the left-most column of the Publish dialog, make sure you are using the SWF/HTML5 option. Change the Project Title to encoderDemo_800_HTML5. Click on the Browse button and choose the Chapter06/publish folder of the exercises as the publish location. Make sure the Publish to Folder checkbox is selected. In the Output Format Option section, select the HTML5 checkbox. Once done, uncheck the SWF checkbox. This is the single most important setting of the entire procedure. Note that you can select both the SWF and the HTML5 options. In the Advanced Options area of the Publish dialog, deselect the Scalable HTML content checkbox. Leave the other options at their current settings and click on the Publish button. Captivate informs us that some features used in this project are not supported in HTML5. Click on Yes to discard the message and start the publication to HTML5. The process of publishing to HTML5 is much longer than the publication to Flash. One of the reasons is that Captivate needs to open the Adobe Media Encoder to convert the .flv video used in slide 2 and the Full Motion Recording of slide 13 to the .mp4 format. When the publish process is complete, a second message appears asking if you want to view the output. Click on No to discard the message and return to the standard Captivate interface. We will now use the Windows Explorer (Windows) or the Finder (Mac) to take a closer look at the generated files. Use the Windows Explorer (Windows) or the Finder (Mac) to go to the Chapter06/publish/encoderDemo_800_HTML5 folder of the exercises. You should find a bunch of files and folders in the publish/encoderDemo_800_ HTML5 folder, as follows: index.html – is the main HTML file. This is the file to load in the web browser to play the course. The /ar folder – contains all the needed sound clips in .mp3 format. The /dr folder – contains all the needed images. Notice that the mouse pointers, the slide backgrounds, as well as all the Text Captions are exported as .png images. The /vr folder – contains the needed video files in .mp4 format. The /assets folders – contains the needed CSS and JavaScript files. We will now test this version of the project in a web browser. Supported browsers and OS for HTML5 On the desktop, the HTML5 version of our eLearning project requires Internet Explorer 9 or later versions, Safari 5.1 or later versions, or Google Chrome 17 or later versions. For mobile devices, HTML5 is supported on iPads with iOS 5 or later versions. Make sure you use one of the browsers mentioned for the testing phase of this exercise. Open the .index.html. file in one of the supported browsers. When testing the HTML5 version of the project in a web browser, notice that the unsupported Text Animations of slide 1 and 22 have been replaced by a standard Text Caption with a Fade In effect. On slide 3, the effect we added on the AMELogo image is not reproduced in the HTML5 output. Surprisingly, this was not mentioned in the HTML5 tracker panel. On slide 5, the unsupported orange arrows Animations have been replaced by static images. On slide 16, the zooming animation is supported, but Text Captions that should be invisible are showing in the Zoom Destination area. Apart from the few problems mentioned in the previous list, Captivate 6 does a pretty good job in converting our demonstration to HTML5. That being said, HTML5 publishing is still an emerging technology. The room for improvement is enormous. In the coming years more parts of the HTML5 specifcation will be finalized and new techniques, tools, and framework will emerge. We will then be able to better implement HTML5 across devices, both in Captivate and throughout the entire Internet Publishing to PDF Another publishing option available in Captivate is to publish our project as an Adobe PDF document. This process is very close to the Flash publishing process we covered previously. When converting to PDF, Captivate first converts the project to Flash and then embeds the resulting .swf file in a PDF document. To read the Flash file embedded in the PDF document, the free Adobe Acrobat Reader simply contains a copy of the Flash player. Publishing the Captivate project to PDF is a great way to make the eLearning course available offline. The students can, for example, download the PDF file from a website and take the course in a train or in an airplane where no Internet connection is available. On the other hand, as the Captivate movie can be viewed offline, any Captivate feature that requires an Internet connection (such as reporting the scores to an LMS (Learning Management System)) will not work! In the following exercise, we will publish the Encoder Demonstration to PDF: Return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can use the File | Publish menu item. In the Publish Format area, make sure the chosen format is SWF/HTML5. If needed, deselect the HTML5 checkbox and make sure the .SWF checkbox is the only one selected. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_pdf. Make sure the publish Folder still is the Chapter06/Publish folder of the exercises. Make sure the Publish to Folder checkbox is still selected. At the end of the Output Format Options area, select the Export PDF checkbox. Click on the Publish button situated in the lower-right corner of the Publish dialog. When the publishing process is complete, a message tells you that Acrobat 9 or higher is required to read the generated PDF file. Click on OK to acknowledge the message. A second information box opens. Click on No to discard the second message and close the Publish dialog. Use the Finder (Mac) or the Windows Explorer (Windows) to browse to the Chapter06/publish/encoderDemo_800_pdf folder. There should be six additional files in the Chapter06/publish/encoderDemo_800_ pdf folder. Actually, publishing to PDF is an extra option of the standard publishing to Flash feature. Delete all but the PDF file from the Chapter06/publish/encoderDemo_800_ pdf folder. Double-click on the encoderDemo_800_pdf.pdf file to open it in Adobe Acrobat. Notice that the file plays normally in Adobe Acrobat. This proves that all the necessary files and assets have been correctly embedded into the PDF file. In the next section, we will explore the third publishing option of Captivate: publishing as a standalone application. Publishing as a standalone application When publishing as a standalone application, Captivate generates an .exe file for playback on Windows or an .app file for playback on Macintosh. The .exe (Windows) or .app (Mac) file contains the compiled .swf file plus the Flash player. The advantages and disadvantages of a standalone application are similar to those of a PDF file. That is, the file can be viewed offline in a train, in an airplane, or elsewhere, but the features requiring an Internet connection will not work. In the following exercise, we will publish the Captivate file as a standalone application using the following steps: If needed, return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can use the File | Publish menu item. Click on the Media icon situated on the left-most column of the Publish dialog box. The middle area is updated. Open the Select Type drop-down list. If you are on a Windows PC, choose Windows Executable (*.exe) and if you are using a Mac, choose MAC Executable (*.app). If needed, change the Project Title to encoderDemo_800. In the Folder field, make sure that the Chapter06/Publish folder still is the chosen value. Take some time to inspect the other options of the Publish dialog. One of them allows us to choose a custom icon for the generated .exe (Win) or .app (Mac) file. Leave the other options at their current value and click on the Publish button. When the publish process is complete, an information box will ask you if you want to see the generated output. Click on No to clear the information message and to close the Publish dialog. Now that the standalone application has been generated, we will use the Finder (Mac) or the Windows Explorer (Win) to take a look at the Chapter06/Publish folder. Use the Finder (Mac) or the Windows Explorer (Windows) to browse to the Chapter06/Publish folder of the exercises. Double-click on the encoderDemo_800.exe (Win) or on the encoderDemo_800.app (Mac) to open the generated application. Our Captivate movie opens as a standalone application in its own window. Notice that no browser is necessary to play the movie. This publish format is particularly useful when we want to burn the movie on a CD-ROM. When generating a Windows executable (.exe), Captivate can even generate an autorun.ini file so that the movie automatically plays when the CD-ROM is inserted in the computer.
Read more
  • 0
  • 0
  • 3261

article-image-article-enabling-plugin-internationalization
Packt
10 Aug 2012
5 min read
Save for later

Enabling Plugin Internationalization

Packt
10 Aug 2012
5 min read
In this article by Yannick Lefebvre, the author of WordPress Plugin Development Cookbook, we will learn about plugin localization through the following topics: Changing the WordPress language configuration Adapting default user settings for translation Making admin page code ready for translation Modifying shortcode output for translation Translating text strings using Poedit Loading a language file in the plugin initialization   Introduction WordPress is a worldwide phenomenon, with users embracing the platform all around the globe. To create a more specific experience for users in different locales, WordPress offers the ability to translate all of its user and visitor-facing content, resulting in numerous localizations becoming available for download online. Like most other functionalities in the platform, internationalization is also available to plugin developers through a set of easy-to-use functions. The main difference being that plugin translations are typically included with the extension, instead of being downloaded separately as is the case with WordPress. To prepare their plugin to be localized, developers must use special internationalization functions when dealing with text elements. Once this structure is in place, any user can create localizations by themselves for languages that they know and submit them back to the plugin author for inclusion in a future update to the extension. This article explains how to prepare a plugin to be translated and shows how to use the Poedit tool to create a new language file for a simple plugin. Changing the WordPress language configuration The first step to translating a plugin is to configure WordPress to a different language setting other than English. This will automatically trigger mechanisms in the platform to look for alternate language content for any internationalized string. In this recipe we will set the site to French. Getting ready You should have access to a WordPress development environment. How to do it... Navigate to the root of your WordPress installation. Open the file called wp-config.php in a code editor. Change the line that declares the site language from define('WPLANG', ''); to define('WPLANG', 'fr_FR');. Save and close the configuration file. How it works... Whenever WordPress renders a page for visitors or site administrators, it executes the contents of the wp-config.php file, which declares a number of site-wide constants. One of these constants is the site language. By default, this constant has no value, indicating that WordPress should display all content in U.S. English. If defined, the system tries to find a translation file under the wp-content/languages or wp-includes/languages directories of the site to locate translation strings for the target language. In this case, it will try to find a file called fr_FR.mo. While it will not actually find this file in a default installation, setting this configuration option will facilitate the creation and testing of a plugin translation file in later recipes. To learn more about translation files and find out where to download them from, visit the WordPress Codex available at http://codex.wordpress.org/WordPress_in_ Your_Language. Adapting default user settings for translation As mentioned in the introduction, plugin code needs to be specifically written to allow text items to be translated. This work starts in the plugin's activation routine, where default plugin option values are set, to find alternate values when a language other than English is specified in the site's configuration file. This recipe shows how to assign a translated string to a plugin's default options array on initialization. Getting ready You should have already followed the Changing the WordPress language configuration recipe to have a specified translation language for the site. How to do it... Navigate to the WordPress plugin directory of your development installation. Create a new directory called hello-world. Navigate to the directory and create a text file called hello-world.php. Open the new file in a code editor and add an appropriate header at the top of the plugin file, naming the plugin Hello World. Add the following line of code before the plugin's closing ?> PHP command to register a function to be called when the plugin is activated: code 1 Insert the following block of code to provide an implementation for the hw_set_default_options_array function: code 2 Save and close the plugin file. Navigate to the Plugins management page and activate the Hello World plugin. Using phpMyAdmin or the NetBeans IDE, find the options table entry where the option_name field has a value of hw_options to see the newly-created option. How it works... The __ function (that's two underscores) is a WordPress utility function that tries to find a translation for the text that it receives in its first argument, within the text domain specified in the second argument. A text domain is essentially a subsection of the global translation table that is managed by WordPress. In this example, the text to be translated is the string Hello World, for which the system tries to find a translation in the hw_hello_world domain. Since this domain is not available at this time, the function returns the original string that it received as its first parameter. The plugin code assigns the value it receives to the default configuration array. It should be noted that the __ function is actually an alias for the translate function. While both functions have the same functionality, using __ makes the code shorter when it contains a lot of text elements to be translated. While it may be tempting for developers to use a variable or constant in the first parameter of the __ function if they need to display the same text multiple times, this should not be done as it will cause problems with the translation lookup mechanism. See also Changing the WordPress language configuration recipe
Read more
  • 0
  • 0
  • 1083

article-image-blackboard-essentials-teachers-assignments-students
Packt
09 Aug 2012
4 min read
Save for later

Blackboard Essentials for Teachers - Assignments for Students

Packt
09 Aug 2012
4 min read
  About assignments An assignment is essentially an activity where the instructor tells the student, "Go do this, and then submit proof that you've done it". Optional features enable the instructor to supply the student with a file, to upload a file, and to submit both feedback and comments. Blackboard will create a link in the assignment, for the student to upload material to the instructor. Every assignment must have instructions and a student submission. The instructions are entered by the instructor when (s)he creates the assignment. The student submission can be material that the student types directly into the assignment-feedback form, or something that the student uploads (such as a word document or picture). The instructor can give a student feedback on the student's submission. In return, the student can give the instructor feedback on the assignment. Instructors can also allow multiple submissions, so the student has multiple tries to get it right. No matter how many trials the student takes, or how many files the student uploads, the instructor will give only one grade to the student. Adding an assignment To add an assignment to a Content Page, follow these steps: Select the Content Page to which you want to add an assignment. Select Create Assessment | Assignment. The Create Assignment page is displayed. Both the Name and the Instructions fields that you enter will be displayed on the page with the assignment, as shown in the following screenshot: In the preceding example, the instructor tells the student to download a file. You might want to remind the students to create a folder on their computers to hold all the material that they download from the course. Under Attached Files, you can add any files that you want the student to download and use in the assignment (this is optional). These can be files that you want the student to modify and then upload (such as a form to fill out), or files that contain instructions for an activity (such as instructions for performing an experiment), or source files that the student will use to create something (such as some raw video footage).If the student will complete the assignment while (s)he is online, enter the instructions into the Instructions area as shown earlier. If the student will complete the assignment while (s)he is offline, consider supplying the student with printer-friendly instructions that (s)he can download.Blackboard will allow the student to upload files up to 100 MB in size. The Grading and Availability sections contain standard options. If you enter Due Date for the assignment, it will not appear on the Content Page (see the preceding screenshot). However, it will appear in several other places. When the student enters the assignment, the due date will appear on the assignment page: The due date will also appear in the student's To Do block. Usually, the To Do block is added to the course's home page, and also to the student's home page. In the following screenshot, you can see the assignment in the To Do block of the course's home page. Because it was recently added, you can also see the assignment in the What's New block: And finally, Due Date will appear on the student's My Grades page: The due date has no effect on the availability of the assignment, or the student's grade. It is for informational purposes only. If you want Blackboard to limit the time period for which students can submit an assignment, use the Availability setting to make the assignment available only during a specified time. Under Recipients, determine if this assignment will be graded individually for each student, or for a group. Click on Submit to save your work. The assignment is added to the course. You don't need to do anything to make the assignment appear within the Assignments page and the To Do block. And, you can create a link to the assignment on the pages of your course.
Read more
  • 0
  • 0
  • 1574

article-image-mastering-newer-prezi-features
Packt
25 Jul 2012
10 min read
Save for later

Mastering the Newer Prezi Features

Packt
25 Jul 2012
10 min read
Templates There will always be time restraints put on us when building any business presentation. Mostly these will be pretty unrealistic time restraints as well. If you do find yourself against the clock when building a Prezi, then why not give yourself a slight advantage and use one of Prezi's templates to get your design started. There are lots of templates you can chose from and here's how to make the most out of them when the clock is ticking. The templates When you create any new Prezi online or in the desktop editor, you'll be presented with a choice of template as shown in the following screenshot: Before you decide which one to choose, you can explore them by simply selecting one and clicking the Preview button. You can see in the following screenshot that we've selected the Our Project template. Rolling your mouse over a template's thumbnail will show you some more details as well to help you choose. At the top of the screen, you'll see the options to either Start Editing or go Back to the templates screen. Before you make your choice, have a look around the template preview and check out all of the various objects available to you. Zoom in and out of certain areas that look interesting and use the arrows in the bottom right to go through the template's path and see how it flows. In the following screenshot, you can see that we've zoomed in to take a closer look at the assets included in this template: As you can see in the preceding screenshot, the Our Project template has some lovely assets included. The assets you'll be able to use in the template are images and sketches such as the Doodles that you can see in the top right of the screenshot. All of these assets can be moved around and used anywhere on your canvas. If you preview a template and decide it's the right one for you to use, then just click the Start Editing button to go into edit mode and begin building your Prezi. Getting the most from templates Once you go into edit mode, don't think that you're stuck with how everything is laid out. You can (and should) move things around to fit with the message you're trying to deliver to your audience. Paths The very first thing we'd suggest is clicking on the Paths button and taking a look at how the Prezi flows. The whole reason you're using a template is because you're pushed for time, but you should know how many frames you need and how many different areas you'll want to focus on in your presentation before you get started. If you do, then you can adjust the paths, add new path points, or delete some that are there already. Assets All of the templates, especially Our Project, will come with various assets included. Use them wherever you can. It'll save you lots of time searching for your own imagery if you can just move the existing assets around. As shown in the preceding screenshot, you are totally free to resize any asset in a template. Make the most of them and save yourself a whole heap of time. Branding The only down side of using templates is that they of course won't have any of your company colors, logo, or branding on them. This is easily fixed by using the Colors & Fonts|Theme Wizard found in the bubble menu. On the very first screen of the wizard, click the Replace Logo button to add your company logo. The logo must be a JPEG file no bigger than 250 pixels wide and 100 pixels high. Clicking the button will allow you to search for your logo and it will then be placed in the bottom left-hand corner of your Prezi at all times. On this screen, you can also change the background color of your entire canvas. On the next screen of the wizard, we recommend you switch to Manual mode by clicking the option in the bottom-left corner. In this screen, you can select the fonts to use in your Prezi. At the present time, Prezi still has only a limited number of fonts but we're confident you can find something close to the one your company uses. The reason we suggest switching to manual mode is because you'll be able to use your corporate colors for the fonts you select, and also on the frames and shapes within the Prezi. You'll need to know the RGB color values specified in your corporate branding. By using this final step, you'll get all the benefits of having an already designed Prezi without getting told off by your marketing team for going against their strict branding guidelines. Shapes A very simple element of the Prezi bubble menu which gets overlooked a lot is the InsertShapes| option. In this part of the article, we'll look at some things you may not have known about how shapes work within Prezi. Shortcut for shapes To quickly enter the Shapes menu when working in the Prezi canvas, just press the S key on your keyboard. Get creative In the first part of this chapter, we looked at the assets from a template called OurProject. Some of those assets were the line drawings shown below the male and female characters. When you see these "Doodles" as they're titled, you might think they've been drawn in some kind of graphics package and inserted into the Prezi canvas as you would anything else. On closer inspection in edit mode, you can see that each of the characters is actually made up of different lines from the Shapes menu. This is a great use of the line tool and we'd encourage you to try and create your own simple drawings wherever you can. These can then be reused over time, and will in turn save you lots of time searching for imagery via the Google image insert. Let's say that we want to add some more detail to the male character. Maybe we'll give him a more exciting hair style to replace the boring one that he has at the moment. First select the current hairline and delete it from the character's head. Now select the line tool from the Shapes menu and let's give this guy a flat top straight from the 80's. One of our lines is too long on the right. To adjust it, simply double-click to enter edit mode and drag the points to the right position as shown in the following screenshot: So there we have a great example of how to quickly draw your own image on the Prezi canvas by just using lines. It's an excellent feature of Prezi and as you can see, it's given our character a stunning new look. It's a shame his girlfriend doesn't think so too! Editing shapes In step three of giving our character a new haircut, you saw the edit menu which is accessed by a simple double-click. You can use the edit function on all items in the shapes menu apart from the Pencil and Highlighter tools. Any shape can be double-clicked to change its size and color as shown in the following screenshot. You can see that all of the shapes on the left have been copied and then edited to change their color and size. The edited versions on the right have all been double- clicked and one of the five extra available colors have been selected. The points of each shape have also been clicked on and dragged to change the dimensions of the shape. Holding the Shift key will not keep your shapes to scale. If you want to scale the shapes up or down, we recommend you use the transformation zebra by clicking the plus (+) or minus (-) signs. Editing lines When editing lines or arrows, you can change them from being straight to curved by dragging the center point in any direction. This is extremely useful when creating the line drawings we saw earlier. It's also useful to get arrows pointing at various objects on your canvas. Highlighter The highlighter tool from the shapes menu is extremely useful for pointing out key pieces of information like in the interesting fact shown in the following screenshot: Just drag it across the text you'd like to highlight. Once you've done that the highlighter marks become objects in their own right, so you can use the transformation zebra to change their size or position as shown in the following screenshot: Pencil The pencil tool can be used to draw freehand sketches like the one shown in the following screenshot. If you hadn't guessed it yet, our drawing is supposed to represent a brain which links to the interesting fact about ants. The pencil tool is great if you're good at sketching things out with your mouse. But if like us, your art skills need a little more work, you might want to stick to using the lines and shapes to create imagery! To change the color of your highlighter or pencil drawings, you will need to go into the Theme Wizard and edit the RGB values. This will help you keep things within your corporate branding guidelines again. Drawings and diagrams Another useful new feature and a big time saver within the Prezi insert menu are drawings and diagrams. You can locate the drawings and diagrams templates by clicking the button in-between YouTube and File from the Insert menu. There are twelve templates to choose from and each has been given a name that best describes their purpose. Rolling over each thumbnail will show you a little more detail to help you choose the right one. Once you have chosen, double-click the thumbnail and then decide where to place your drawing on the canvas. You can see in the following screenshot that the drawing or diagram is grouped together and will not become active until you click the green tick. Once you make the drawing active, you can access all of its frames, text, and any other elements that are included. In the following screenshot, you can see that we've zoomed into a section of the tree diagram. You can see in the preceding screenshot that the diagram uses lines, circular frames, and text which can all be edited in any way you like. This is the case for all of the diagrams and drawings available from the menu. Using these diagrams and drawings gives you a great chance to explain concepts and ideas to your colleagues with ease. You can see from the preceding screenshot that there's a good range of useful drawings and diagrams that you're used to seeing in business presentations. You can easily create organograms, timelines for projects, or business processes and cycles, simply by using the templates available and inserting your own content and imagery. By using the Theme wizard explained earlier in this chapter, you can make sure your drawings and diagrams use your corporate colors.
Read more
  • 0
  • 0
  • 2082
article-image-null-12
Packt
23 Jul 2012
13 min read
Save for later

Ruby with MongoDB for Web Development

Packt
23 Jul 2012
13 min read
Creating documents Let's first see how we can create documents in MongoDB. As we have briefly seen, MongoDB deals with collections and documents instead of tables and rows. Time for action – creating our first document Suppose we want to create the book object having the following schema: book = { name: "Oliver Twist", author: "Charles Dickens", publisher: "Dover Publications", published_on: "December 30, 2002", category: ['Classics', 'Drama'] }   On the Mongo CLI, we can add this book object to our collection using the following command: > db.books.insert(book)   Suppose we also add the shelf collection (for example, the floor, the row, the column the shelf is in, the book indexes it maintains, and so on that are part of the shelf object), which has the following structure: shelf : { name : 'Fiction', location : { row : 10, column : 3 }, floor : 1 lex : { start : 'O', end : 'P' }, }   Remember, it's quite possible that a few years down the line, some shelf instances may become obsolete and we might want to maintain their record. Maybe we could have another shelf instance containing only books that are to be recycled or donated. What can we do? We can approach this as follows: The SQL way: Add additional columns to the table and ensure that there is a default value set in them. This adds a lot of redundancy to the data. This also reduces the performance a little and considerably increases the storage. Sad but true! The NoSQL way: Add the additional fields whenever you want. The following are the MongoDB schemaless object model instances: > db.book.shelf.find() { "_id" : ObjectId("4e81e0c3eeef2ac76347a01c"), "name" : "Fiction", "location" : { "row" : 10, "column" : 3 }, "floor" : 1 } { "_id" : ObjectId("4e81e0fdeeef2ac76347a01d"), "name" : "Romance", "location" : { "row" : 8, "column" : 5 }, "state" : "window broken", "comments" : "keep away from children" } What just happened? You will notice that the second object has more fields, namely comments and state. When fetching objects, it's fine if you get extra data. That is the beauty of NoSQL. When the first document is fetched (the one with the name Fiction), it will not contain the state and comments fields but the second document (the one with the name Romance) will have them. Are you worried what will happen if we try to access non-existing data from an object, for example, accessing comments from the first object fetched? This can be logically resolved—we can check the existence of a key, or default to a value in case it's not there, or ignore its absence. This is typically done anyway in code when we access objects. Notice that when the schema changed we did not have to add fields in every object with default values like we do when using a SQL database. So there is no redundant information in our database. This ensures that the storage is minimal and in turn the object information fetched will have concise data. So there was no redundancy and no compromise on storage or performance. But wait! There's more. NoSQL scores over SQL databases The way many-to-many relations are managed tells us how we can do more with MongoDB that just cannot be simply done in a relational database. The following is an example: Each book can have reviews and votes given by customers. We should be able to see these reviews and votes and also maintain a list of top voted books. If we had to do this in a relational database, this would be somewhat like the relationship diagram shown as follows: (get scared now!) The vote_count and review_count fields are inside the books table that would need to be updated every time a user votes up/down a book or writes a review. So, to fetch a book along with its votes and reviews, we would need to fire three queries to fetch the information: SELECT * from book where id = 3; SELECT * from reviews where book_id = 3; SELECT * from votes where book_id = 3; We could also use a join for this: SELECT * FROM books JOIN reviews ON reviews.book_id = books.id JOIN votes ON votes.book_id = books.id; In MongoDB, we can do this directly using embedded documents or relational documents. Using MongoDB embedded documents Embedded documents, as the name suggests, are documents that are embedded in other documents. This is one of the features of MongoDB and this cannot be done in relational databases. Ever heard of a table embedded inside another table? Instead of four tables and a complex many-to-many relationship, we can say that reviews and votes are part of a book. So, when we fetch a book, the reviews and the votes automatically come along with the book. Embedded documents are analogous to chapters inside a book. Chapters cannot be read unless you open the book. Similarly embedded documents cannot be accessed unless you access the document. For the UML savvy, embedded documents are similar to the contains or composition relationship. Time for action – embedding reviews and votes In MongoDB, the embedded object physically resides inside the parent. So if we had to maintain reviews and votes we could model the object as follows: book : { name: "Oliver Twist", reviews : [ { user: "Gautam", comment: "Very interesting read" }, { user: "Harry", comment: "Who is Oliver Twist?" } ] votes: [ "Gautam", "Tom", "Dick"] } What just happened? We now have reviews and votes inside the book. They cannot exist on their own. Did you notice that they look similar to JSON hashes and arrays? Indeed, they are an array of hashes. Embedded documents are just like hashes inside another object. There is a subtle difference between hashes and embedded objects as we shall see later on in the book. Have a go hero – adding more embedded objects to the book Try to add more embedded objects such as orders inside the book document. It works! order = { name: "Toby Jones" type: "lease", units: 1, cost: 40 } Fetching embedded objects We can fetch a book along with the reviews and the votes with it. This can be done by executing the following command: > var book = db.books.findOne({name : 'Oliver Twist'}) > book.reviews.length 2 > book.votes.length 3 > book.reviews [ { user: "Gautam", comment: "Very interesting read" }, { user: "Harry", comment: "Who is Oliver Twist?" } ] > book.votes [ "Gautam", "Tom", "Dick"] This does indeed look simple, doesn't it? By fetching a single object, we are able to get the review and vote count along with the data. Use embedded documents only if you really have to! Embedded documents increase the size of the object. So, if we have a large number of embedded documents, it could adversely impact performance. Even to get the name of the book, the reviews and the votes are fetched. Using MongoDB document relationships Just like we have embedded documents, we can also set up relationships between different documents. Time for action – creating document relations The following is another way to create the same relationship between books, users, reviews, and votes. This is more like the SQL way. book: { _id: ObjectId("4e81b95ffed0eb0c23000002"), name: "Oliver Twist", author: "Charles Dickens", publisher: "Dover Publications", published_on: "December 30, 2002", category: ['Classics', 'Drama'] } Every document that is created in MongoDB has an object ID associated with it. In the next chapter, we shall soon learn about object IDs in MongoDB. By using these object IDs we can easily identify different documents. They can be considered as primary keys. So, we can also create the reviews collection and the votes collection as follows: users: [ { _id: ObjectId("8d83b612fed0eb0bee000702"), name: "Gautam" }, { _id : ObjectId("ab93b612fed0eb0bee000883"), name: "Harry" } ] reviews: [ { _id: ObjectId("5e85b612fed0eb0bee000001"), user_id: ObjectId("8d83b612fed0eb0bee000702"), book_id: ObjectId("4e81b95ffed0eb0c23000002"), comment: "Very interesting read" }, { _id: ObjectId("4585b612fed0eb0bee000003"), user_id : ObjectId("ab93b612fed0eb0bee000883"), book_id: ObjectId("4e81b95ffed0eb0c23000002"), comment: "Who is Oliver Twist?" } ] votes: [ { _id: ObjectId("6e95b612fed0eb0bee000123"), user_id : ObjectId("8d83b612fed0eb0bee000702"), book_id: ObjectId("4e81b95ffed0eb0c23000002"), }, { _id: ObjectId("4585b612fed0eb0bee000003"), user_id : ObjectId("ab93b612fed0eb0bee000883"), } ] What just happened? Hmm!! Not very interesting, is it? It doesn't even seem right. That's because it isn't the right choice in this context. It's very important to know how to choose between nesting documents and relating them. In your object model, if you will never search by the nested document (that is, look up for the parent from the child), embed it. Just in case you are not sure about whether you would need to search by an embedded document, don't worry too much – it does not mean that you cannot search among embedded objects. You can use Map/Reduce to gather the information. Comparing MongoDB versus SQL syntax This is a good time to sit back and evaluate the similarities and dissimilarities between the MongoDB syntax and the SQL syntax. Let's map them together: SQL commands NoSQL (MongoDB) equivalent SELECT * FROM books db.books.find() SELECT * FROM books WHERE id = 3; db.books.find( { id : 3 } ) SELECT * FROM books WHERE name LIKE 'Oliver%' db.books.find( { name : /^Oliver/ } ) SELECT * FROM books WHERE name like '%Oliver%' db.books.find( { name : /Oliver/ } ) SELECT * FROM books WHERE publisher = 'Dover Publications' AND published_date = "2011-8-01" db.books.find( { publisher : "Dover Publications", published_date : ISODate("2011-8-01") } ) SELECT * FROM books WHERE published_date > "2011-8-01" db.books.find ( { published_date : { $gt : ISODate("2011-8-01") } } ) SELECT name FROM books ORDER BY published_date db.books.find( {}, { name : 1 } ).sort( { published_date : 1 } ) SELECT name FROM books ORDER BY published_date DESC db.books.find( {}, { name : 1 } ).sort( { published_date : -1 } ) SELECT votes.name from books JOIN votes where votes.book_id = books.id db.books.find( { votes : { $exists : 1 } }, { votes.name : 1 } ) Some more notable comparisons between MongoDB and relational databases are: MongoDB does not support joins. Instead it fires multiple queries or uses Map/Reduce. We shall soon see why the NoSQL faction does not favor joins. SQL has stored procedures. MongoDB supports JavaScript functions. MongoDB has indexes similar to SQL. MongoDB also supports Map/Reduce functionality. MongoDB supports atomic updates like SQL databases. Embedded or related objects are used sometimes instead of a SQL join. MongoDB collections are analogous to SQL tables. MongoDB documents are analogous to SQL rows. Using Map/Reduce instead of join We have seen this mentioned a few times earlier—it's worth jumping into it, at least briefly. Map/Reduce is a concept that was introduced by Google in 2004. It's a way of distributed task processing. We "map" tasks to works and then "reduce" the results. Understanding functional programming Functional programming is a programming paradigm that has its roots from lambda calculus. If that sounds intimidating, remember that JavaScript could be considered a functional language. The following is a snippet of functional programming: $(document).ready( function () { $('#element').click( function () { # do something here }); $('#element2').change( function () { # do something here }) }); We can have functions inside functions. Higher-level languages (such as Java and Ruby) support anonymous functions and closures but are still procedural functions. Functional programs rely on results of a function being chained to other functions. Building the map function The map function processes a chunk of data. Data that is fed to this function could be accessed across a distributed filesystem, multiple databases, the Internet, or even any mathematical computation series! function map(void) -> void The map function "emits" information that is collected by the "mystical super gigantic computer program" and feeds that to the reducer functions as input. MongoDB as a database supports this paradigm making it "the all powerful" (of course I am joking, but it does indeed make MongoDB very powerful). Time for action – writing the map function for calculating vote statistics Let's assume we have a document structure as follows: { name: "Oliver Twist", votes: ['Gautam', 'Harry'] published_on: "December 30, 2002" } The map function for such a structure could be as follows: function() { emit( this.name, {votes : this.votes} ); } What just happened? The emit function emits the data. Notice that the data is emitted as a (key, value) structure. Key: This is the parameter over which we want to gather information. Typically it would be some primary key, or some key that helps identify the information. For the SQL savvy, typically the key is the field we use in the GROUP BY clause. Value: This is a JSON object. This can have multiple values and this is the data that is processed by the reduce function. We can call emit more than once in the map function. This would mean we are processing data multiple times for the same object. Building the reduce function The reduce functions are the consumer functions that process the information emitted from the map functions and emit the results to be aggregated. For each emitted data from the map function, a reduce function emits the result. MongoDB collects and collates the results. This makes the system of collection and processing as a massive parallel processing system giving the all mighty power to MongoDB. The reduce functions have the following signature: function reduce(key, values_array) -> value Time for action – writing the reduce function to process emitted information This could be the reduce function for the previous example: function(key, values) { var result = {votes: 0} values.forEach(function(value) { result.votes += value.votes; }); return result; } What just happened? reduce takes an array of values – so it is important to process an array every time. There are various options to Map/Reduce that help us process data. Let's analyze this function in more detail: function(key, values) { var result = {votes: 0} values.forEach(function(value) { result.votes += value.votes; }); return result; } The variable result has a structure similar to what was emitted from the map function. This is important, as we want the results from every document in the same format. If we need to process more results, we can use the finalize function (more on that later). The result function has the following structure: function(key, values) { var result = {votes: 0} values.forEach(function(value) { result.votes += value.votes; }); return result; } The values are always passed as arrays. It's important that we iterate the array, as there could be multiple values emitted from different map functions with the same key. So, we processed the array to ensure that we don't overwrite the results and collate them.
Read more
  • 0
  • 0
  • 4808

article-image-building-site-directory-sharepoint-search
Packt
17 Jul 2012
8 min read
Save for later

Building a Site Directory with SharePoint Search

Packt
17 Jul 2012
8 min read
  (For more resources on Microsoft Sharepoint, see here.) Site Directory options There are two main approaches to providing a Site Directory feature: A central list that has to be maintained Using a search-based tool that can provide the information dynamically   List-based Site Directory With a list-based Site Directory, a list is provisioned in a central site collection, such as the root of a portal or intranet. Like all lists, site columns can be defined to help describe the site's metadata. Since it is stored in a central list, the information can easily be queried, which can make it easy to show a listing of all sites and perform filtering, sorting, and grouping, like all SharePoint lists. It is important to consider the overall site topology within the farm. If everything of relevance is stored within a single site collection, a list-based Site Directory, accessible throughout that site collection, may be easy to implement. But as soon as you have a large number of site collections or web applications, you will no longer be able to easily use that Site Directory without creating custom solutions that can access the central content and display it on those other sites. In addition, you will need to ensure that all users have access to read from that central site and list. Another downside to this approach is that the list-based Site Directory has to be maintained to be effective, and in many cases it is very difficult to keep up with this. It is possible to add new sites to the directory programmatically, using an event receiver, or as part of a process that automates the site creation. However, through the site's life cycle, changes will inevitably have to be made, and in many cases sites will be retired, archived, or deleted. While this approach tends to work well in small, centrally controlled environments, it does not work well at all in most of the large, distributed environments where the number of sites is expected to be larger and the rate of change is typically more frequent. Search-based site discovery An alternative to the list-based Site Directory is a completely dynamic site discovery based on the search system. In this case the content is completely dynamic and requires no specific maintenance. As sites are created, updated, or removed, the changes will be updated in the index as the scheduled crawls complete. For environments with a large number of sites, with a high frequency of new sites being created, this is the preferred approach. The content can also be accessed throughout the environment without having to worry about site collection boundaries, and can also be leveraged using out of the box features. The downside to this approach is that there will be a limit to the metadata you can associate with the site. Standard metadata that will be related to the site include the site's name, description, URL, and to a lesser extent, the managed path used to configure the site collection. From these items you can infer keyword relevance, but there is no support for extended properties that can help correlate the site with categories, divisions, or other specific attributes. How to leverage search Most users are familiar with how to use the Search features to find content, but are not familiar with some of the capabilities that can help them pinpoint specific content or specific types of content. This section will provide an overview on how to leverage search to provide features that help support users finding results that are only related to sites. Content classes SharePoint Search includes an object classification system that can be used to identify specific types of items as shown in the next table. It is stored in the index as a property of the item, making it available for all queries. Content Class Description STS_Site Site Collection objects STS_Web Subsite/Web objects STS_list_[templatename] List objects where [templatename] is the name of the template such as Announcements or DocumentLibrary. STS_listitem_[templatename] List Item objects where [templatename] is the name of the template such as Announcements or DocumentLibrary. SPSPeople User Profile objects (requires a User Profile Service Application) The contentclass property can be included as part of an ad hoc search performed by a user, included in the search query within a customization, or as we will see in the next section, used to provide a filter to a Search Scope. Search Scopes Search Scopes provide a way to filter down the entire search index. As the index grows and is filled with potentially similar information, it can be helpful to define Search Scopes to put specific set of rules in place to reduce the initial index that the search query is executed against. This allows you to execute a search within a specific context. The rules can be set based on the specific location, specific property values, or the crawl source of the content. The Search Scopes can be either defined centrally within the Search service application by an administrator or within a given Site Collection by a Site Collection administrator. If the scope is going to be used in multiple Site Collections, it should be defined in the Search service application. Once defined, it is available in the Search Scopes dropdown box for any ad hoc queries, within the custom code, or within the Search Web Parts. Defining the Site Directory Search Scope To support dynamic discovery of the sites, we will configure a Search Scope that will look at just site collections and subsites. As we saw above, this will enable us to separate out the site objects from the rest of the content in the search index. This Search Scope will serve as the foundation for all of the solutions in this article. To create a custom Search Scope: Navigate to the Search Service Application. Click on the Search Scopes link on the QuickLaunch menu under the Queries and Results heading. Set the Title field to Site Directory. Provide a Description. Click on the OK button as shown in the following screenshot: From the View Scopes page, click on the Add Rules link next to the new Search Scope. For the Scope Rule Type select the Property Query option. For the Property Query select the contentclass option. Set the property value to STS_Site. For the Behaviorsection, select the Include option. From the Scope Properties page, select the New Rule link. For the Scope Rule Type section, select the Property Query option./li> For the Property Query select the contentclass option. Set the property value to STS_Web. For the Behavior section, select the Include option.   The end result will be a Search Scope that will include all Site Collection and subsite entries. There will be no user generated content included in the search results of this scope. After finishing the configuration for the rules there will be a short delay before the scope is available for use. A scheduled job will need to compile the search scope changes. Once compiled, the View Scopes page will list out the currently configured search scopes, their status, and how many items in the index match the rules within the search scopes. Enabling the Search Scope on a Site Collection Once a Search Scope has been defined you can then associate it with the Site Collection(s) you would like to use it from. Associating the Search Scope to the Site Collection will allow the scope to be selected from within the Scopes dropdown on applicable search forms. This can be done by a Site Collection administrator one Site Collection at a time or it can be set via a PowerShell script on all Site Collections. To associate the search scope manually: Navigate to the Site Settings page. Under the Site Collection Administration section, click on the Search Scopes link. In the menu, select the Display Groups action. Select the Search Dropdown item. You can now select the Sites Scope for display and adjust its position within the list. Click on the OK button when complete.   Testing the Site Directory Search Scope Once the scope has been associated with the Site Collection's search settings, you will be able to select the Site Directory scope and perform a search, as shown in the following screenshot: Any matching Site Collections or subsites will be displayed. As we can see from the results shown in the next screenshot, the ERP Upgrade project site collection comes back as well as the Project Blog subsite.
Read more
  • 0
  • 0
  • 5118

article-image-installing-and-configuring-drupal
Packt
11 Jul 2012
7 min read
Save for later

Installing and Configuring Drupal

Packt
11 Jul 2012
7 min read
(For more resources on Drupal 7, see here.) Installing Drupal There are a number of different ways to install Drupal on a web server, but in this recipe we will focus on the standard, most common installation, which is to say, Drupal running on an Apache server, which runs PHP with a MySQL database. In order to do this we will download the latest Drupal release, and walk you through all of the steps required to get it up and running. Getting ready Before beginning, you need to ensure that you meet the following minimal requirements: Web hosting with FTP access (or file access through a control panel). A server running PHP 5.2.5+ (5.3+ recommended). A blank MySQL database and the login credentials to access it. Ensure that register globals is set to off in the PHP.ini file. You may need to contact your hosting provider to do this. How to do it... The first step is to download the latest Drupal 7 release from the Drupal download page, which is located at http://drupal.org/project/drupal : This page displays the most recent and recommended releases for both Drupal 6 and 7. It also displays the most recent development versions, but be sure to download the recommended release (development versions are for developers who want to stay on the cutting edge). When the file is downloaded, extract it and upload the files to your chosen web server document root directory on the server. This may take some time. Configure your web server document root and server name (usually through a vhost directive). When the upload is complete, open your browser and in the address bar, type in the server name configured in the previous step to begin the installation wizard. Select Standard option and then select Save and continue: The next screen that you will see is the language selection screen; there should only be one language available at this point. Ensure that English is selected before proceeding: Following a requirements check, you will arrive at the database settings page. Enter your database name, username, and password in the required fields. Unless your database details have been supplied with a specific host name and port, you should leave the advanced options as they are and continue. You will now see the Site configuration page. Under Site information enter the name you would like to appear as the site's name. For Site e-mail address enter an e-mail address. Under the SITE MAINTENANCE ACCOUNT box, enter a username for the admin user (also known as user 1), followed by an e-mail address and password: (Move the mouse over the image to enlarge.) In the Server settings box, select your country from the drop-down, followed by your local time zone. Finally, in the Update notification box, ensure that both options are selected. Click on Save and continue to complete the installation. You will be presented with the congratulations page with a link to your new site. How it works... On the server requirements page, Drupal will carry out a number of tests. It is a requirement that PHP "register globals" is set to off or disabled. Register globals is a feature of PHP which allows global variables to be set from the contents of the Environment, GET, POST, Cookie, and Server variables. It can be a major security risk, as it enables potential hackers to overwrite important variables and gain unauthorized access. The Configure site page is where you specify the site name and e-mail addresses for the site and the admin user. The admin e-mail address will be used to contact the administrator with notifications from the site, and the site e-mail address is used as the originating e-mail address when the site sends e-mails to users. You can change these settings later on in the Site information page in the Configuration section. It's important to select the options to receive the site notifications so that you are aware when software updates are available for your site core and contrib modules; important security updates are available from time to time. There's more... In this recipe we have seen a regular Drupal installation procedure. There are various different ways to install and configure Drupal. We will explore some of these alternatives in the following sections. We will also cover some of the potential pitfalls you may come across with the requirements page. Uploading through a control panel If your web-hosting provider provides web access to your files through a control panel such as CPanel, you can save time by uploading the compressed Drupal installation package and running the unzip function on the file, if that functionality is provided. This will dramatically reduce the amount of time taken to perform the installation. Auto-installers There are other ways in which Drupal can be installed. Your hosting may come with an auto- installer such as Fantastico De Luxe or Softaculous. Both of these services provide a simple way to achieve the same results without the need to use FTP or to configure a database. Database table prefixes At the database setup screen there is an option to use a table prefix. Any prefix entered into the field would be added to the start of all table names in the database. This means that you could run multiple installations of Drupal, or possibly other CMSs from the same database by setting a different prefix. This method, however, will have implications for performance and maintenance. Installing on a Windows environment This recipe deals with installing Drupal on a Linux server. However, Drupal runs perfectly well on an IIS (Windows) server. Using Microsoft's WebMatrix software, it's easy to set up a Drupal site: http://www.microsoft.com/web/drupal Alternative languages Drupal supports many different languages. You can view and download the language packs at http://localize.drupal.org/download. You then need to upload the file to Drupal root/profiles/standard/translations. You will then see the option for that new language in the language selection page of the installation. Verifying the requirements page If all goes to plan, and the server is already configured correctly, then step 3, the server requirements page, will be skipped. However, you may come across problems in a few areas: Register Globals: This should be set to off in the php.ini file. This is very important in securing your site. If you find that register globals is turned on, then you will need to consult your hosting provider's documentation on this feature in order to switch it off. Drupal will attempt to create the following folder: Drupal root/sites/default/ files. If it fails, you may have to manually create this file on the server and give it the permission 755. Drupal will attempt to create a settings.php file by copying the default.settings.php file. If Drupal has trouble doing this, copy the default.settings.php file in the following directory: Drupal root/sites/default/default.settings.php and rename the copied file as settings.php. Give settings.php full write access CHMODD 777. After Drupal finishes the installation process, it will try to set the permission of this file to 444; you must check that this has been done, and manually set the file to 444, if it has not. See also See Installing Drupal distributions for more installation options using a preconfigured Drupal distribution. For more information about installing Drupal, see the installation guide at Drupal.org: http://drupal.org/documentation/install
Read more
  • 0
  • 0
  • 1601
article-image-setting-basics-drupal-multilingual-site-languages-and-ui-translation
Packt
25 Jun 2012
10 min read
Save for later

Setting up the Basics for a Drupal Multilingual site: Languages and UI Translation

Packt
25 Jun 2012
10 min read
(For more resources on Drupal, see here.) Getting up and running Before we get started, we obviously need a Drupal 7 website to work on. This section gives you two options, namely, roll your own or install the demo. Using your own site You can use your own Drupal 7 site. It can be an existing site or one you create from scratch. If you are creating a brand new site and weren't planning on using a particular installation profile, you can get a head start by using the Localized Drupal Distribution install profile at drupal.org/project/l10n_install. It is probably obvious, but it's best to run the site on a development machine and not in a production environment. Once all the basic Drupal core modules are configured, you will also want to set up the following additional modules to get the most out of the exercises: Panels: A tool for creating pages with custom layouts Path auto: Settings for creating path aliases automatically Views: A tool for creating custom pages and blocks Using the demo site If you'd prefer a jump-start, a full demo website can be created using a special install profile. Instructions for downloading and installing the demo website are included on the Drupal project page available at drupal.org/project/multilingual_book_demo. The demo site contains additional modules including the modules listed previously as well as the following: Administration Menu: Toolbar for quick access to the site configuration Views Bulk Operations: Extra functionality for Views forms Views Slideshow: Slideshows of content coming from Views These modules provide us with a starting point. As more modules are needed for particular exercises, they will be listed so you can add them. Roles, users, and permissions Although you might already have multiple users on your test site, for simplicity it will be assumed that you are logged in as the super admin (user ID 1). Working with languages If we want a multilingual site, the logical first step is to add more languages! In this section, we will add languages to our site, configure how our languages are detected, and set up ways to go between these languages. Adding languages with the Locale module Drupal has language support built into the core, but it's not fully turned on by default. If you go to your site right now and navigate to Configuration | Regional and language, you will see the Regional settings and Date and time comfit page s for configuring default country, time zone, and date/time formats: To get our languages hooked in, let's enable the core module, Locale. Now go back to Configuration | Regional and language to see more options: Click on Languages and you'll see we only have English in our list so far: Now let's add a language by clicking on the Add language link. You can add a predefined language such as German or you can create a custom language. For our purposes, we will work with predefined languages. So choose a language and click on the Add language button. Drupal will then redirect you to the main language admin page and your new language will be added to the list. Now you can simply repeat the process for each language. In my case, I've added three new languages, namely, Arabic, German, and Polish: The overview table shows the language's name (English and native), its code, and its directionality. The language's direction can be Left to right (LTR) or Right to left (RTL), with most languages using the former. 'Right to left' just means that you start at the right side of the page and move towards the left side when you are writing. RTL languages include Arabic, Hebrew, and Syriac, which are written in their own alphabets. You can choose which languages to enable, order them, and set the site default. Links are provided to edit and delete each language. English only has an edit link since it is the system language and cannot be deleted, but English can be disabled if you use a non-English default. If we edit a language, we can modify all the information from the overview table except for the language's code since we need that as a consistent reference string. Do not change the default language once you have started translating or translations might break. Install String Translation from the Internationalization package (drupal.org/project/i18n), go to Configuration | Regional and language | Multilingual settings | Strings, select the Source language, and click on Save configuration. Do not change this setting once it's configured. Detecting languages We have our languages, so now what? If you click around your site, nothing looks different. That's because we are looking at the English version of the site and we haven't told Drupal how we want to deal with the other languages. We'll do that now. Navigate to Configuration | Regional and language | Languages | Detection and selection and you'll see we have a number of choices available to us: The Default detection method is enabled for us, but we can also enable the URL, Session, User, and Browser options. If you want a cookie-based option, check out the Language Cookie and Locale Cookie modules. Let's go over the core options in more detail. URL If you enable this method, users can navigate to URLs such as example.com/de/ news or example.com/deutsch/news (when using the path prefix option) and example.de/news, deutschexample.com/news, or deutsch.example.com/news (when using the domain option). Configuring domains requires web server changes, but using path prefixes does not. This is a common configuration for multilingual sites, and one we'll use shortly. The language's path prefix can be changed when editing the language. If you want to use path-prefixed URLs, then you should decide on your path prefixes before translating content as changing path prefixes might break links (unless you set up proper redirects). If desired, you can choose one language that does not have any path prefix. This is common for the site's default language. For example, if German is the default language and no path prefix is used, the news page would be accessed as example.com/news whereas other languages would be accessed using a path prefix (for example, example.com/en/news). Session The Session option is available if you want to store a user's language preference inside their user session. It was actually proposed by some Drupal community members that this method be removed from the set of choices as it caused a number of issues in other code. One reason you may not want to use this option is due to the possible inconsistency between the content and the URL language. For example, you could enable both URL and Session methods and order them so that the Session method is first. If a user is at example.com/de and if the session is set to French, then the user will see French content even though the URL corresponds with German. My advice is to just skip this one, or, if you need it, at least make sure that it's ordered below the URL option. User Once the Locale module is enabled, users can specify their preferred language when they edit their account profile. If you enable the User method in the detection settings, the user's profile language will be checked when deciding what language to display. Note that the user profile language defaults to the site's default language. Browser Users can configure their browsers to specify which languages they prefer. If the Browser method is enabled, Drupal will check the browser's request to find out the language setting and use it for the language choice. This option may or may not be useful depending on your site audience. Default The default site language is configured on the Configuration | Regional and language | Languages settings page, and is used for the Default detection method. Although you can't disable this method, you can reorder it if you choose. But, it makes the most sense to keep it at the bottom of the list to use it as the fallback language. Detection method order It is important to note that the detection method order is critical to how detection works. If you were to drag the Default method to the top of the list, then none of the other methods would be used and the site would only use the default language. Similarly, if you allow a user profile language and drag User to top of the list, then the URL method would not matter even if it's enabled. Also, if URL detection is ordered below Session, User, and Browser options, the user might see a UI language that does not match up with the URL language, which could be confusing. Make sure to think carefully about the order of these settings. If you use the URL method, it's likely you will want it first. The Default method should be last. The other detection method positions depend on your preference. When using path-prefixed URLs, if one language does not have a prefix, then detection for that language will work differently. For example, if the URL method is first, then no other detection methods will trigger for any URLs with no path prefix such as example.com/news or example.com/about-us. Our choice For our purposes, let's stick with URL detection and use the path-prefix option as this is the easiest to configure (it doesn't require extra domains). This choice will keep our URLs in sync with our interface language, which is also user and SEO-friendly. Check Enabled for the URL method and press the Save settings button. Now click on Configure for that method and you'll see options for Path prefix and Domain. We'll use the default option, that is Path prefix (for example, example.com/de). Don't panic on the next step. You won't see anything different in the UI until we finish our interface translation process later in the article. Now change the URL in your browser to include the path prefix for one of your languages. In my case, I'll try German and go to example.com/de. You should be able to use the path prefixes for each of your configured languages. Switching between languages Most likely you don't want your users to have to manually type in a different URL to switch between languages. Drupal core provides a language switcher block that you can put somewhere convenient for your users. To use the block, navigate to Structure | Blocks, find the Language switcher (User interface text) block, position it where you'd like, and save your block settings. The order of the languages in the block is based on the order configured at Configuration | Regional and language | Languages. Once enabled, the language switcher block looks like the following screenshot: You can now easily switch between your site languages, and the language chosen is highlighted. The UI won't look different when switching until we finish the next section. Two alternatives to the core language switcher block are provided by the Language Switcher and Language Switcher Drop-down modules. Also, if you want country flag icons added next to each language, you can install the Language Icons module.
Read more
  • 0
  • 0
  • 5731

article-image-wordpress-buddypress-courseware
Packt
19 Jun 2012
10 min read
Save for later

Wordpress: Buddypress Courseware

Packt
19 Jun 2012
10 min read
Installing and configuring BP Courseware As BP Courseware is a plugin that runs atop BuddyPress, we must have already installed, activated, and configured BuddyPress. To install BP Courseware, log in to the WordPress dashboard, hover over Plugins in the left sidebar, and choose Add New. Search for BuddyPress ScholarPress Courseware and install the plugin. BuddyPress Courseware requires the Private Messaging BuddyPress component to be enabled. If you have disabled Private Messaging, you will be prompted to enable it before activating BuddyPress Courseware. To enable Private Messaging, log in to the WordPress dashboard and visit the BuddyPress Components screen. BuddyPress Courseware settings While BuddyPress Courseware will work immediately, there are a number of settings that can be adjusted to ensure that the plugin meets our needs. To access the BuddyPress Courseware settings, log in to the WordPress dashboard, hover over BuddyPress in the left sidebar, and select Courseware. Global settings BP Courseware integrates with BuddyPress groups for course management. By default, we must enable courseware individually for each group. Checking the Enable Courseware globally checkbox will turn courseware on for all new groups. This is useful if groups are used exclusively for course management. If you intend to use BuddyPress groups for other purposes, such as student project collaboration, the Enable Courseware globally option should remain unchecked. In this scenario each group will require enabling courseware manually. To do so, follow the instructions given in the Enabling BP Courseware section later in the article. Collaboration settings Within BP Courseware we are able to define users as either teachers or students. By enabling the Collaboration settings option, any site user with a teacher role has the ability to edit and add courses, assignments, and schedules. Make assignment responses private When students submit an assignment their response is public to all site users. By enabling the Make assignment responses private feature, student responses will be visible only to the teachers and the student who has completed the assignment. Gradebook default grade format The default BuddyPress Courseware Gradebook format is numeric. Within the Gradebook default grade format settings we are able to choose between numeric, letter, or percentage grading for assignments. Webservices API integration BP Courseware has the ability to integrate with WorldCat and ISBNdb web services to aid in locating books and articles. To integrate these services with BuddyPress Courseware, follow the links from the BudddyPress Courseware settings screen to sign up for a free API key. Customization Cascading stylesheets (CSS) are the files that control the look and formatting of a web page. BuddyPress Courseware allows administrators with advanced web skills to create a custom stylesheet for fine grain control over the look of Courseware. Renaming the groups page BP Courseware utilizes the BuddyPress group feature for course content. While the term Groups makes sense in the context of a standard BuddyPress installation, it can be confusing when using BuddyPress Courseware as a learning management system. To prevent this confusion, I find it helpful to rename the Groups page to Courses.   To rename Groups: Log in to the WordPress dashboard. Create a new WordPress page titled Courses by hovering over Pages in the left sidebar, and choosing Add New. Title the page Courses, leaving the page content blank, and click on the blue Publish button Adjust the BuddyPress page settings by hovering over BuddyPress in the left sidebar and selecting the Pages tab. In the menu next to User Groups, select the Courses option and click on the Save button. Delete the Groups page by clicking on Pages in the left sidebar. From the All Pages screen, hover over the Groups page and click on the red Trash link. Setting Courses as the site home page Using the BuddyPress Courseware plugin, we may wish to enable our Courses page as the site's front page. Doing so will allow students to quickly access course information and prevent confusion regarding how to find the courseware dashboard.   To enable the Courses page as our site's home page: Log in to the WordPress dashboard. If you have not already done so, create an empty page titled Blog Hover over Settings in the left sidebar and select the Reading tab. From the Reading Settings screen, select Front page displays | A static page option. Select Courses from the Front page menu choices and Blog as the Posts page Creating a course When setting up a course we must first create a BuddyPress group. To create course or group: From our public facing site, visit the Courses page (or Groups if not renamed). Click on the Create a Group button. From the Details screen, provide a Group Name such as the course name and section number and enter a Group Description such as the course catalog information. On the Privacy Options page, select This is a public group, allowing any site member to join. Complete the installation by optionally adding an avatar image and inviting members. Enabling BP Courseware Once the course group has been created, we may enable BP Courseware. This step may be skipped, if we selected Enable Courseware globally from the BuddyPress Courseware settings screen. To enable BP Courseware: Visit the page of the newly created group. Click on the Admin tab Click on the Courseware link from the row of links below the Admin tab. Below Courseware Status , select Enable to enable BP Courseware for the group. Optionally, if you wish to keep student assignment responses private, select Enable below Private Responses. Click on the Save button. Courseware dashboard Within BP Courseware, the courseware dashboard acts as the course home screen for both instructors and students. From the courseware dashboard, instructors are able to add and manage course content. Students use the dashboard to access course materials and submit assignments. To access the courseware dashboard, visit the Courses page (or Groups if unchanged) and click on the Courseware link located below the course/group description. The teacher dashboard appears as shown in the following screenshot: The student dashboard appears as shown in the following screenshot: Adding course content Adding course content to BP Courseware allows educators to easily organize and share course information with students. The BP Courseware plugin provides a structure for managing course lectures, assignments, quizzes, grades, resources, and schedules. Lectures Adding lecture information allows instructors to share course notes, resources, and slides with students in a structured format. While the term lecture implies the lecture format of university courses, I find it useful to think of lectures in terms of teaching units. The lecture pages can serve as a resource for a chunk of course content. To add a new lecture, click on the Add a new lecture button from the course dashboard. We may then edit the content of the lecture much in the same way as a WordPress post adding text, images, links, and embedded media. Lectures will appear in the Latest Lectures section of course dashboard, with the most recently posted lecture appearing at the top. This allows students to quickly access the most recently posted course lecture. Assignments BP Courseware provides a means for us to post assignments and collect student responses. The assignments can take multiple formats, allowing students to respond to questions, upload a file, or embed media. Posting assignments as a teacher As a teacher, we have the ability to post assignments. To post an assignment, visit the course dashboard and click on the Create an assignment button. This will take us to the New Assignment screen. From the New Assignment screen, we may enter the details of the assignment. From the New Assignment screen, assign a title to the assignment and enter the assignment description and necessary information. This acts much in the same way as WordPress posts, allowing us to enter text, images, media, and links. In the right column, we may choose the corresponding lecture topic and select the assignment due date. Once the assignment information is complete, click on the Publish assignment button to make it visible to students. Submitting assignments as a student Students can access assignments by clicking on the All Assignments button or viewing the Latest Assignments from the course dashboard. By clicking on the Assignment Title, students can see the detailed assignment information written by the instructor. Clicking on the Add a response button, will give the students an opportunity to submit the assignment. For standard assignments, students will be presented with a text input area similar to the WordPress post editor. Within this text area, students may type a written response, add links, embed media, and attach files. Viewing student responses Instructors have access to all student assignment responses, while students are only able to view their own. To view student assignment responses, visit the individual assignment page and click on the Responses button, located in the right sidebar. This will present us with a list of student responses. Clicking on the individual assignment link, will take us to a screen containing the student's assignment response. Gradebook BP Courseware provides us with a Gradebook feature for assessing student assignments. To access the Gradebook, visit an individual assignment page and click on the Gradebook button, located in the right sidebar. This will take us to the Gradebook screen for the assignment. For each student, we are given the option to enter a grade value, a private comment, and a public comment. Once the grades and comments have been entered, we may click on the Save grades button. After an assignment has been graded, students will receive a message containing the grade. Students will be alerted to this message by a notification, but may access their grades directly by visiting the individual assignment page. The grade is posted in the Assignment Meta sidebar of the assignment page. Bibliography The Bibliography is designed so that educators can easily maintain a list of course materials and resources. To add entries to the bibliography, visit the Courseware dashboard and click on the Manage bibliography button. From the Bibliography page we may add entries manually or import them by pasting information from BibTeX. The bibliography is ideal for courses utilizing a wide range of materials. BibTeX is a tool for formatting references. It is typically used in conjunction with the LaTeX typesetting system. More information can be found at http://www.bibtex.org. Schedule and calendar The BuddyPress Schedule page functions as a course calendar, automatically containing assignment due dates as well as manually managed schedule items. To view the course calendar, visit the Courseware Dashboard and click on the Schedules link. To schedule more items, click on the Add a schedule button from the Courseware dashboard. Complete the New Schedule form and click on the Publish Schedule button once it is complete. New schedule items will be added to the calendar as well as featured in a list format on the Schedules page.
Read more
  • 0
  • 0
  • 2337