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

How-To Tutorials

7018 Articles
article-image-choosing-right-flavor-debian-simple
Packt
08 Oct 2013
7 min read
Save for later

Choosing the right flavor of Debian (Simple)

Packt
08 Oct 2013
7 min read
(For more resources related to this topic, see here.) Getting ready At any point in time, Debian has three different branches available for use: stable, testing, and unstable. Think of unstable as the cutting edge of free software; it has reasonably modern software packages, and sometimes those packages introduce changes or features that may break the user experience. After an amount of time has passed (usually 10 days, but it depends on the package's upload priority), the new software is considered to be relatively safe to use and is moved to testing. Testing can provide a good balance between modern software and relatively reliable software. Testing goes through several iterations during the course of several years, and eventually it's frozen for a new stable release. This stable release is supported by the Debian Project for a number of years, including feature and security updates. Chances are you are building something that has an interesting team of people to back it up. In such scenarios, web development teams have chosen to go with testing, or even unstable, in order to get the latest software available. In other cases, conservative teams or groups with less savvy staff have resorted to stable because it's consistent for years. It is up to you to choose between any, but this book will get you started with stable. You can change your Advanced Packaging Tool (APT ) configuration later and upgrade to testing and unstable, but the initial installation media that we will use will be stable. Also, it is important that developers target the production environment as closely as possible. If you use stable for production, using stable for development will save a lot of time debugging mismatches. You should know which versions of programming languages, modules, libraries, frameworks, and databases your application will be targeting, as this will influence the selection of your branch. You can go to packages.debian.org to check the versions available for a specific package across different branches. Choosing testing (outside a freeze period) and unstable will also mean that you'll need to have an upgrade strategy where you continuously check for new updates (with tools such as cron-apt) and install them if you want to take advantage of new bug fixes and so on. How to do it… Debian offers a plethora of installation methods for the operating system. From standard CDs and DVDs, Debian also offers reduced-size installation media, bootable USB images, network boot, and other methods. The complexity of installation is a relative factor that usually is of no concern for DevOps since installation only happens once, while configuration and administration are continuously happening. Before you start considering replication methods (such as precooked images, network distribution, configuration management, and software delivery), you and your team can choose from the following installation methods: If you are installing Debian on a third-party provider (such as a cloud vendor), they will either provide a Debian image for you, or you can prepare your own in virtualization software and upload the disk later. If you are installing on your own hardware (including virtualized environments), it's advisable to get either the netinst ISO or the full first DVD ISO. It all depends on whether you are installing several servers over the course of several months (thus making the DVD obsolete as new updates come out) or have a good Internet connection (or proxies and caching facilities, nearby CDNs, and so on) for downloading any additional packages that the netinst disk might not contain. In general, if you are only deploying a handful of servers and have a good Internet connection at hand, I'd suggest you choose the amd64 netinst ISO, which we will use in this book. There's more… There are several other points that you need to consider while choosing the right flavor of Debian. One of them is the architecture you're using and targeting for development. Architectures There are tens of computer architectures available in the market. ARM, Intel, AMD, SPARC, and Alpha are all different types of architectures. Debian uses the architecture codenames i386 and amd64 for historical reasons. i386 actually means an Intel or Intel-compatible, 32-bit processor (x86), while amd64 means an Intel or Intel-compatible, 64-bit processor (x86_64). The brand of the processor is irrelevant. A few years ago, choosing between the two was tricky as some binary-only, non-free libraries and software were not always available for 64-bit processors, and architecture mismatches happened. While there were workarounds (such as running a 32-bit-only software using special libraries), it was basically a matter of time until popular software such as Flash caught up with 64-bit versions—thus, the concern was mainly about laptops and desktops. Nowadays, if your CPU (and/or your hypervisor) has 64-bit capabilities (most Intel do), it's considered a good practice to use the amd64 architecture. We will use amd64 in this book. And since Debian 7.0, the multiarch feature has been included, allowing more than one architecture to be installed and be active on the same hardware. While the market seems to settle around 64-bit Intel processors, the choice of an architecture is still important because it determines the future availability of software that you can choose from Debian. There might be some software that is not compiled for or not compatible with your specific architecture, but there is software that is independent of the architecture. DevOps are usually pragmatic when it comes to choosing architectures, so the following two questions aim to help you understand what to expect when it comes to it: Will you run your web applications on your own hardware? If so, do you already have this hardware or will you procure it? If you need to procure hardware, take a look at the existing server hardware in your datacenter. Factors such as a preferred vendor, hardware standardization, and so on are all important when choosing the right architecture. From the most popular 32- or 64-bit Intel and AMD processors, the growing ARM ecosystem, and also the more venerable but declining SPARC or Itanium, Debian is available for lots of architectures. If you are out in the market for new hardware, your options are most likely based on an Intel- or AMD-compatible, 32- or 64-bit, server-grade processor. Your decisions will be influenced by factors such as the I/O capacity (throughput and speed), memory, disk, and so on, and the architecture will most likely be covered by Debian. Will you run your web applications on third-party hardware, such as a Virtual Private Server (VPS ) provider or a cloud Infrastructure as a Service (IaaS ) provider? Most providers will provide you with prebuilt images for Debian. They are either 32- or 64-bit, x86 images that have some sort of community support—but, be aware they might have no vendor support, or in some cases waive warranties and/or other factors such as the SLA. You should be able to prepare your own Debian installation using virtualization software (such as KVM, VirtualBox, or Hyper-V) and then upload the virtual disk (VHD, VDI, and so on) to your provider. Summary In this article, we learned about selecting the right flavor of Debian for our system. We also learned about the different architectures available in the market that we can use for Debian. Resources for Article : Further resources on this subject: Installation of OpenSIPS 1.6 [Article] Installing and customizing Redmine [Article] Installing and Using Openfire [Article]
Read more
  • 0
  • 0
  • 17206

article-image-layer-height-fill-settings-and-perimeters-our-objects
Packt
08 Oct 2013
7 min read
Save for later

Layer height, fill settings, and perimeters in our objects

Packt
08 Oct 2013
7 min read
(For more resources related to this topic, see here.) Getting ready Open up Slic3r and go to the Print Settings tab. We're staying in the Simple mode for now, because it's easier to track the changes we make to the changes in our final print. A good thing to do when making setting changes is to only make one change at a time. This is so that if something goes wrong, or right, we know exactly what change did it. How to do it... The Print Settings section is where a lot of changes will happen as we print. Let's go down the list of options in this section so we know what they are and why we might want to change them, sometimes from print to print. First up is Layer height option. The default layer height of 0.4mm is ok, assuming that we have a 0.5mm nozzle. So we can leave that for now. If our nozzle is more than 0.5mm though, we will have a lot of squeeze out of our filament. So if our nozzle is larger, increase the size of the layer. 80 percent of the nozzle diameter is a good rule of thumb. This also means that if we have a nozzle less than 0.5mm, we can make our layer height default smaller. Again, 80 percent of the nozzle diameter is a good starting place. Depending on our object we are printing, the Perimeters (minimum) setting of 3 is good. If there are gaps in the walls, especially of sloped surfaces, increasing the number of perimeters is something to try. Next, Solid layers is the setting of how many layers Slic3r will tell the printer to fill completely at the top and the bottom of the print. For the bottom layers, this will give the object a stable base that is less prone to warping. For the top, the default of 3 layers is based on the extruded filament width, and how much coverage the filament will give as it gets to the top of the object. For the Infill settings, a value of 0.15 for Fill density should stay, but change Fill pattern to honeycomb. It's a bit slower, but more stable. This is how the inner part of the object is filled with plastic. Since filling the entire object uses a lot of plastic, and isn't needed, we set the infill settings. How it works... Layer height, infill settings, perimeters, what does it all mean? Let's look into those settings and what they stand for, in more detail. Layer height The layer height of the print means how thick each layer of plastic is deposited on the model. The thinner the layer, the smoother and more detailed the print can be. We don't always want thin layers though. Some prints, such as for mechanical parts, or parts that will not be seen, can be done with thicker layer heights. If we're printing parts for a RepRap or another printer, the layer height can be thicker for the structural elements. It doesn't directly relate to the structural strength however. That would be covered in a moment when discussing the Perimeters and Infill settings. For thicker layer heights, it's usually a good idea to have layers at or under your nozzle size. This is so the extruder will press the plastic into the layer below. If the layer height is higher, the plastic will have a chance to cool before touching the foundation layer, and also only have gravity to help weld the two layers together. If we're printing objects for viewing, such as a statue or a decorative item, we'll usually want to go with thinner layer heights. This comes at the expense of printing speed, because the printer will now need to lay down more layers to complete the model. So finding a balance between looks and speed is something we will constantly juggle. For very detailed objects, resolutions as low as 0.1mm have been achieved by some printers. Perimeters These make up the walls of the object. They are also important for adding stability to the object being printed. The Slic3r developers recommend a minimum of two perimeters for printing. Having at least two will help both the structure of the outside, and help to cover up imperfections in the print. There is also a setting for solid layers. It is related to Perimeters, in that, it determines the number of solid layers at the top and the bottom of the print. The default setting for this is three perimeters. For models that are not solid, set them with the Infill settings; having more than one top layer will help bridge any gaps in the model and will result in a better fill for the top of the model. The default setting for Slic3r is for the three top and bottom layers to be solid. Depending on our model, and what we want to do with it, we can change this. Coming up is a hack for making hollow objects such as vases from normally solid objects. Infill settings Infill in our objects gives them stability. Too much infill, however, such as making our object solid, can not only cause printing issues, but also is a waste of plastic. The Fill Density setting ranges from 0 to 1, with 0 being 0 percent, and 1 being 100 percent. The default setting for Fill Density is 40 percent, or 0.4 in the preference. This is a decent setting to start with, but for structural components, or ones that will depend on being rigid under stress, raising that up would be a good idea. The developers suggest a minimum of 0.2 as the setting to support flat ceilings. Any lower, the top of your model is likely to sag inward. The Fill Pattern is interesting. This setting is how Slic3r will tell our printer how to fill in the inside of our model. The honeycomb option is good for structure, but takes longer to print. The developers also recommend rectilinear and line for infill, but there are several others to choose from. A bit of experimentation will reveal what is best for what models we want to print. There's more... Settings can be more than just settings. More than just a tool for making nicer quality prints. We can use some settings to alter the objects themselves, to make changes to the objects, and have it come out as what we want without having to touch the modeling software. Vases and other hollow objects There are some interesting things you can do while printing models and changing these settings. For instance, if you set the Infill Fill Density to 0, and the Top setting of Solid layers to 0, you can make any object hollow with the top open. We'll need to make sure the model can actually print this way, structurally. If it can, it is an interesting way to make custom vases or other open cupped objects. Having a higher setting on the Perimeters (minimum) will help some prints with this. Summary This article talked about some of the most important settings for printing your objects. It delved into how each setting works, and how changing it affects your final printed object. Resources for Article: Further resources on this subject: Learn Baking in Blender [Article] Getting Started with Blender’s Particle System- A Sequel [Article] The Trivadis Integration Architecture Blueprint: Implementation scenarios [Article]
Read more
  • 0
  • 0
  • 6565

article-image-disaster-recovery-techniques-end-users
Packt
08 Oct 2013
11 min read
Save for later

Disaster Recovery Techniques for End Users

Packt
08 Oct 2013
11 min read
(For more resources related to this topic, see here.) Well this DR concept is wrong and might work in the mainframe world, but with SharePoint, the approach should be "we are all in this together". Financially, this approach makes sense as well. The following screenshot shows the SharePoint costs for 1,000 users over a 3-year period. If IT support can be reduced by just 2 percent through end user education, the savings would equate to almost $40,000, by not doing a lot of extra work. Unfortunately, this is often overlooked, because there is a perception that end users already have SharePoint knowledge. Source: www.huddle.com In the previous screenshot, the people costs are manpower such as support, administration, trainers, and development. In this article, we will cover the following points: Why end user DR training is often forgotten Useful end user DR practices Managing expectations Training Why is end user DR training often forgotten? Why is end user DR training often forgotten? End user DR is often overlooked by the IT department because typical DR procedures involve SQL Server backup plans, server images, and third-party backup tools, all of which are handled by IT resources. End users are not necessarily technical and are not accustomed to performing even the simplest backup and restore procedures. When IT puts together a DR plan, the procedures normally focus on the "big hairy" disasters which are costly, highly visible to upper management, and effort large user communities. The small end user issues are often overlooked. These small issues are more common than one would think. Often, IT's perception of end users is that they are not capable of protecting their content with scheduled backups and although this is often the case, you can set up a DR process targeted to the end users. Although end users usually only manipulate content, it is the deleted content, such as sites, files, and list items that is most alarming to them. These end user disasters have their own negative effect on productivity and business continuity. Useful end user DR practices This section explains simple, yet often overlooked SharePoint functionality that enables the end user to recover content without the IT helpdesk number being dialed. Recycle bins Often an end user will delete content and not realize this information can be retrieved from the end user site recycle bin. To retrieve content from the end user site recycle bin, follow these steps: In the quick launch tray, click on Site Contents, as shown in the following screenshot: Select Recycle Bin on the ribbon, as shown in the following screenshot: Choose the file that you wish to restore, and then select the Restore Selection link, as depicted in the following screenshot: The file will be restored to the original location from where it was deleted. This simple and easy activity can be performed by the end user. By default, content stays in the recycle bin for 30 days and then it is moved to the Site Collection's recycle bin. The Site Collection Administrator can also restore content at the top-level site of the Site Collection by selecting the Recycle bin on the Site Content page. The following screenshot explains the first and second stage recycle bins: One of the advantages of the Site Collection administrator or IT performing this activity is that they do not need to navigate to the actual site where the document was deleted. This makes the restore process slightly quicker. This recycle bin restore feature can save the day, because often senior committees often meet once a month—every 30 days—just when deleted content is being moved to the Site Collection recycle bin, which requires a Site Collection administrator's intervention. So it makes sense to extend the duration of the site recycle bin. Increase the site recycle bin retention time Problem An executive level committee meets once a month, at the end of the month. The default site recycle bin configuration moves the deleted items to the second stage (or Site Collection) recycle bin every 30 days (that is, at the end of the month). The committee members are looking to restore deleted content, but find the site recycle bin empty. Due to bad timing, the content was moved to the Site Collection recycle bin right about the time of their monthly meeting! The committee will have to contact the helpdesk to restore the content. Resolution Increase the site recycle bin retention time so that it does not coincide with the end-of-month activities. To extend the duration of the recycle bin, follow the next given steps. This must be performed by someone with the appropriate permissions. In Central Administration, perform the following steps: Select the web application containing the Site Collection. Click on the General Settings button from the ribbon. Select the General Settings submenu. Scroll down to the Recycle Bin section. Only a Site Collection administrator can restore content in the Site Collection recycle bin. Make the changes to the retention days of the Recycle Bin. Checked in but not published Often, end users will upload a document to SharePoint, check it in, but not publish it. This results in restricted visibility to the document for other users, because the document is not published. The unpublished document is not visible to other end users, so the end user train of thought is that SharePoint is not working and they of course call the help desk. To prevent this from occurring, educating the end user is key. You will need to explain that the document needs to be published for readership to occur. Keeping documents unpublished allows only users with editable access to the content. This might be by design. The following screenshot illustrates how to publish a document. This also applies to any SharePoint content such as calendar event, or an announcement. The previous screenshot can be accessed from a view of a list or library and through the item drop-down menu. Permission Similar to the previous point of major publishing, an end user unintentionally changes the permission on content and restricts the ability for other users to view or edit it. This is often interpreted as "There's a problem with SharePoint!" This can be resolved easily with the end user or IT confirming the content permissions by performing the following steps: Open the menu option of the content. Click on View Properties. Click on Share With on the ribbon. Click on Advanced. Select the Check Permissions icon. This will confirm who has access to the content. Users can't remember where their file is saved This is a common issue with end users, and a call to the Help Desk often follows. Before pulling out the backup and restore documentation, performing a SharePoint search to locate the file could be the quickest way to locate it. Version control The version control capabilities of SharePoint are a big selling point of the product that is often overlooked in an actual SharePoint deployment. By default, version control is turned off on lists and libraries. Therefore, as a result, previous versions of the document are not recoverable. To restore a previous version of a content object, carry out the following procedure: Open the menu option of the content. Select Version History. Restore a previous version. Version history is not turned on automatically when a list/library is created. This is done in the list/library settings, and has to be done for each list/library. SkyDrive Pro SkyDrive Pro (Sky Drive) is a Dropbox-type desktop application for the professional community. Files are saved on the end user's PC and synchronized both with other devices and on your My Site SharePoint server. SkyDrive Pro is a part of Office 2013 Standard or ProPlus. It can be installed separately for previous editions of Office, but there is no synchronization client for Office 2010 or 2007. SkyDrive Pro is similar to the SharePoint Workspace 2010, which was Groove, the Microsoft client software that never really took off. This is mentioned as a comparison of technologies in different versions of SharePoint. To synchronize files, carry out the following steps: In the document library on your My Site (or any site), click on the SkyDrive link on the menu as shown in the following screenshot: This will display the following screen: Click on the SYNC link on the ribbon (top right-hand corner). The content in the library and the end user's desktop will be synchronized. This is an end user DR procedure if the SharePoint server is unavailable. The files can be stored offline are still accessible. Admittedly, this is a temporary measure, but it still provides content workability for the end user. This is not peer-to-peer software, so you will need SharePoint in the mix somewhere. You can think of SkyDrive Pro as your SkyDrive for business. When you store your files on SkyDrive Pro, only you can see them, but you can easily share them with co-workers and access them from your mobile devices. Your files are safely kept in the cloud with SharePoint Online, or on your company's SharePoint Server 2013 servers, depending on what your company has set up. Microsoft's SkyDrive was previously called Windows Live SkyDrive and Windows Live Folders is a file hosting service that allows users to upload and synchronize files to cloud storage and then access them from a web browser or their local device. It is part of the Windows Live range of online services, and allows users to keep their files private, share them with contacts, or make the files public. This is a consumer-based file storage service available through your Microsoft account. SkyDrive, not SkyDrive Pro, has no relationship to SharePoint Server 2013. However, if you install Office 2013 and open Windows Explorer, you see a SkyDrive folder in the favorites section. For more information regarding SkyDrive, visit the following links: http://technet.microsoft.com/en-us/library/dn167720.aspx http://office.microsoft.com/en-us/word-help/share-a-document-using-sharepoint-or-skydrive-HA102849692.aspx http://community.office365.com/en-us/forums/154/t/162276.aspx http://sharepoint.microsoft.com/Blogs/GetThePoint/Lists/Posts/Post.aspx?ID=675 http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?pID=1015 http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?pID=1033 http://community.office365.com/en-us/blogs/office_365_technical_blog/archive/2013/05/29/skydrive-pro-client-for-windows-now-available.aspx By implementing the previous practices, the urgent support calls and the "Let me walk over to your desk" activity of the day should be reduced. Managing end user expectations End user and business expectations must be managed. This is in line with what is stated in Planning and Key Concepts – What Not to Forget, along with service level agreements. When there is a problem, how does it get resolved and how quickly is the business, IT, and user community made aware of the recovery time? Is there a support number to call, or is there just an online ticketing system. Just because the content is a Microsoft Word document does not mean that it is not important to someone who is important. So SharePoint support needs to be part of helpdesk support. Training The points mentioned in this article should be covered as part of end user training. The authors cannot stress how important end user training is to the end user DR procedure. This does not have to be more than an hour for a user, but the payoff is huge for uptime and a working environment for the end user. Cheat sheets are useful to provide tips in resolving easy and simple issues. Summary In this article the reader has been introduced to several simple techniques that can reduce the support calls or fire drill activities related to end user disaster recovery. These techniques will not save the day if SQL Server crashes, but this activity is not daily support activity to the business. The SharePoint cost of ownership is not the software licenses but the user support staff. If this can be reduced through user training, then the end user is more productive and IT is freed up. From experience, the authors would state, SharePoint 2010 licensing is approximately 5 percent of the total cost, with the remaining 95 percent represented by the administration and support costs. Resources for Article: Further resources on this subject: Microsoft SharePoint 2010 Administration: Farm Governance [Article] Microsoft Sharepoint 2010: List Management [Article] How to Manage Content in a List in Microsoft Sharepoint [Article]
Read more
  • 0
  • 0
  • 1827

article-image-custom-components-in-visualforce
Packt
08 Oct 2013
14 min read
Save for later

Custom Components in Visualforce

Packt
08 Oct 2013
14 min read
(For more resources related to this topic, see here.) Custom components allow custom Visualforce functionality to be encapsulated as discrete modules, which provides two main benefits: Functional decomposition, where a lengthy page is broken down into custom components to make it easier to develop and maintain Code re-use, where a custom component provides common functionality that can be re-used across a number of pages A custom component may have a controller, but unlike Visualforce pages, only custom controllers may be used. A custom component can also take attributes, which can influence the generated markup or set property values in the component's controller. Custom components do not have any associated security settings; a user with access to a Visualforce page has access to all custom components referenced by the page. Passing attributes to components Visualforce pages can pass parameters to components via attributes. A component declares the attributes that it is able to accept, including information about the type and whether the attribute is mandatory or optional. Attributes can be used directly in the component or assigned to properties in the component's controller. In this recipe we will create a Visualforce page that provides contact edit capability. The page utilizes a custom component that allows the name fields of the contact, Salutation, First Name , and Last Name, to be edited in a three-column page block section. The contact record is passed from the page to the component as an attribute, allowing the component to be re-used in any page that allows editing of contacts. How to do it… This recipe does not require any Apex controllers, so we can start with the custom component. Navigate to the Visualforce Components setup page by clicking on Your Name | Setup | Develop | Components. Click on the New button. Enter ContactNameEdit in the Label field. Accept the default ContactNameEdit that is automatically generated for the Name field. Paste the contents of the ContactNameEdit.component file from the code download into the Visualforce Markup area and click on the Save button. Once a custom component is saved, it is available in your organization's component library, which can be accessed from the development footer of any Visualforce page. For more information visit http://www.salesforce.com/us/developer/docs/pages/Content/pages_quick_start_component_library.htm. Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Click on the New button. Enter ContactEdit in the Label field. Accept the default Contact Edit that is automatically generated for the Name field. Paste the contents of the ContactEdit.page file from the code download into the Visualforce Markup area and click on the Save button. Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Locate the entry for the Contact Edit page and click on the Security link. On the resulting page, select which profiles should have access and click on the Save button. How it works… Opening the following URL in your browser displays the ContactEdit page: https://<instance>/apex/ContactEdit. Here, <instance> is the Salesforce instance specific to your organization, for example, na6.salesforce.com. The custom component that renders the input fields in the Name section defines a single, required attribute of type Contact. <apex:attribute name="Contact" type="Contact" description="The contact to edit" required="true" /> The description of the attribute must always be provided, as this is included in the component reference. The type of the attribute must be a primitive, sObject, one-dimensional list, map, or custom Apex class. The Contact attribute can then be used in merge syntax inside the component. <apex:inputField value="{!Contact.Salutation}"/> <apex:inputField value="{!Contact.FirstName}"/> <apex:inputField value="{!Contact.LastName}"/> The page passes the contact record being managed by the standard controller to the component via the Contact attribute. <c:ContactNameEdit contact="{!Contact}"/> See also The Updating attributes in component controllers recipe in this article shows how a custom component can update an attribute that is a property of the enclosing page controller. Updating attributes in component controllers Updating fields of sObjects passed as attributes to custom components is straightforward, and can be achieved through simple merge syntax statements. This is not so simple when the attribute is a primitive and will be updated by the component controller, as parameters are passed by value, and thus, any changes are made to a copy of the primitive. For example, passing the name field of a contact sObject, rather than the contact sObject itself, would mean that any changes made in the component would not be visible to the containing page. In this situation, the primitive must be encapsulated inside a containing class. The class instance attribute is still passed by value, so it cannot be updated to point to a different instance, but the properties of the instance can be updated. In this recipe, we will create a containing class that encapsulates a Date primitive and a Visualforce component that allows the user to enter the date via day/month/year picklists. A simple Visualforce page and controller will also be created to demonstrate how this component can be used to enter a contact's date of birth. Getting ready This recipe requires a custom Apex class to encapsulate the Date primitive. To do so, perform the following steps: First, create the class that encapsulates the Date primitive by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes. Click on the New button. Paste the contents of the DateContainer.cls Apex class from the code download into the Apex Class area. Click on the Save button. How to do it… First, create the custom component controller by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes. Click on the New button. Paste the contents of the DateEditController.cls Apex class from the code download into the Apex Class area. Click on the Save button. Next, create the custom component by navigating to the Visualforce Components setup page by clicking on Your Name | Setup | Develop | Components. Click on the New button. Enter DateEdit in the Label field. Accept the default DateEdit that is automatically generated for the Name field. Paste the contents of the DateEdit.component file from the code download into the Visualforce Markup area and click on the Save button. Next, create the Visualforce page controller extension by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes. Click on the New button. Paste the contents of the ContactDateEditExt.cls Apex class from the code download into the Apex Class area. Click on the Save button. Finally, create a Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Click on the New button. Enter ContactDateEdit in the Label field. Accept the default ContactDateEdit that is automatically generated for the Name field. Paste the contents of the ContactDateEdit.page file from the code download into the Visualforce Markup area and click on the Save button. Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Locate the entry for the ContactDateEdit.page file and click on the Security link. On the resulting page, select which profiles should have access and click on the Save button. How it works… Opening the following URL in your browser displays the ContactDateEdit page: https://<instance>/apex/ContactDateEdit?id=<contact_id>. Here, <instance> is the Salesforce instance specific to your organization, for example, na6.salesforce.com, and <contact_id> is the ID of any contact in your Salesforce instance. The Visualforce page controller declares a DateContainer property that will be used to capture the contact's date of birth. public DateContainer dob {get; set;} private Contact cont; private ApexPages.StandardController stdCtrl {get; set;} public ContactDateEditExt(ApexPages.StandardController std) { stdCtrl=std; cont=(Contact) std.getRecord(); dob=new DateContainer(cont.BirthDate); } Note that as DateContainer is a class, it must be instantiated when the controller is constructed. The custom component that manages the Date of Birth section defines the following two attributes: A required attribute of type DateContainer, which is assigned to the dateContainer property of the controller The title of for the page block section that will house the picklists; as this is a reusable component, the page supplies an appropriate title Note that this component is not tightly coupled with a contact date of birth field; it may be used to manage a date field for any sObject. <apex:attribute type="DateContainer" name="dateContainerAtt" description="The date" assignTo="{!dateContainer}" required="true" /> <apex:attribute type="String" description="Page block section title" name="title" /> The component controller defines properties for each of the day, month, and year elements of the date. Each setter for these properties attempts to construct the date if all of the other elements are present. This is required as there is no guarantee of the order in which the setters will be called when the Save button is clicked and the postback takes place. public Integer year {get; set { year=value; updateContainer(); } } private void updateContainer() { if ( (null!=year) && (null!=month) && (null!=day) ) { Date theDate=Date.newInstance(year, month, day); dateContainer.value=theDate; } } When the contained date primitive is changed in the updateContainer method, this is reflected in the page controller property, which can then be used to update a field in the contact record. public PageReference save() { cont.BirthDate=dob.value; return stdCtrl.save(); } See also The Passing attributes to components recipe in this article shows how an sObject may be passed as an attribute to a custom component. Passing action methods to components A controller action method is usually invoked from the Visualforce page that it is providing the logic for. However, there are times when it is useful to be able to execute a page controller action method directly from a custom component contained within the page. One example is for styling reasons, in order to locate the command button that executes the action method inside the markup generated by the component. In this recipe we will create a custom component that provides contact edit functionality, including command buttons to save or cancel the edit, and a Visualforce page to contain the component and supply the action methods that are executed when the buttons are clicked. How to do it… This recipe does not require any Apex controllers, so we can start with the custom component. Navigate to the Visualforce Components setup page by clicking on Your Name | Setup | Develop | Components. Click on the New button. Enter ContactEdit in the Label field. Accept the default ContactEdit that is automatically generated for the Name field. Paste the contents of the ContactEdit.component file from the code download into the Visualforce Markup area and click on the Save button. Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Click on the New button. Enter ContactEditActions in the Label field. Accept the default ContactEditActions that is automatically generated for the Name field. Paste the contents of the ContactEditActions.page file from the code download into the Visualforce Markup area and click on the Save button. Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Locate the entry for the ContactEditActions page and click on the Security link. On the resulting page, select which profiles should have access and click on the Save button. How it works… Opening the following URL in your browser displays the ContactEditActions page: https://<instance>/apex/ContactEditActions?id=<contact_id>. Here, <instance> is the Salesforce instance specific to your organization, for example, na6.salesforce.com, and <contact_id> is the ID of any contact in your Salesforce instance. The Visualforce page simply includes the custom component, and passes the Save and Cancel methods from the standard controller as attributes. <apex:page standardController="Contact"> <apex:pageMessages /> <apex:form > <c:ContactEdit contact="{!contact}" saveAction="{!save}" cancelAction="{!cancel}" /> </apex:form> </apex:page> The ContactEdit custom component declares attributes for the action methods of type ApexPages.Action. <apex:attribute name="SaveAction" description="The save action method from the page controller" type="ApexPages.Action" required="true"/> <apex:attribute name="CancelAction" description="The cancel action method from the page controller" type="ApexPages.Action" required="true"/> These attributes can then be bound to the command buttons in the component in the same way as if they were supplied by the component's controller. <apex:commandButton value="Save" action="{!SaveAction}" /> <apex:commandButton value="Cancel" action="{!CancelAction}" immediate="true" /> There's more… While this example has used action methods from a standard controller, any action method can be passed to a component using this mechanism, including methods from a custom controller or controller extension. See also The Updating attributes in component controllers recipe in this article shows how a custom component can update an attribute that is a property of the enclosing page controller. Data-driven decimal places Attributes passed to custom components from Visualforce pages can be used wherever the merge syntax is legal. The <apex:outputText /> standard component can be used to format numeric and date values, but the formatting is limited to literal values rather than merge fields. In this scenario, an attribute indicating the number of decimal places to display for a numeric value cannot be used directly in the <apex:outputText /> component. In this recipe we will create a custom component that accepts attributes for a numeric value and the number of decimal places to display for the value. The decimal places attribute determines which optional component is rendered to ensure that the correct number of decimal places is displayed, and the component will also bracket negative values. A Visualforce page will also be created to demonstrate how the component can be used. How to do it… This recipe does not require any Apex controllers, so we can start with the custom component. Navigate to the Visualforce Components setup page by clicking on Your Name | Setup | Develop | Components. Click on the New button. Enter DecimalPlaces in the Label field. Accept the default DecimalPlaces that is automatically generated for the Name field. Paste the contents of the DecimalPlaces.component file from the code download into the Visualforce Markup area and click on the Save button. Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Click on the New button. Enter DecimalPlacesDemo in the Label field. Accept the default DecimalPlacesDemo that is automatically generated for the Name field. Paste the contents of the DecimalPlacesDemo.page file from the code download into the Visualforce Markup area and click on the Save button. Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages. Locate the entry for the DecimalPlacesDemo page and click on the Security link. On the resulting page, select which profiles should have access and click on the Save button. How it works… Opening the following URL in your browser displays the DecimalPlacesDemo page: https://<instance>/apex/DecimalPlacesDemo. Here, <instance> is the Salesforce instance specific to your organization, for example, na6.salesforce.com. The Visualforce page iterates a number of opportunity records and delegates to the component to output the opportunity amount, deriving the number of decimal places from the amount. <c:DecimalPlaces dp="{!TEXT(MOD(opp.Amount/10000, 5))}" value="{!opp.Amount}" /> The component conditionally renders the appropriate output panel, which contains two conditionally rendered <apex:outputText /> components, one to display a positive value to the correct number of decimal places and another to display a bracketed negative value. <apex:outputPanel rendered="{!dp=='1'}"> <apex:outputText rendered="{!AND(NOT(ISNULL(VALUE)), value>=0)}" value="{0, number, #,##0.0}"> <apex:param value="{!value}"/> </apex:outputText> <apex:outputText rendered="{!AND(NOT(ISNULL(VALUE)), value<0)}" value="({0, number, #,##0.0})"> <apex:param value="{!ABS(value)}"/> </apex:outputText> </apex:outputPanel>
Read more
  • 0
  • 0
  • 4420

article-image-minimizing-http-requests
Packt
08 Oct 2013
6 min read
Save for later

Minimizing HTTP requests

Packt
08 Oct 2013
6 min read
(For more resources related to this topic, see here.) How to do it... Reducing DNS lookup: Whenever possible try to use URL directives and paths to different functionalities instead of different hostnames. For example, if a website is abc.com, instead of having a separate hostname for its forum, for example, forum.abc.com, we can have the same URL path, abc.com/forum. This will reduce one extra DNS lookup and thus minimize HTTP requests. Imagine if your website contains many such URLs, either its own subdomains or others, it would take a lot of time to parse the page, because it will send a lot of DNS queries to the server. For example, check www.aliencoders.com that has several DNS lookup components that makes it a very slow website. Please check the following image for a better understanding: If you really have to serve some JavaScript files at the head section, make sure that they come from the same host where you are trying to display the page, else put it at the bottom to avoid latency because almost all browsers block other downloads while rendering JavaScript files are being downloaded fully and get executed. Modern browsers support DNS prefetching. If it's absolutely necessary for developers to load resources from other domains, he/she should make use of it. The following are the URLs: https://developer.mozilla.org/en/docs/Controlling_DNS_prefetching http://www.chromium.org/developers/design-documents/dns-prefetching Using combined files: If we reduce the number of JavaScript files to be parsed and executed and if we do the same for CSS files, it will reduce HTTP requests and load the website much faster. We can do so, by combining all JavaScript files into one file and all CSS files into one CSS file. Setting up CSS sprites: There are two ways to combine different images into one to reduce the number of HTTP requests. One is using the image map technique and other is using CSS sprites. What we do in a CSS sprite is that we write CSS code for the image going to be used so that while hovering, clicking, or performing any action related to that image would invoke the correct action similar to the one with having different images for different actions. It's just a game of coordinates and a little creativity with design. It will make the website at least 50 percent faster as compared to the one with a lot of images. Using image maps: Use the image map idea if you are going to have a constant layout for those images such as menu items and a navigational part. The only drawback with this technique is that it requires a lot of hard work and you should be a good HTML programmer at the least. However, writing mapping code for a larger image with proper coordinates is not an easy task, but there are saviors out there. If you want to know the basics of the area and map tags, you can check out the Basics on area and map tag in HTML post I wrote at http://www.aliencoders.com/content/basics-area-and-map-tag-html. You can create an image map code for your image online at http://www.maschek.hu/imagemap/imgmap. If you want to make it more creative with different sets of actions and colors, try using CSS codes for image maps.. The following screenshot shows you all the options that you can play with while reducing DNS lookups: How it works… In the case of reducing DNS lookup, when you open any web page for the first time, it performs DNS lookups through all unique hostnames that are involved with that web page. When you hit a URL in your browser, it first needs to resolve the address (DNS name) to an IP address. As we know, DNS resolutions are being cached by the browser or the operating system or both. So, if a valid record for the URL is available in the user's browser or OS cache, there is no time delay observed. All ISPs have their own DNS servers that cache name-IP mappings from authoritative name servers and if the caching DNS server's record has already expired, it should be refreshed again. We will not go much deeper into the DNS mechanism. But it's important to reduce DNS lookups more than any other kind of requests because it will add a more prolonged latency period as any other requests do. Similarly, in the case of using image maps, imagine you have a website where you have inserted separate images for separate tabular menus instead of just plain text to make the website catchier! For example, Home, Blogs, Forums, Contact Us, and About Us. Now whenever you load the page, it sends five requests, which will surely consume some amount of time and will make the website a bit slower too. It will be a good idea to merge all such images into one big image and use the image map technique to reduce the number of HTTP requests for those images. We can do it by using area and map tags to make it work like the previous one. It will not only save a few KBs, but also reduce the server request from five to just one. There's more... If you already have map tags in your page and wish to edit it for proper coordinates without creating trouble for yourself, there is a Firefox add-on available called the Image Map Editor (https://addons.mozilla.org/en-us/firefox/addon/ime/). If you want to know the IP address of your name servers, use the $ grepnameserver /etc/resolv.conf command in Linux and C:/>ipconfig /all in Windows. Even you can get the website's details from your name server, that is, host website-name <nameserver>. There is a Firefox add-on that will speed up DNS resolution by doing pre-DNS work and you will observe faster loading of the website. Download Speed DNS from https://addons.mozilla.org/en-US/firefox/addon/speed-dns/?src=search. Summary We saw that lesser the number of requests, faster the website will be. This article showed us how to minimize such HTTP requests without hampering the website. Resources for Article: Further resources on this subject: Magento Performance Optimization [Article] Creating and optimizing your first Retina image [Article] Search Engine Optimization using Sitemaps in Drupal 6 [Article]
Read more
  • 0
  • 0
  • 3839

article-image-understanding-cython
Packt
07 Oct 2013
8 min read
Save for later

Understanding Cython

Packt
07 Oct 2013
8 min read
If you were to create an API for Python, you should write it using Cython to create a more type-safe Python API. Or, you could take the C types from Cython to implement the same algorithms in your Python code, and they will be faster because you're specifying the types and you avoid a lot of the type conversion required. Consider you are implementing a fresh project in C. There are a few issues we always come across in starting fresh; for example, choosing the logging or configuration system we will use or implement. With Cython, we can reuse the Python logging system as well as the ConfigParser standard libraries from Python in our C code to get a head start. If this doesn't prove to be the correct solution, we can chop and change easily. We can even extend and get Python to handle all usage. Since the Python API is very powerful, we might as well make Python do as much as it can to get us off the ground. Another question is do we want Python be our "driver" (main entry function) or do we want to handle this from our C code? Cython cdef In the next two examples, I will demonstrate how we can reuse the Python logging and Python ConfigParser modules directly from C code. But there are a few formalities to get over first, namely the Python initialization API and the link load model for fully embedded Python applications for using the shared library method. It's very simple to embed Python within a C/C++ application; you will require the following boilerplate: #include <Python.h>int main (int argc, char ** argv){Py_SetProgramName (argv [0]);Py_Initialize ();/* Do all your stuff in side here...*/Py_Finalize ();return 0;} Make sure you always put the Python.h header at the very beginning of each C file, because Python contains a lot of headers defined for system headers to turn things on and off to make things behave correctly on your system. Later, I will introduce some important concepts about the GIL that you should know and the relevant Python API code you will need to use from time to time. But for now, these few calls will be enough for you to get off the ground. Linking models Linking models are extremely important when considering how we can extend or embed things in native applications. There are two main linking models for Cython: fully embedded Python and code, which looks like the following figure: This demonstrates a fully embedded Python application where the Python runtime is linked into the final binary. This means we already have the Python runtime, whereas before we had to run the Python interpreter to call into our Cython module. There is also a Python shared object module as shown in the following figure: We have now fully modularized Python. This would be a more Pythonic approach to Cython, and if your code base is mostly Python, this is the approach you should take if you simply want to have a native module to call into some native code, as this lends your code to be more dynamic and reusable. The public keyword Moving on from linking models, we should next look at the public keyword, which allows Cython to generate a C/C++ header file that we can include with the prototypes to call directly into Python code from C. The main caveat if you're going to call Python public declarations directly from C is if your link model is fully embedded and linked against libpython.so; you need to use the boilerplate code as shown in the previous section. And before calling anything with the function, you need to initialize the Python module example if you have a cythonfile.pyx file and compile it with public declarations such as the following: cdef public void cythonFunction ():print "inside cython function!!!" You will not only get a cythonfile.c file but also cythonfile.h; this declares a function called extern void initcythonfile (void). So, before calling anything to do with the Cython code, use the following: /* Boiler plate init Python */Py_SetProgramName (argv [0]);Py_Initialize ();/* Init our config module into Python memory */initpublicTest ();cythonFunction ();/* cleanup python before exit ... */Py_Finalize (); Calling initcythonfile can be considered as the following in Python: import cythonfile Just like the previous examples, this only affects you if you're generating a fully embedded Python binary. Logging into Python A good example of Cython's abilities in my opinion is reusing the Python logging module directly from C. So, for example, we want a few macros we can rely on, such as info (…) that can handle VA_ARGS and feels as if we are calling a simple printf method. I think that after this example, you should start to see how things might work when mixing C and Python now that the cdef and public keywords start to bring things to life: import loggingcdef public void initLogging (char * logfile):logging.basicConfig (filename = logfile,level = logging.DEBUG,format = '%(levelname)s %(asctime)s:%(message)s',datefmt = '%m/%d/%Y %I:%M:%S')cdef public void pyinfo (char * message):logging.info (message)cdef public void pydebug (char * message):logging.debug (message)cdef public void pyerror (char * message):logging.error (message) This could serve as a simple wrapper for calling directly into the Python logger, but we can make this even more awesome in our C code with C99 __VA_ARGS__ and an attribute that is similar to GCC printf. This will make it look and work just like any function that is similar to printf. We can define some headers to wrap our calls to this in C as follows: #ifndef __MAIN_H__#define __MAIN_H__#include <Python.h>#include <stdio.h>#include <stdarg.h>#define printflike __attribute__ ((format (printf, 3, 4)))extern void printflike cinfo (const char *, unsigned, const char *,...);extern void printflike cdebug (const char *, unsigned, const char *,...);extern void printflike cerror (const char *, unsigned, const char *,...);#define info(...) cinfo (__FILE__, __LINE__, __VA_ARGS__)#define error(...) cerror (__FILE__, __LINE__, __VA_ARGS__)#define debug(...) cdebug (__FILE__, __LINE__, __VA_ARGS__)#include "logger.h" // remember to import our cython public's#endif //__MAIN_H__ Now we have these macros calling cinfo and the rest, and we can see the file and line number where we call these logging functions: void cdebug (const char * file, unsigned line,const char * fmt, ...){char buffer [256];va_list args;va_start (args, fmt);vsprintf (buffer, fmt, args);va_end (args);char buf [512];snprintf (buf, sizeof (buf), "%s-%i -> %s",file, line, buffer);pydebug (buf);} On calling debug ("debug message"), we see the following output: Philips-MacBook:cpy-logging redbrain$ ./example log Philips-MacBook:cpy-logging redbrain$ cat log INFO 05/06/2013 12:28:24: main.c-62 -> info message DEBUG 05/06/2013 12:28:24: main.c-63 -> debug messageERROR 05/06/2013 12:28:24: main.c-64 -> error message Also, you should note that we import and do everything we would do in Python as we would in here, so don't be afraid to make lists or classes and use these to help out. Remember if you had a Cython module with public declarations calling into the logging module, this integrates your applications as if it were one. More importantly, you only need all of this boilerplate when you fully embed Python, not when you compile your module to a shared library. Python ConfigParser Another useful case is to make Python's ConfigParser accessible in some way from C; ideally, all we really want is to have a function to which we pass the path to a config file to receive a STATUS OK/FAIL message and a filled buffer of the configuration that we need: from ConfigParser import SafeConfigParser, NoSectionErrorcdef extern from "main.h":struct config:char * pathint numbercdef config myconfig Here, we've Cythoned our struct and declared an instance on the stack for easier management: cdef public config * parseConfig (char * cfg):# initialize the global stack variable for our config...myconfig.path = NULLmyconfig.number = 0# buffers for assigning python types into C typescdef char * path = NULLcdef number = 0parser = SafeConfigParser ()try:parser.readfp (open (cfg))pynumber = int (parser.get ("example", "number"))pypath = parser.get ("example", "path")except NoSectionError:print "No section named example"return NULLexcept IOError:print "no such file ", cfgreturn NULLfinally:myconfig.number = pynumbermyconfig.path = pypathreturn &myconfig This is a fairly trivial piece of Cython code that will return NULL on error as well as the pointer to the struct containing the configuration: Philips-MacBook:cpy-configparser redbrain$ ./example sample.cfgcfg->path = some/path/to/somethingcfg-number = 15 As you can see, we easily parsed a config file without using any C code. I always found figuring out how I was going to parse config files in C to be a nightmare. I usually ended up writing my own mini domain-specific language using Flex and Bison as a parser as well as my own middle-end, which is just too involved.
Read more
  • 0
  • 0
  • 6273
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-introducing-feature-introjs
Packt
07 Oct 2013
5 min read
Save for later

Introducing a feature of IntroJs

Packt
07 Oct 2013
5 min read
(For more resources related to this topic, see here.) API IntroJs includes functions that let the user to control and change the execution of the introduction. For example, it is possible to make a decision for an unexpected event that happens during execution, or to change the introduction routine according to user interactions. Later on, all available APIs in IntroJs will be explained. However, these functions will extend and develop in the future. IntroJs includes these API functions: start goToStep exit setOption setOptions oncomplete onexit onchange onbeforechange introJs.start() As mentioned before, introJs.start() is the main function of IntroJs that lets the user to start the introduction for specified elements and get an instance of the introJS class. The introduction will start from the first step in specified elements. This function has no arguments and also returns an instance of the introJS class. introJs.goToStep(stepNo) Jump to the specific step of the introduction by using this function. As it is clear, introductions always start from the first step; however, it is possible to change the configuration by using this function. The goToStep function has an integer argument that accepts the number of the step in the introduction. introJs().goToStep(2).start(); //starts introduction from step 2 As the example indicates, first, the default configuration changed by using the goToStep function from 1 to 2, and then the start() function will be called. Hence, the introduction will start from the second step. Finally, this function will return the introJS class's instance. introJs.exit() The introJS.exit() function lets the user exit and close the running introduction. By default, the introduction ends when the user clicks on the Done button or goes to the last step of the introduction. introJs().exit() As it shows, the exit() function doesn't have any arguments and returns an instance of introJS. introJs.setOption(option, value) As mentioned before, IntroJs has some default options that can be changed by using the setOption method. This function has two arguments. The first one is useful to specify the option name and the second one is to set the value. introJs().setOption("nextLabel", "Go Next"); In the preceding example, nextLabel sets to Go Next. Also, it is possible to change other options by using the setOption method. introJs.setOptions(options) It is possible to change an option using the setOption method. However, to change more than one option at once, it is possible to use setOptions instead. The setOptions method accepts different options and values in the JSON format. introJs().setOptions({ skipLabel: "Exit", tooltipPosition: "right" }); In the preceding example, two options are set at the same time by using JSON and the setOptions method. introJs.oncomplete(providedCallback) The oncomplete event is raised when the introduction ends. If a function passes as an oncomplete method, it will be called by the library after the introduction ends. introJs().oncomplete(function() { alert("end of introduction"); }); In this example, after the introduction ends, the anonymous function that is passed to the oncomplete method will be called and alerted with the end of introduction message. introJs.onexit(providedCallback) As mentioned before, the user can exit the running introduction using the Esc key or by clicking on the dark area in the introduction. The onexit event notices when the user exits from the introduction. This function accepts one argument and returns the instance of running introJS. introJs().onexit(function() { alert("exit of introduction"); }); In the preceding example, we passed an anonymous function to the onexit method with an alert() statement. If the user exits the introduction, the anonymous function will be called and an alert with the message exit of introduction will appear. introJs.onchange(providedCallback) The onchange event is raised in each step of the introduction. This method is useful to inform when each step of introduction is completed. introJs().onchange(function(targetElement) { alert("new step"); }); You can define an argument for an anonymous function (targetElement in the preceding example), and when the function is called, you can access the current target element that is highlighted in the introduction with that argument. In the preceding example, when each introduction's step ends, an alert with the new step message will appear. introJs.onbeforechange(providedCallback) Sometimes, you may need to do something before each step of introduction. Consider that you need to do an Ajax call before the user goes to a step of the introduction; you can do this with the onbeforechange event. introJs().onbeforechange(function(targetElement) { alert("before new step");}); We can also define an argument for an anonymous function (targetElement in the preceding example), and when this function is called, the argument gets some information about the currently highlighted element in the introduction. So using that argument, you can know which step of the introduction will be highlighted or what's the type of target element and more. In the preceding example, an alert with the message before new step will appear before highlighting each step of the introduction. Summary In this article we learned about the API functions, their syntaxes, and how they are used. Resources for Article: Further resources on this subject: ASP.Net Site Performance: Improving JavaScript Loading [Article] Trapping Errors by Using Built-In Objects in JavaScript Testing [Article] Making a Better Form using JavaScript [Article]
Read more
  • 0
  • 0
  • 6039

article-image-planning-your-store
Packt
07 Oct 2013
11 min read
Save for later

Planning Your Store

Packt
07 Oct 2013
11 min read
Defining the catalogue The type of products you are selling will determine the structure of your store. Different types of products will have different requirements in terms of the information presented to the customer, and the data that you will need to collect in order to fulfill an order. Base product definition Every product needs to have the following fields which are added by default: Title Stock Keeping Unit (SKU) Price (in the default store currency) Status (a flag indicating if the product is live on the store) This is the minimum you need to define a product in Drupal Commerce—everything else is customized for your store. You can define multiple Product Types (Product Entity Bundles), which can contain different fields depending on your requirements. Physical products If you are dealing with physical products, such as books, CDs, or widgets, you may want to consider these additional fields: Product images Description Size Weight Artist/Designer/Author Color You may want to consider setting up multiple Product Types for your store. For example, if you are selling CDs, you may want to have a field for Artist which would not be relevant for a T-shirt (where designer may be a more appropriate field). Whenever you imagine having distinct pieces of data available, adding them as individual fields is well worth doing at the planning stage so that you can use them for detailed searching and filtering later. Digital downloads If you are selling a digital product such as music or e-books, you will need additional fields to contain the actual downloadable file. You may also want to consider including: Cover image Description Author/Artist Publication date Permitted number of downloads Tickets Selling tickets is a slightly more complex scenario since there is usually a related event associated with the product. You may want to consider including: Related event (which would include date, venue, and so on) Ticket Type / Level / Seat Type Content access and subscriptions Selling content access and subscriptions through Drupal Commerce usually requires associating the product with a Drupal role. The customer is buying membership of the role which in turn allows them to see content that would usually be restricted. You may want to consider including: Associated role(s) Duration of membership Initial cost (for example, first month free) Renewal cost (for example, £10/month ) Customizing products The next consideration is whether products can be customized at the point of purchase. Some common examples of this are: Specifying size Specifying color Adding a personal message (for example, embossing) Selecting a specific seat (in the event example) Selecting a subscription duration Specifying language version of an e-book Gift wrapping or gift messaging It is important to understand what additional user input you will need from the customer to fulfill the order over and above the SKU and quantity. When looking at these options, also consider whether the price changes depending on the options that the customer selects. For example: Larger sizes cost more than smaller sizes Premium for "red" color choice Extra cost for adding an embossed message Different pricing for different seating levels Monthly subscription is cheaper if you commit to a longer duration Classifying products Now that you have defined your Product Types, the next step is to consider the classification of products using Drupal's in-built Taxonomy system. A basic store will usually have a catalog taxonomy vocabulary where you can allocate a product to one or more catalog sections, such as books, CDs, clothing, and so on. The taxonomy can also be hierarchical, however, individual vocabularies for the classification of your products is often more workable, especially when providing the customer with a faceted search or filtering facility later. The following are examples of common taxonomy vocabulary: Author/Artist/Designer Color Size Genre Manufacturer/Brand It is considered best practice to define a taxonomy vocabulary rather than have a simple free text field. This provides consistency during data entry. For example, a free text field for size may end up being populated with S, Small, Sm, all meaning the same thing. A dropdown taxonomy selector would ensure that the value entered was the same for every product. Do not be tempted to use List type fields to provide dropdown menus of choices. List fields are necessarily the reserve of the developer and using them excludes the less technical site owner or administrator from managing them. Pricing Drupal Commerce has a powerful pricing engine, which calculates the actual selling price for the customer, depending on one or more predefined rules. This gives enormous flexibility in planning your pricing strategy. Currency Drupal Commerce allows you to specify a default currency for the store, but also allows you to enter multiple price fields or calculate a different price based on other criteria, such as the preferred currency of the customer. If you are going to offer multiple currencies, you need to consider how the currency exchange will work; do you want to enter a set price for each product and currency you offer, or a base price in the default currency and calculate the other currencies based on a conversion rate? If you use a conversion rate, how often is it updated? Variable pricing Prices do not have to be fixed. Consider scenarios where the prices for your store will vary over time, or situations based on other factors such as volume-based discounts. Will some preferred customers get a special price deal on one or more products? Customers You cannot complete an order without a customer and it is important to consider all of their needs during the planning process. By default, a customer profile in Drupal Commerce contains an address type field which works to the Name and Address Standard (xNAL) format, collecting international addresses in a standard way. However, you may want to extend this profile type to collect more information about the customer. For example: Telephone number Delivery instructions E-mail opt-in permission Do any of the following apply? Is the store open to public or open by invitation only? Do customers have to register before they can purchase? Do customers have to enter an e-mail address in order to purchase? Is there a geographical limit to where products can be sold/shipped? Can a customer access their account online? Can a customer cancel an order once it is placed? What are the time limits on this? Can a customer track the progress of their order? Taxes Many stores are subject to Sales tax or Value Added Tax(VAT) on products sold. However, these taxes often vary depending on the type of product sold and the final destination of the physical goods. During your planning you should consider the following: What are the sales tax / VAT rules for the store? Are there different tax rules depending on the shipping destination? Are there different tax rules depending on the type of product? If you are in a situation where different types of products in your store will incur different rates of taxes, then it is a very good idea to set up different Product Types so that it's easy to distinguish between them. For example, in the UK, physical books are zero rated for VAT, whereas, the same book in digital format will have 20% VAT added. Payments Drupal Commerce can connect to many different payment gateways in order create a transaction for an order. While many of the popular payment gateways, such as PayPal and Sage Pay, have fully functional payment gateway modules on Drupal.org, it's worth checking if the one you want is available because creating a new one is no small undertaking. The following should also be considered: Is there a minimum spend limit? Will there be multiple payment options? Are there surcharges for certain payment types? Will there be account customers that do not have to enter a payment card? How will a customer be refunded if they cancel or return their order? Shipping Not every product will require shipping support, but for physical products, shipping can be a complex area. Even a simple product store can have complex shipping costs based on factors such as weight, destination, total spend, and special offers. Ensure the following points are considered during your planning: Is shipping required? How is the cost calculated? By value/weight/destination? Are there geographical restrictions? Is express delivery an option? Can the customer track their order? Stock With physical products and some virtual products such as event tickets, stock control may be a requirement. Stock control is a complex area and beyond the scope of this book, but the following questions will help uncover the requirements: Are stock levels managed in another system, for example, MRP? If the business has other sales channels, is there dedicated stock for the online store? When should stock levels be updated (at the point of adding to the cart or at the point of completing the order)? How long should stock be reserved? What happens when a product is out of stock? Can a customer order an out-of-stock product (back order)? What happens if a product goes out of stock during the customer checkout process? If stock is controlled by an external system, how often should stock levels be updated in the e-store? Legal compliance It is important to understand the legal requirements of the country where you operate your store. It is beyond the scope of this book to detail the legal requirements of every country, but some examples of e-commerce regulation that you should research and understand are included here: PCI-DSS Compliance—Worldwide The Privacy and Electronic Communications (EC Directive) (also known as the EU cookie law)—European Union Distance Selling Regulations—UK Customer communication Once the customer has placed their order, how much communication will there be? A standard expectation of the customer will be to receive a notification that their order has been placed, but how much information should that e-mail contain? Should the e-mail be plain text or graphical? Does the customer receive an additional e-mail when the order is shipped? If the product has a long lead time, should the customer receive interim updates? What communication should take place if a customer cancels their order? Back office In order for the store to run efficiently, it is important to consider the requirements of the back office system. This will often be managed by a different group of people to those specifying the e-store. Identify the different types of users involved in the order fulfillment process. These roles may include: Sales order processing Warehouse and order handling Customer service for order enquiries Product managers These roles may all have different information available to them when trying to locate the order or product they need, so it's important for the interface to cater to different scenarios: Does the website need to integrate with a third-party system for management of orders? How are order status codes updated on the website so that customers can track progress? In a batch, manually or automatically? User experience How will the customer find the product that they are looking for? Well-structured navigation? Search by SKU? Free text search? Faceted search? The source of product data When you are creating a store with more than a trivial number of products, you will probably want to work on a method of mass importing the product data. Find out where the product data will be coming from, and in what format it will be delivered. You may want to define your Product Types taking into account the format of the data coming in—especially if the incoming data format is fixed. You may also want to define different methods of importing taxonomy terms from the supplied data. Summary Once you have gone through all of these checklists with the business stakeholders, you should have enough information to start your Drupal Commerce build. Drupal Commerce is very flexible, but it is crucial that you understand the outcome that you are trying to achieve before you start installing modules and setting up Product Types. Resources for Article: Further resources on this subject: Drupal Web Services: Twitter and Drupal [Article] Introduction to Drupal Web ServicesIntroduction to Drupal Web Services [Article] Drupal Site Configuration: Performance, Maintenance, Logging and Errors and Reports [Article]
Read more
  • 0
  • 0
  • 1799

article-image-new-way-scale
Packt
07 Oct 2013
8 min read
Save for later

A New Way to Scale

Packt
07 Oct 2013
8 min read
(For more resources related to this topic, see here.) High-level OpsWorks As you may have guessed from the title, this article is about AWS OpsWorks and how it can be put to practical use so that web applications can scale with minimal effort. OpsWorks is a Chef Framework solution for application and infrastructure management. Using AWS OpsWorks, DevOps teams can systematically manage, deploy, and scale global infrastructures and applications faster, and with much less effort in comparison to previously used methods. OpsWorks is one of the many services provided by Amazon Web Services (AWS). The thing that stands out about OpsWorks is that it allows you to bootstrap complete environments that contain other AWS services. For example, with OpsWorks, AWS services such as EC2, ELB, EBS, Elastic IP, Security Groups, Route 53, CloudWatch, and IAM can all play a part in its configuration. Managing the configuration of several services at once and in advance provides for automated deployment of applications and the infrastructure that supports them. Accessing OpsWorks involves having an AWS account, then navigating to it using the AWS Management Console by going to Deployment & Management | OpsWorks as shown in the following screenshot: To date, OpsWorks has four defining areas which all work together in providing configuration management for scaling web applications. These areas are briefly defined in the following paragraphs. Stacks At the highest level, OpsWorks uses something called stacks. There are many possible uses for this high-level item, and one such use could be as a stage within a multistage environment (think test, staging, production, and so on.); a single stack could represent the staging environment. In the example of a stack called staging, the stack would serve as a container, which includes configuration settings for enabling layers, instances, and apps. Layers The second level of OpsWorks is called layers. A layer is a blueprint for EC2 instances, EBS volumes, load balancers and so on, which function in a specific way. Layers define which packages and applications are installed, and how they are configured. An example of a layer is a Rails app server. The Rails app server includes configuration items such as the Ruby version, (which Rails stack to use), the RubyGems version, and whether or not to manage a particular version of Bundler. Instances At the third tier, OpsWorks provides a method for launching and managing instances. Instances are the EC2 instances that serve applications and data, balance traffic, and so on, in accordance to the configuration of their parent layer. As instances are launched, they will show up in the EC2 section of the AWS Management Console. Apps At the fourth level of OpsWorks are the apps. An app is application code that you want to run on an instance. Apps hold configuration information, which is required to deploy application code to application server instances. With an app, you define what code base it is (PHP), where it resides (GitHub), and what domain names it should be associated with. The origin of OpsWorks AWS OpsWorks wasn't always a part of AWS. Actually, OpsWorks was originally a product called Scalarium, which was created in July 2008 by Berlin-based startup Peritor. AWS acquired Peritor in 2012, which then launched a modified version of Scalarium called OpsWorks in February 2013. AWS then discontinued Scalarium in August 2013, while providing a migration path for its existing customers up until that point. Founders of Peritor Scalarium included Thomas Metschke, Jonathan Weiss, and Mathias Meyer. AWS recognized that Scalarium had strong capabilities that were broadly useful to AWS customers, and they've done an excellent job to date in transitioning and building upon the new service. As AWS continues to rapidly deploy new services and features, one can only assume that OpsWorks will eventually be tied into the majority of them. The importance of OpsWorks So, you might still be asking yourself how and why OpsWorks is important anyway. Good question! OpsWorks is important for several reasons. First, OpsWorks is a service native to AWS and because of this, it works seamlessly with other AWS services that it supports. Status information and callback response with services such as EC2, ELB, EIP, CloudWatch and so on, are updated in real time. This means that as changes are initiated to infrastructure, callbacks to the OpsWorks console happen immediately so that users don't have to wait for status updates prior to moving forward with other changes or additions. Secondly, OpsWorks provides the ability to create full stacks, which can then be cloned into other stacks. This is extremely efficient for infrastructure development. For example, it allows individuals in a DevOps role to build a complete staging stack that includes layers and instances which are configured using Chef, then clone it to production, and then with the click of a button, bring an entire production environment, including applications, online within minutes. Another very important aspect of OpsWorks is auto scaling. Auto scaling allows you to scale EC2 capacity up or down automatically according to predefined conditions. With auto scaling, it's possible to ensure that the number of Amazon EC2 instances you're using increases seamlessly during demand spikes to maintain performance, and decreases automatically during demand lulls to minimize costs. Auto scaling is particularly well-suited to applications that experience hourly, daily, or weekly variability in usage. With OpsWorks, there are two distinct auto scaling options: time-based and load-based. This practically allows any flexibility with auto scaling that a DevOps team might require in meeting the demands of a rapidly growing business. One other important feature of OpsWorks is application deployment. OpsWorks can be configured to automatically deploy application code from source code repositories hosted in Git and Subversion repositories, as well as S3 and HTTP archives. Members of a DevOps team can update code in a repository or archive, and then deploy the updates simultaneously across all application servers with the click of a button. This is a very powerful feature that solves the problem of maintaining code version consistency across servers. The role of DevOps DevOps...that term that is being thrown around these days. DevOps, a portmanteau of Development and Operations, is typically a software development methodology that stresses communication, collaboration, and integration between Development, Technology Operations, and Quality Assurance. There are varying ways of how this method is implemented, and in the case of AWS OpsWorks, DevOps refers to a team of individuals that has experience with all three facets of the business at hand. The following figure is an illustration of how the DevOps method is ideally situated: In this scenario, a DevOps team communicates with Developers and Quality Assurance to ensure that application code is ready to be released to the servers that support it. DevOps can then deploy the code using the OpsWorks deployment features. DevOps also plays a role in communicating with Operations to ensure that the infrastructure in question effectively supports the application code that Developers are working on. OpsWorks for the startup Internet startups that are looking toward rapid growth and scaling should consider OpsWorks as the platform for their applications. With OpsWorks, businesses including startups can look forward to the following for powering and protecting their infrastructure and applications: Bootstrapped learning through familiarity with AWS Tight integration with other Amazon Web Services The ability to easily build and deploy distinct system environments, that is; test, staging, and production Fine grained control over infrastructure Infrastructure auto scaling Automatic deployment of application code across many servers Disaster recovery through intelligent architecture and auto healing As you can see, any organization including Internet startups that are looking to effectively deploy, manage, and scale their infrastructure and application code will benefit from the use of OpsWorks. As the two worlds of System Engineers and Developers continue to meld, services like OpsWorks will become increasingly prevalent. For any other requirements that don't involve the previously mentioned elements, simply using the EC2 console for launching and managing individual EC2 instances, EBS volumes, EIPs, and so on will suffice. Summary In this article, we learned that OpsWorks is a tool that was designed by a third-party company with the goal of making it easier to both integrate and scale AWS services using Chef. AWS recognized this tool as a bit of a game changer, and then acquired the technology so that they could bring even tighter integration with native services to allow a DevOps team the ability to configure, deploy, manage, and scale infrastructure and applications easily using the AWS cloud. Resources for Article: Further resources on this subject: Features of CloudFlare [Article] Introduction to Cloud Computing with Microsoft Azure [Article] Troubleshooting in OpenStack Cloud Computing [Article]
Read more
  • 0
  • 0
  • 1632

article-image-developing-reports-using-rdp-and-report-contracts
Packt
07 Oct 2013
4 min read
Save for later

Developing Reports Using RDP and Report Contracts

Packt
07 Oct 2013
4 min read
(For more resources related to this topic, see here.) The Report data provider class A Report data provider class is commonly known as RDP. RDP is the data source type which is available when we add a new dataset to the report in Visual Studio. RDP is a class which resides inside AX and executes the business logic, processes the data, and returns a dataset which is rendered in the report. A Report data provider class should be ideally used in the following cases: We cannot directly use a query to access the data from the database The data has to prepare on the basis of business logic To define a Report data provider class, we use the following syntax: Sample RDP The Report contract class Report contracts in AX 2012 are used for defining parameters to the SSRS report. We can define any number of parameters using X++ statements of any data type, which can be passed on to the RDP class. And then, we can use the same contracts to query data from the database engine which will decrease an overhead on execution of a query in SQL. To define a Report contract class we use the following syntax: Report Contract Walkthrough – Creating an Auto Design report using the RDP class Scenario Matt, a Sales manager, needs a report to analyze total sales for customers. This walkthrough illustrates the following tasks: Creating a Report data provider class Creating a Report Model project Creating a Table report using Auto Design Saving to AOT, deploying, and running the report Prerequisites To learn and implement the following walkthrough, you must have: Microsoft Dynamics AX 2012 with sample data Microsoft Visual Studio 2010 with Microsoft Dynamics AX reporting extension Microsoft Dynamics AX 2012 SQL Server Reporting Services Creating a Report data provider class Open Microsoft Dynamics AX 2012 from the Start menu. Open the development workspace. You can do it in either of the following ways: Press Ctrl + D to open AOT in Development Workspace. Press Ctrl + Shift + P to open Projects in Development Workspace. Press Alt + W to open windows and select New Development Workspace. Press Ctrl + Shift + W to open New Development Workspace. Navigate to the AOT | Classes node. Right-click on the Classes node, and click on New | Class. Double-click on the class created and change the class declaration, as shown in the following code: class SrsRDPSample extends SRSReportDataProviderBase{ CustTransTotalSales custTransTotalSales; } Right-click on the SrsRDPSample class and select New | Method. Modify the method, as shown in the following code: [SRSReportDataSetAttribute('CustSales')] public CustTransTotalSales getTmpCustTable(){ return custTransTotalSales; } Right-click on the SrsRDPSample class and navigate to Override method | processReport. Modify the method, as shown in the following code: public void processReport(){ select * from custTransTotalSales; } Creating a Report Model project Start Visual Studio and press Ctrl + N to create a new project. Select Microsoft Dynamics AX under Installed Templates from the left pane, and select Report Model. Provide a name for the project as CustomerTotalSales_Autodesign. New project Creating a Table report using Auto Design Right-click on Solution, select Report under the Add submenu. Select the report and rename it to CustTotalSales_Autodesign. Right-click on Datasets and click on Add dataset. Modify the following properties for the newly added dataset: Data source to Microsoft Dynamics AX. Data source type to Query. Default Layout to Matrix. Name to CustTotalSalesDS. Switch to the Query property, and click on the button besides the name of the entity button to open the Query dialog. Select SrsRDPSample from the list and click on the Next button. New dataset: CustTotalSalesDS Select all fields from CustSales. Drag-and-drop CustTotalSalesDS to the Design section of the report. This will create a new Auto Design named as AutoDesign1. Select AutoDesign1, go to Properties, and set the following properties: LayoutTemplate to ReportLayoutStyleTemplate Title to Customer sales. Select CustTotalSalesDS under AutoDesign1, and set the following properties: StyleTemplate to TableStyleAlternatingRowsTemplate. Title to Customer sales. Drag the AccountNum field from the Data node to Groupings. Drag the TransDate field to the Sorting node. Under the Data node, select only the TransDate, AmountMST, CurrencyCode, DocumentDate, DueDate, LastSettleDate, PaymMode, and TransType1 fields. Report design Saving to AOT, deploying, and running the report Save the report to AOT and Deploy to the Report Server, and then run the report. Summary In this article we covered Report data provider (RDP) class and Report contract class. We also learned how to implement these classes for our reporting needs. We learned creating an Auto Design report using the RDP class by following the step-by-step walkthrough. Resources for Article: Further resources on this subject: Testing Workflows for Microsoft Dynamics AX 2009 Administration [Article] Types of services in Microsoft Dynamics AX 2012 [Article] Installing the Dynamics AX Base Server Components for Microsoft [Article]
Read more
  • 0
  • 0
  • 7135
article-image-dependency-management-sbt
Packt
07 Oct 2013
17 min read
Save for later

Dependency Management in SBT

Packt
07 Oct 2013
17 min read
(For more resources related to this topic, see here.) In the early days of Java, when projects were small and didn't have many external dependencies, developers tended to manage dependencies manually by copying the required JAR files in the lib folder and checking it in their SCM/VCS with their code. This is still followed by a lot of developers, even today. But due to the aforementioned issues, this is not an option for larger projects. In many enterprises, there are central servers, FTP, shared drives, and so on, which store the approved libraries for use and also internally released libraries. But managing and tracking them manually is never easy. They end up relying on scripts and build files. Maven came and standardized this process. Maven defines standards for the project format to define its dependencies, formats for repositories to store libraries, the automated process to fetch transitive dependencies, and much more. Most of the systems today either back onto Maven's dependency management system or on Ivy's, which can function in the same way, and also provides its own standards, which is heavily inspired by Maven. SBT uses Ivy in the backend for dependency management, but uses a custom DSL to specify the dependency. Quick introduction to Maven or Ivy dependency management Apache Maven is not a dependency management tool. It is a project management and a comprehension tool. Maven is configured using a Project Object Model (POM), which is represented in an XML file. A POM has all the details related to the project right from the basic ones, such as groupId, artifactId, version, and so on, to environment settings such as prerequisites, and repositories. Apache Ivy is a dependency management tool and a subproject of Apache Ant. Ivy integrates publicly available artifact repositories automatically. The project dependencies are declared using XML in a file called ivy.xml. This is commonly known as the Ivy file. Ivy is configured using a settings file. The settings file (ivysettings.xml) defines a set of dependency resolvers. Each resolver points to an Ivy file and/or artifacts. So, the configuration essentially indicates which resource should be used to resolve a module. How Ivy works The following diagram depicts the usual cycle of Ivy modules between different locations: The tags along the arrows are the Ivy commands that need to be run for that task, which are explained in detail in the following sections. Resolve Resolve is the phase where Ivy resolves the dependencies of a module by accessing the Ivy file defined for that module. For each dependency in the Ivy file, Ivy finds the module using the configuration. A module could be an Ivy file or artifact. Once a module is found, its Ivy file is downloaded to the Ivy cache. Then, Ivy checks for the dependencies of that module. If the module has dependencies on other modules, Ivy recursively traverses the graph of dependencies, handling conflicts simultaneously. After traversing the whole graph, Ivy downloads all the dependencies that are not already in the cache and have not been evicted by conflict management. Ivy uses a filesystem-based cache to avoid loading dependencies already available in the cache. In the end, an XML report of the dependencies of the module is generated in the cache. Retrieve Retrieve is the act of copying artifacts from the cache to another directory structure. The destination for the files to be copied is specified using a pattern. Before copying, Ivy checks if the files are not already copied to maximize performance. After dependencies have been copied, the build becomes independent of Ivy. Publish Ivy can then be used to publish the module to a repository. This can be done by manually running a task or from a continuous integration server. Dependency management in SBT In SBT, library dependencies can be managed in the following two ways: By specifying the libraries in the build definition By manually adding the JAR files of the library Manual addition of JAR files may seem simple in the beginning of a project. But as the project grows, it may depend on a lot of other projects, or the projects it depends on may have newer versions. These situations make handling dependencies manually a cumbersome task. Hence, most developers prefer to automate dependency management. Automatic dependency management SBT uses Apache Ivy to handle automatic dependency management. When dependencies are configured in this manner, SBT handles the retrieval and update of the dependencies. An update does not happen every time there is a change, since that slows down all the processes. To update the dependencies, you need to execute the update task. Other tasks depend on the output generated through the update. Whenever dependencies are modified, an update should be run for these changes to get reflected. There are three ways in which project dependencies can be specified. They are as follows: Declarations within the build definition Maven dependency files, that is, POM files Configuration and settings files used for Ivy Adding JAR files manually Declaring dependencies in the build definition The Setting key libraryDependencies is used to configure the dependencies of a project. The following are some of the possible syntaxes for libraryDependencies: libraryDependencies += groupID % artifactID % revision libraryDependencies += groupID %% artifactID % revision libraryDependencies += groupID % artifactID % revision % configuration libraryDependencies ++= Seq( groupID %% artifactID % revision, groupID %% otherID % otherRevision ) Let's explain some of these examples in more detail: groupID: This is the organization/group's ID by whom it was published artifactID: This is the project's name on which there is a dependency revision: This is the Ivy revision of the project on which there is a dependency configuration: This is the Ivy configuration for which we want to specify the dependency Notice that the first and second syntax are not the same. The second one has a %% symbol after groupID. This tells SBT to append the project's Scala version to artifactID. So, in a project with Scala Version 2.9.1, libraryDependencies ++= Seq("mysql" %% "mysql-connector-java" % "5.1.18") is equivalent to libraryDependencies ++= Seq("mysql" % "mysql-connector-java_2.9.1" % "5.1.18"). The %% symbol is very helpful for cross-building a project. Cross-building is the process of building a project for multiple Scala versions. SBT uses the crossScalaVersion key's value to configure dependencies for multiple versions of Scala. Cross-building is possible only for Scala Version 2.8.0 or higher. The %% symbol simply appends the current Scala version, so it should not be used when you know that there is no dependency for a given Scala version, although it is compatible with an older version. In such cases, you have to hardcode the version using the first syntax. Using the third syntax, we could add a dependency only for a specific configuration. This is very useful as some dependencies are not required by all configurations. For example, the dependency on a testing library is only for the test configuration. We could declare this as follows: libraryDependencies ++= Seq("org.specs2" % "specs2_2.9.1" % "1.12.3" % "test") We could also specify dependency for the provided scope (where the JDK or container provides the dependency at runtime).This scope is only available on compilation and test classpath, and is not transitive. Generally, servlet-api dependencies are declared in this scope: libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided" The revision does not have to be a single-fixed version, that is, it can be set with some constraints, and Ivy will select the one that matches best. For example, it could be latest integration or 12.0 or higher, or even a range of versions. A URL for the dependency JAR If the dependency is not published to a repository, you can also specify a direct URL to the JAR file: libraryDependencies += groupID %% artifactID % revision from directURL directURL is used only if the dependency cannot be found in the specified repositories and is not included in published metadata. For example: libraryDependencies += "slinky" % "slinky" % "2.1" from "http://slinky2.googlecode.com/svn/artifacts/2.1/slinky.jar" Extra attributes SBT also supports Ivy's extra attributes. To specify extra attributes, one could use the extra method. Consider that the project has a dependency on the following Ivy module: <ivy-module version ="2.0" > <info organization="packt" module = "introduction" e:media = "screen" status = "integration" e:codeWord = "PP1872"</ivy-module> A dependency on this can be declared by using the following: libraryDependencies += "packt" % "introduction" % "latest.integration" extra( "media"->"screen", "codeWord"-> "PP1872") The extra method can also be used to specify extra attributes for the current project, so that when it is published to the repository its Ivy file will also have extra attributes. An example for this is as follows: projectID << projectID {id => id extra( "codeWord"-> "PP1952")} Classifiers Classifiers ensure that the dependency being loaded is compatible with the platform for which the project is written. For example, to fetch the dependency relevant to JDK 1.5, use the following: libraryDependencies += "org.testng" % "testng" % "5.7" classifier "jdk15" We could also have multiple classifiers, as follows: libraryDependencies += "org.lwjgl.lwjgl" % "lwjgl-platform" % lwjglVersion classifier "natives-windows" classifier "natives-linux" classifier "natives-osx" Transitivity In logic and mathematics, a relationship between three elements is said to be transitive. If the relationship holds between the first and second elements and between the second and third elements, it implies that it also holds a relationship between the first and third elements. Relating this to the dependencies of a project, imagine that you have a project that depends on the project Foo for some of its functionality. Now, Foo depends on another project, Bar, for some of its functionality. If a change in the project Bar affects your project's functionality, then this implies that your project indirectly depends on project Bar. This means that your project has a transitive dependency on the project Bar. But if in this case a change in the project Bar does not affect your project's functionality, then your project does not depend on the project Bar. This means that your project does not have a dependency on the project Bar. SBT cannot know whether your project has a transitive dependency or not, so to avoid dependency issues, it loads the library dependencies transitively by default. In situations where this is not required for your project, you can disable it using intransitive() or notTransitive(). A common case where artifact dependencies are not required is in projects using the Felix OSGI framework (only its main JAR is required). The dependency can be declared as follows: libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" intransitive() Or, it can be declared as follows: libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" notTransitive() If we need to exclude certain transitive dependencies of a dependency, we could use the excludeAll or exclude method. libraryDependencies += "log4j" % "log4j" % "1.2.15" exclude("javax.jms", "jms")libraryDependencies += "log4j" % "log4j" % "1.2.15" excludeAll( ExclusionRule(organization = "com.sun.jdmk"), ExclusionRule(organization = "com.sun.jmx"), ExclusionRule(organization = "javax.jms") ) Although excludeAll provides more flexibility, it should not be used in projects that will be published in the Maven style as it cannot be represented in a pom.xml file. The exclude method is more useful in projects that require pom.xml when being published, since it requires both organizationID and name to exclude a module. Download documentation Generally, an IDE plugin is used to download the source and API documentation JAR files. However, one can configure SBT to download the documentation without using an IDE plugin. To download the dependency's sources, add withSources() to the dependency definition. For example: libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" withSources() To download API JAR files, add withJavaDoc() to the dependency definition. For example: libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" withSources() withJavadoc() The documentation downloaded like this is not transitive. You must use the update-classifiers task to do so. Dependencies using Maven files SBT can be configured to use a Maven POM file to handle the project dependencies by using the externalPom method. The following statements can be used in the build definition: externalPom(): This will set pom.xml in the project's base directory as the source for project dependencies externalPom(baseDirectory{base=>base/"myProjectPom"}): This will set the custom-named POM file myProjectPom.xml in the project's base directory as the source for project dependencies There are a few restrictions with using a POM file, as follows: It can be used only for configuring dependencies. The repositories mentioned in POM will not be considered. They need to be specified explicitly in the build definition or in an Ivy settings file. There is no support for relativePath in the parent element of POM and its existence will result in an error. Dependencies using Ivy files or Ivy XML Both Ivy settings and dependencies can be used to configure project dependencies in SBT through the build definition. They can either be loaded from a file or can be given inline in the build definition. The Ivy XML can be declared as follows: ivyXML := <dependencies> <dependency org="org.specs2" name="specs2" rev="1.12.3"></dependency></ dependencies> The commands to load from a file are as follows: externalIvySettings(): This will set ivysettings.xml in the project's base directory as the source for dependency settings. externalIvySettings(baseDirectory{base=>base/"myIvySettings"}): This will set the custom-named settings file myIvySettings.xml in the project's base directory as the source for dependency settings. externalIvySettingsURL(url("settingsURL")): This will set the settings file at settingsURL as the source for dependency settings. externalIvyFile(): This will set ivy.xml in the project's base directory as the source for dependency. externalIvyFile(baseDirectory(_/"myIvy"): This will set the custom-named settings file myIvy.xml in the project's base directory as the source for project dependencies. When using Ivy settings and configuration files, the configurations need to be mapped, because Ivy files specify their own configurations. So, classpathConfiguration must be set for the three main configurations. For example: classpathConfiguration in Compile := Compile classpathConfiguration in Test := Test classpathConfiguration in Runtime := Runtime Adding JAR files manually To handle dependencies manually in SBT, you need to create a lib folder in the project and add the JAR files to it. That is the default location where SBT looks for unmanaged dependencies. If you have the JAR files located in some other folder, you could specify that in the build definition. The key used to specify the source for manually added JAR files is unmanagedBase. For example, if the JAR files your project depends on are in project/extras/dependencies instead of project/lib, modify the value of unmanagedBase as follows: unmanagedBase <<= baseDirectory {base => base/"extras/dependencies"} Here, baseDirectory is the project's root directory. unmanagedJars is a task which lists the JAR files from the unmanagedBase directory. To see the list of JAR files in the interactive shell type, type the following: > show unmanaged-jars [info] ArrayBuffer() Or in the project folder, type: $ sbt show unmanaged-jars If you add a Spring JAR (org.springframework.aop-3.0.1.jar) to the dependencies folder, then the result of the previous command would be: > show unmanaged-jars [info] ArrayBuffer(Attributed(/home/introduction/extras/dependencies/ org.springframework.aop-3.0.1.jar)) It is also possible to specify the path(s) of JAR files for different configurations using unmanagedJars. In the build definition, the unmanagedJars task may need to be replaced when the jars are in multiple directories and other complex cases. unmanagedJars in Compile += file("/home/downloads/ org.springframework.aop-3.0.1.jar") Resolvers Resolvers are alternate resources provided for the projects on which there is a dependency. If the specified project's JAR is not found in the default repository, these are tried. The default repository used by SBT is Maven2 and the local Ivy repository. The simplest ways of adding a repository are as follows: resolvers += name at location. For example: resolvers += "releases" at "http://oss.sonatype.org/content/ repositories/releases" resolvers ++= Seq (name1 at location1, name2 at location2). For example: resolvers ++= Seq("snapshots" at "http://oss.sonatype.org/ content/repositories/snapshots", "releases" at "http://oss.sonatype.org/content/repositories/releases") resolvers := Seq (name1 at location1, name2 at location2). For example: resolvers := Seq("sgodbillon" at "https://bitbucket.org/ sgodbillon/repository/raw/master/snapshots/", "Typesafe backup repo" at " http://repo.typesafe.com/typesafe/repo/", "Maven repo1" at "http://repo1.maven.org/") ) You can also add their own local Maven repository as a resource using the following syntax: resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository" An Ivy repository of the file types URL, SSH, or SFTP can also be added as resources using sbt.Resolver. Note that sbt.Resolver is a class with factories for interfaces to Ivy repositories that require a hostname, port, and patterns. Let's see how to use the Resolver class. For filesystem repositories, the following line defines an atomic filesystem repository in the test directory of the current working directory: resolvers += Resolver.file ("my-test-repo", file("test")) transactional() For URL repositories, the following line defines a URL repository at http://example.org/repo-releases/: resolvers += Resolver.url(" my-test-repo", url("http://example.org/repo-releases/")) The following line defines an Ivy repository at http://joscha.github.com/play-easymail/repo/releases/: resolvers += Resolver.url("my-test-repo", url("http://joscha.github.com/play-easymail/repo/releases/")) (Resolver.ivyStylePatterns) For SFTP repositories, the following line defines a repository that is served by SFTP from the host example.org: resolvers += Resolver.sftp(" my-sftp-repo", "example.org") The following line defines a repository that is served by SFTP from the host example.org at port 22: resolvers += Resolver.sftp("my-sftp-repo", "example.org", 22) The following line defines a repository that is served by SFTP from the host example.org with maven2/repo-releases/ as the base path: resolvers += Resolver.sftp("my-sftp-repo", "example.org", "maven2/repo-releases/") For SSH repositories, the following line defines an SSH repository with user-password authentication: resolvers += Resolver.ssh("my-ssh-repo", "example.org") as("user", "password") The following line defines an SSH repository with an access request for the given user. The user will be prompted to enter the password to complete the download. resolvers += Resolver.ssh("my-ssh-repo", "example.org") as("user") The following line defines an SSH repository using key authentication: resolvers += { val keyFile: File = ... Resolver.ssh("my-ssh-repo", "example.org") as("user", keyFile, "keyFilePassword") } The next line defines an SSH repository using key authentication where no keyFile password is required to be prompted for before download: resolvers += Resolver.ssh("my-ssh-repo", "example.org") as("user", keyFile) The following line defines an SSH repository with the permissions. It is a mode specification such as chmod: resolvers += Resolver.ssh("my-ssh-repo", "example.org") withPermissions("0644") SFTP authentication can be handled in the same way as shown for SSH in the previous examples. Ivy patterns can also be given to the factory methods. Each factory method uses a Patterns instance which defines the patterns to be used. The default pattern passed to the factory methods gives the Maven-style layout. To use a different layout, provide a Patterns object describing it. The following are some examples that specify custom repository layouts using patterns: resolvers += Resolver.url("my-test-repo", url)( Patterns("[organisation]/[module]/ [revision]/[artifact].[ext]") ) You can specify multiple patterns or patterns for the metadata and artifacts separately. For filesystem and URL repositories, you can specify absolute patterns by omitting the base URL, passing an empty patterns instance, and using Ivy instances and artifacts. resolvers += Resolver.url("my-test-repo") artifacts "http://example.org/[organisation]/[module]/ [revision]/[artifact].[ext]" When you do not need the default repositories, you must override externalResolvers. It is the combination of resolvers and default repositories. To use the local Ivy repository without the Maven repository, define externalResolvers as follows: externalResolvers <<= resolvers map { rs => Resolver.withDefaultResolvers(rs, mavenCentral = false) } Summary In this article, we have seen how dependency management tools such as Maven and Ivy work and how SBT handles project dependencies. This article also talked about the different options that SBT provides to handle your project dependencies and configuring resolvers for the module on which your project has a dependency. Resources for Article : Further resources on this subject: So, what is Play? [Article] Play! Framework 2 – Dealing with Content [Article] Integrating Scala, Groovy, and Flex Development with Apache Maven [Article]
Read more
  • 0
  • 0
  • 14945

article-image-images-colors-and-backgrounds
Packt
07 Oct 2013
5 min read
Save for later

Images, colors, and backgrounds

Packt
07 Oct 2013
5 min read
(For more resources related to this topic, see here.) The following screenshot (Images and colors) shows the final result of this article:   Images and colors The following is the corresponding drawing.kv code: 64. # File name: drawing.kv (Images and colors) 65. <DrawingSpace>: 66. canvas: 67. Ellipse: 68. pos: 10,10 69. size: 80,80 70. source: 'kivy.png' 71. Rectangle: 72. pos: 110,10 73. size: 80,80 74. source: 'kivy.png' 75. Color: 76. rgba: 0,0,1,.75 77. Line: 78. points: 10,10,390,10 79. width: 10 80. cap: 'square' 81. Color: 82. rgba: 0,1,0,1 83. Rectangle: 84. pos: 210,10 85. size: 80,80 86. source: 'kivy.png' 87. Rectangle: 88. pos: 310,10 89. size: 80,80 This code starts with an Ellipse (line 67) and a Rectangle (line 71). We use the source property, which inserts an image to decorate the polygon. The image kivy.png is 80 x 80 pixels with a white background (without any alpha/transparency channel). The result is shown in the first two columns of the previous screenshot (Images and colors). In line 75, we use the context instruction Color to change the color (with the rgba property: red, green, blue, and alpha) of the coordinate space context. This means that the next VertexInstructions will be drawn with the color changed by rgba. A ContextInstruction changes the current coordinate space context. In the previous screenshot, the blue bar at the bottom (line 77) has a transparent blue (line 76) instead of the default white (1,1,1,1) as seen in the previous examples. We set the ends shape of the line to a square with the cap property (line 80). We change the color again in line 81. After that, we draw two more rectangles, one with the kivy.png image and other without it. In the previous screenshot (Images and color) you can see that the white part of the image has become as green as the basic Rectangle on the left. Be very careful with this. The Color instruction acts as a light that is illuminating the kivy.png image. This is why you can still see the Kivy logo on the background instead of it being all covered by the color. There is another important detail to notice in the previous screenshot. There is a blue line that crosses the first two polygons in front and then crosses behind the last two. This illustrates the fact that the instructions are executed in order and this might bring some unwanted results. In this example we have full control of the order but for more complicated scenarios Kivy provides an alternative. We can specify three Canvas instances (canvas.before, canvas, and canvas.after) for each Widget. They are useful to organize the order of execution to guarantee that the background component remains in the background, or to bring some of the elements to the foreground. The following drawing.kv file shows an example of these three sets (lines 92, 98, and 104) of instructions: 90. # File name: drawing.kv (Before and After Canvas) 91. <DrawingSpace>: 92. canvas.before: 93. Color: 94. rgba: 1,0,0,1 95. Rectangle: 96. pos: 0,0 97. size: 100,100 98. canvas: 99. Color: 100. rgba: 0,1,0,1 101. Rectangle: 102. pos: 100,0 103. size: 100,100 104. canvas.after: 105. Color: 106. rgba: 0,0,1,1 107. Rectangle: 108. pos: 200,0 109. size: 100,100 110. Button: 111. text: 'A very very very long button' 112. pos_hint: {'center_x': .5, 'center_y': .5} 113. size_hint: .9,.1 In each set, a Rectangle of different color is drawn (lines 95, 101, and 107). The following diagram illustrates the execution order of the canvas. The number on the top-left margin of each code block indicates the order of execution: Execution order of the canvas Please note that we didn't define any canvas, canvas.before, or canvas.after for the Button, but Kivy does. The Button is a Widget and it displays graphics on the screen. For example, the gray background is just a Rectangle. That means that it has instructions in its internal Canvas instances. The following screenshot shows the result (executed with python drawing.py --size=300x100): Before and after canvas The graphics of the Button (the child) are covered up by the graphics of instructions in the canvas.after. But what is executed between canvas.before and canvas? It could be code of a base class when we are working with inheritance and we want to add instructions in the subclass that should be executed before the base class Canvas instances. A practical example of this will be covered when we apply them in the last section of this article in the comic creator project. The canvas.before will also be useful when we study how to dynamically add instruction to Canvas instances For now, it is sufficient to understand that there are three sets of instructions (Canvas instances) that provide some flexibility when we are displaying graphics on the screen. We will now explore some more context instructions related to three basic transformations. Summary In this article we learned how to add images and colors to shapes and how to position graphics at a front or back level. Resources for Article: Further resources on this subject: Easily Writing SQL Queries with Spring Python [Article] Python Testing: Installing the Robot Framework [Article] Advanced Output Formats in Python 2.6 Text Processing [Article]
Read more
  • 0
  • 0
  • 4777

article-image-gamified-websites-framework
Packt
07 Oct 2013
15 min read
Save for later

Gamified Websites: The Framework

Packt
07 Oct 2013
15 min read
(For more resources related to this topic, see here.) Business objectives Before we can go too far down the road on any journey, we first have to be clear about where we are trying to go. This is where business objectives come into the picture. Although games are about fun, and gamification is about generating positive emotion without losing sight of the business objectives, gamification is a serious business. Organizations spend millions of dollars every year on information technology. Consistent and steady investment in information technology is expected to bring a return on that investment in the way of improved business process flow. It's meant to help the organization run smoother and easier. Gamification is all about "improving" business processes. Organizations try to improve the process itself, wherever possible, whereas technology only facilitates the process. Therefore, gamification efforts will be scrutinized under similar microscope and success metrics that information technology efforts will. The fact that customers, employees, or stakeholders are having more fun with the organization's offering is not enough. It will have to meet a business objective. The place to start with defining business objectives is with the business process that the organization is looking to improve. In our case, the process we are planning to improve is e-learning. We are looking at the process of K-12 aged persons learning "thinking". How does that process look right now? Image source: http://www.moddb.com/groups/critical-thinkers-of-moddb/images/critical-thinking-skills-explained In a full-blown e-learning situation, we would be looking to gamify as much of this process as possible. For our purpose, we will focus on the areas of negotiation and cooperation. According to the Negotiate and Cooperate phase of the Critical Thinking Process, learners consider different perspectives and engage in discussions with others. This gives us a clear picture of what some of our objectives might be. They might be, among others: Increasing engagement in discussion with others Increasing the level of consideration of different perspectives Note that these objectives are measurable. We will be able to test whether the increases/improvements we are looking for are actually happening over time. With a set of measurable objectives, we can turn our attention to the next step, that is target behaviors, in our Gamification Design Framework. Target behaviors Now that we are clear about what we are trying to accomplish with our system, we will focus on the actions we are hoping to incentivize: our target behaviors. One of the big questions around gamification efforts is can it really cause behavioral change. Will employees, customers, and stakeholders simply go back to doing things the way they are used to once the game is over? Will they figure out a way to "cheat" the system? The only way to meet long-term organizational objectives in a systematic way is the application to not only cause change for the moment, but lasting change over time. Many gamification applications fail in long-term behavior change, and here's why. Psychologists have studied the behavior change life cycle at length. . The study revealed that people go through five distinct phases when changing a behavior. Each phase presents a different set of challenges. The five phases of the behavioral life cycle are as follows: Awareness: Before a person will take any action to change a behavior, he/she must first be aware of their current behavior and how it might need to change. Buy in: After a person becomes aware that they need to change, they must agree that they actually need to change and make the necessary commitment to do so. Learn: But what actually does a person need to do to change? It cannot be assumed that he/she knows how to change. They must learn the new behavior. Adopt: Now that he/she has learned the necessary skills, they have to actually implement them. They need to take the new action. Maintain: Finally, after adopting a new behavior, it can only become a lasting change with constant practice. Image source: http://www.accenture.com/us-en/blogs/technology-labs-blog/archive/2012/03/28/gamification-and-the-behavior-change-lifecycle.aspx) How can we use this understanding to establish our target behaviors? Keep in mind that our objectives are to increase interaction through discussion and increase consideration for other perspectives. According to our understanding of changing behavior around our objectives, we need our users to: Become aware of their discussion frequency with other users Become aware that other perspectives exist Commit to more discussions with other users Commit to considering other users' perspectives Learn how to have more discussions with other users Learn about other users' perspectives Have more discussions with other users Actually consider other users' perspectives Continue to have more discussions with other users on a consistent basis Continue to consider other users' perspectives over time This outlines the list of activities that needs to be performed for our systems to meet our objectives. Of course, some of our target behaviors will be clear. In other cases, it will require some creativity on our part to get users to take these actions. So what are some possible actions that we can have our users take to move them along the behavior change life cycle? Check their discussion thread count Review the Differing Point of View section Set a target discussion amount for a particular time period Set a target number of Differing Points of View to review Watch a video (or some instructional material) on how to use the discussion area Watch a video (or some instructional material) on the value of viewing other perspectives Participate in the discussion groups Read through other users' discussions posts Participate in the discussion groups over time Read through other users' perspectives over time Some of these target behaviors are relatively straightforward to implement. Others will require more thought. More importantly, we have now identified the target behaviors we want our users to take. This will guide the rest of our development efforts. Players Although the last few sections have been about the serious side of things, such as objectives and target behaviors, we still have gamification as the focal point. Hence, from this point on we will refer to our users as players. We must keep in mind that although we have defined the actions that we want our players to take, the strategies to motivate them to take that action vary from player to player. Gamification is definitely not a one-size-fits-all process. We will have to look at each of our target behaviors from the perspective of our players. We must take their motivations into consideration, unless our mechanics are pretty much trial and error. We will need an approach that's a little more structured. According to the Bartle's Player Motivations theory, players of any game system fall into one of the following four categories: Killers: These are people motivated to participate in a gaming scenario with the primary purpose of winning the game by "acting on" other players. This might include killing them, beating, and directly competing with other players in the game. Achievers: These, on the other hand, are motivated by taking clear actions against the system itself to win. They are less motivated by beating an opponent than by achieving things to win. Socializers: These have very different motivations for participating in a game. They are motivated more by interacting and engaging with other players. Explorers: Like socializers, explorers enjoy interaction and engagement, but less with other players than with the system itself. The following diagram outlines each player motivation type and what game mechanic might best keep them engaged. Image source: http://frankcaron.com/Flogger/?p=1732 As we define our activity loops, we need to make sure that we include each of the four types of players and their motivations. Activity loops Gamified systems, like other systems, are simply a series of actions. The player acts on the system and the system responds. We refer to how the user interacts with the system as activity loops. We will talk about two types of activity loops, engagement loops and progression loops, to describe our player interactions. Engagement loops describe how a player engages the system. They outline what a player does and how the system responds. Activity will be different for players depending on their motivations, so we must also take into consideration why the player is taking the action he is taking. A progression loop describes how the player engages the system as a whole. It outlines how he/she might progress through the game itself. Whereas engagement loops discuss what the player does on a detailed level, progression loops outline the movement of the player through the system. For example, when a person drives a car, he/she is interacting with the car almost constantly. This interaction is a set of engagement loops. All the while, the car is going somewhere. Where the car is going describes its progression loops. Activity loops tend to follow the Motivation, Action, Feedback pattern. The players are sufficiently motivated to take an action. When the players take the action and they get a feedback from the system, the feedback hopefully motivates the players enough to take another action. They take that action and get more feedback. In a perfect world, this cycle would continue indefinitely and the players would never stop playing our gamified system. Our goal is to get as close to this continuous activity loop as we possibly can. Progression loops We have spent the last few pages looking at the detailed interactions that a player will have with the system in our engagement loops. Now it's time to turn our attention to the other type of activity loop, the progression loop. Progression loops look at the system at a macro level. They describe the player's journey through the system. We usually think about levels, badges, and/or modes when we are thinking about progression loops We answer questions such as: where have you been, where are you now, and where are you going. This can all be summed up into codifying the player's mastery level. In our application, we will look at the journey from the vantage point of a novice, an expert, and a master. Upon joining the game, players will begin at novice level. At novice level we will focus on: Welcome On-boarding and getting the user acclimated to using the system Achievable goals In the Welcome stage, we will simply introduce the user to the game and encourage him/her to try it out. Upon on-boarding, we need to make the process as easy as possible and give back positive feedback as soon as possible. Once the user is on board, we will outline the easiest way to get involved and begin the journey. At the expert level, the player is engaging regularly in the game. However, other players would not consider this player a leader in the game. Our goal at this level is to present more difficult challenges. When the player reaches a challenge that is appearing too difficult, we can include surprise alternatives along the way to keep him/her motivated until they can break through the expert barrier to master level. The game and other players recognize masters. They should be prominently displayed within the game and might tend to want to help others at novice and expert levels. These options should become available at later stages in the game. Fun After we have done the work of identifying our objectives, defining target behaviors, scoping our players, and laying out the activities of our system, we can finally think about the area of the system where many novice game designers start: the fun. Other gamification practitioners will avoid, or at least disguise, the fun aspect of the gamification design process. It is important that we don't over or under emphasize the fun in the process. For example, chefs prepare an entire meal with spices, but they don't add all spices together. They use the spices in a balanced amount in their cooking to bring flavor to their dishes. Think of fun as an array of spices that we can apply to our activity loops. Marc Leblanc has categorized fun into eight distinct categories. We will attempt to sprinkle just enough of each, where appropriate, to accomplish the desired amount of fun. Keep in mind that what one player will experience as fun will not be the same for another. One size definitely does not fit all in this case. Sensation: A pleasurable experience Narrative: An unfolding story Challenge: An obstacle course Fantasy: Make believe Fellowship: A social framework Discovery: Exploring uncharted territory Expression: Player is given a platform Submission: Mindless activity So how can we sparingly introduce the above dimensions of fun in our system? Action to take Dimension of fun Check their discussion thread count Challenge Review a differing point of the View section Discovery Set a target discussion  amount for a particular time period Challenge Set a target number of "Differing Points of View" to review Challenge Watch a video (or some instructional material) on the how to use the discussion area Challenge Watch a video (or some instructional material) on the value of viewing other perspectives Challenge Participate in the discussion groups Fellowship Expression Read through other users' discussions posts Discovery Participate in the discussion groups over time Fellowship Expression Read through other users' perspectives over time Discovery Tools We are finally at the stage from where we can begin implementation. At this point, we can look at the various game elements (tools) to implement our gamified system. If we have followed the framework upto this point, the mechanics and elements should become apparent. We are not simply adding leader boards or a point system for the sake of it. We can tie all the tools we use back to our previous work. This will result in a Gamification Design Matrix for our application. But before we go there, let's stop and take a look at some tools we have at our disposal. There are a myriad of tools, mechanics, and strategies at our disposal. New ones are being designed everyday. Here are a few of the most common mechanics that we will encounter when designing our gamified system: Achievements: These are specific objectives that a player meets. Avatars: These are visual representations of a player's role, persona, or character in a game. Badges: These are visual elements used to recognize a particular accomplishment. They give players a sense of pride that they can show off to others. Boss fight: This is an exceptionally difficult challenge in a game scenario, usually at the end of a level to demonstrate enough skill level to move up to the next level. Leaderboards: These show rankings of players publicly. They recognize an accomplishment like a badge, but they are visible for all to see. We see this almost every day, in every way from sports team rankings to sales rep monthly results. Points: These are rather straightforward. Players accumulate points and take various actions in the system. Quests/Mission: These are specialized challenges in a game scenario having narrative and objective as characteristics. Reward: This is anything used to extrinsically motivate the user to take a particular action. Team: This is a group of players playing as a single unit. Virtual assets: These are elements in the game that have some value and can be acquired or used to acquire other assets, whether tangible or virtual. Now it's time to turn and take off our gamification design hat and put on our developer hat. Let's start by developing some initial mockups of what our final site might look like using the design we have outlined previously. Many people develop mockups using graphics tools such as Photoshop or Gimp. At this stage, we will be less detailed in our mockups and simply use pencil sketches or a mockup tool such as Balsamiq. Login screen This is a mock-up of the basic login screen in our application. Players are accustomed to a basic login and password scenario we provide here. Account creation screen First time players will have to create an account initially. This is the mock-up of our signup page. Main Player Screen This captures the main elements of our system when a player is fully engaged with the system. Main Player Post Response Screen We have outlined the key functionality of our gamified system via mock-ups. Mock-ups are a means of visually communicating to our team what we are building and why we are building it. Visual mock-ups also give us an opportunity to uncover issues in our design early in the process. Summary Most gamified applications will fail due to a poorly designed system. Hence, we have introduced a Gamification Design Framework to guide our development process. We know that our chances of developing a successful system increase tremendously if we: Define clear business objectives Establish target behaviors Understand our players Work through the activity loops Remember the fun Optimize the tools Resources for Article: Further resources on this subject: An Introduction to PHP-Nuke [Article] Installing phpMyAdmin [Article] Getting Started with jQuery [Article]
Read more
  • 0
  • 0
  • 2565
article-image-customizing-linux-kernel
Packt
07 Oct 2013
5 min read
Save for later

Customizing a Linux kernel

Packt
07 Oct 2013
5 min read
(For more resources related to this topic, see here.) How to do it... First, we must go to the Buildroot folder (cd $HOME/work/Buildroot). We need to modify the kernel options, so enter make linux-menuconfig. Enter the General setup menu; we want to enable the LZMA support for the compressed kernel in order to reduce the total size of the system. This compression scheme is far better than standard GZIP, but at the cost of speed, it takes much more time to expand the kernel when booting. In order to enable this function, set the Kernel compression mode to LZMA, check the Support initial ramdisks compressed using LZMA option, and set the Built-in initramfs compression mode to LZMA. Another trick to reduce the size is to embed the RFS into the kernel; by doing this we can profit from the LZMA compression. Also, for the RFS, set the location of the roofs.cpio file in the Initramfs source file(s) option. Finally, check the Optimize for size option to enable some compiler flags for allowing the kernel to reduce the final size. Inside the Boot menu, we can configure the kernel boot sequence. This option is interesting to add a default command-line argument, which the kernel will use if the bootloader doesn't pass anything. So we can put our kernel arg line here just in case something fails in the bootloader. Inside the Networking menu, in the Networking options submenu, there are configurations related to networking protocols. You can configure all of the TCP/IP stack options here. Now, enter the Wireless menu and make sure that cfg80211 is enabled in order to use the Wi-Fi interface later. We will now revise the most common modification point in Linux kernel, the Device drivers menu. Here resides all of the options related with the support and configuration of the possible device drivers that Linux supports, so you need to configure here all of the devices that your board has. Also, it's a good idea to disable the support for the drivers that you won't use, so you can reduce the overall size. We will add support for Wi-Fi USB devices, so let's enter the Network devices support menu, and then the Wireless LAN submenu. For example, if your USB dongle is a Ralink one, enter Ralink driver support and set your device with an M, which means that you are including support for this device as a module that could be dynamically loaded when the device is detected. The other option will be to mark as an asterisk (*); this will include support inside the kernel itself, so you always have the driver ready. Loadable module drivers are a good idea because it gives you more flexibility and reduces the overall memory occupation when some devices are not needed. The next important item is the File systems menu, where the user can select the desired support for filesystems to mount the RFS; in our case, we need to select EXT3/4, NFS, and RAMFS. This is a good place to get more space by getting rid of unused filesystems that our system won't support. Now, exit the graphical menu. Linux configuration will be stored in a .config file, which we will save in a secure location in order to retain the changes that we made: cp output/build/linux-e959a8e/.config $HOME/work/project/linux.config We should then teach Buildroot where to get the configuration file for Linux; enter the Buildroot menu using make menuconfig. Go to the Kernel menu and set the Kernel configuration option to using a custom config file, write down the path to the linux.config file, and exit the menu. One last change is necessary, because now the RFS resides compressed inside the kernel. We need to modify the U-Boot script in order to not load the RFS, but just the kernel, into memory. Modify the boot script file $HOME/work/project/boot.txt to contain: load mmc 0:1 $kernel_addr zImage; setenv bootargs "$console_args $ramfs_args" bootz $kernel_addr Generate the script file with the command (you can add this line to your post-image.sh in order to generate it automatically each time the system is rebuilt): ../buildroot/output/build/uboot-rpi/tools/mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n 'u-boot script' -d boot.txt boot. scr Generate the system with the make command and copy the generated files to the SD card. The system should boot into the login prompt; enter the username as root without a password. How it works... Kernel configuration is one of the main tasks that any embedded project will face. The basic steps to configure your system will be to first identify all of the hardware devices on your board, and then the requirements of RFS support and networking protocols. As advised, usually you can add driver support in two ways: as a loadable module or by directly adding the driver support to the kernel. The module support is good enough to test your system and make the kernel size smaller (because the modules and .ko files reside in the RFS). Anyway, once your system is fully tested and stable, you can add the required drivers into the kernel and remove all of the modules that you don't need in order to reduce the overall size of your system. Another good idea is to back up your config file with all of the modifications in order to easily go back to working state and share your modifications with the rest of your team. Summary In this article, we learn about the most important part in any embedded system—the kernel. It has many configurable parameters and support for many external devices. It also helps you learn the basic configurations and how to add support for your peripherals. Resources for Article : Further resources on this subject: Installing VirtualBox on Linux [Article] Linux Shell Script: Tips and Tricks [Article] Linux Shell Script: Logging Tasks [Article]
Read more
  • 0
  • 0
  • 5965

article-image-cql-client-applications
Packt
04 Oct 2013
7 min read
Save for later

CQL for client applications

Packt
04 Oct 2013
7 min read
(For more resources related to this topic, see here.) Using the Thrift API The Thrift library is based on the Thrift RPC protocol. High-level clients built over it have been a standard way of building an application for a long time. In this section, we'll explain how to write a client application using CQL as the query language and thrift as the Java API. When we start Cassandra, by default it listens to Thrift clients (start_rpc: true property in the CASSANDRA_HOME/conf/cassandra.yaml file enables this). Let's build a small program that connects to Cassandra using the Thrift API, and runs CQL 3 queries for reading/writing data in the UserProfiles table we created for the facebook application. The program can be built by performing the following steps: For downloading the Thrift Library, you need to enter apache-assandra-thrift-1.2.x.jar (which is to be found in the CASSANDRA_HOME/lib folder) into your classpath. If your Java project is mavenized, you need to insert the following entry in pom.xml under the dependency section (version will vary depending upon your Cassandra server installation): <dependency> <groupId>org.apache.cassandra</groupId> <artifactId>cassandra-thrift</artifactId> <version>1.2.5</version> </dependency> For connecting to the Cassandra server on a given host and port, you need to open org.apache.thrift.transport.TTransport to the Cassandra node and create an instance of org.apache.cassandra.thrift.Cassandra.Client as follows: TTransport transport = new TFramedTransport(new TSocket("localhost", 9160)); TProtocol protocol = new TBinaryProtocol(transport); Cassandra.Client client = new Cassandra.Client(protocol); transport.open(); client.set_cql_version("3.0.0"); The default CQL version for Thrift is 2.0.0. You must set it to 3.0.0 if you are writing CQL 3 queries and don't want to see any version related errors. After you are done with transport, close it gracefully (usually at the end of read/write operations) as follows: transport.close(); Creating a schema : The executeQuery() utility method accepts String CQL 3 query and runs it: CqlResult executeQuery(String query) throws Exception { return client.execute_cql3_query(ByteBuffer.wrap(query.getBytes("UTF-8")), Compression.NONE, ConsistencyLevel.ONE); } Now, create keyspace and the table by directly executing CQL 3 query: //Create keyspace executeQuery("CREATE KEYSPACE facebook WITH replication = "{'class':'SimpleStrategy','replication_factor':3};"); executeQuery("USE facebook;"); //Create table executeQuery("CREATE TABLE UserProfiles(" +"email_id text," + "password text,"+ "name text," + "age int," + "profile_picture blob," + "PRIMARY KEY(email_id)" + ");" ); Reading/writing data: A couple of records can be inserted as follows: executeQuery("USE facebook;"); executeQuery("INSERT INTO UserProfiles(email_id, password, name, age, profile_picture) VALUES('john.smith@example.com','p4ssw0rd',' John Smith',32,0x8e37);"); executeQuery("INSERT INTO UserProfiles(email_id, password, name, age, profile_picture) VALUES('david.bergin@example.com','guess1t',' David Bergin',42,0xc9f1);"); Executing the SELECT query returns CQLResult, on which we can iterate easily to fetch records: CqlResult result = executeQuery("SELECT * FROM facebook.UserProfiles " + "WHERE email_id = 'john.smith@example.com';"); for (CqlRow row : result.getRows()) { System.out.println(row.getKey(); } Using the Datastax Java driver The Datastax Java driver is based on the Cassandra binary protocol that was introduced in Cassandra 1.2, and works only with CQL 3. The Cassandra binary protocol is specifically made for Cassandra in contrast to Thrift, which is a generic framework and has many limitations. Now, we are going to write a Java program that uses the Datastax Java driver for reading/writing data into Cassandra, by performing the following steps: Downloading the driver library : This driver library JAR file must be in your classpath in order to build an application using it. If you have a maven-based Java project, you need to insert the following entry into the pom.xml file under the dependeny section: <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>1.0.1</version> </dependency> This driver project is hosted on Github: (https://github.com/datastax/java-driver). It makes sense to check and download the latest version. Configuring Cassandra to listen to native clients : In the newer version of Cassandra, this would be enabled by default and Cassandra will listen to clients using binary protocol. But the earlier Cassandra installations may require enabling this. All you have to do is to check and enable the start_native_transport property into the CASSANDRA_HOME/conf/Cassandra.yaml file by inserting/uncommenting the following line: start_native_transport: true The port that Cassandra will use for listening to native clients is determined by the native_transport_port property. It is possible for Cassandra to listen to both Thrift and native clients simultaneously. If you want to disable Thrift, just set the start_rpc property to false in CASSANDRA_HOME/conf/Cassandra.yaml. Connecting to Cassandra : The com.datastax.driver.core.Cluster class is the entry point for clients to connect to the Cassandra cluster: Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").build(); After you are done with using it (usually when application shuts down), close it gracefully: cluster.shutdown(); Creating a session : An object of com.datastax.driver.core.Session allows you to execute a CQL 3 statement. The following line creates a Session instance: Session session = cluster.connect(); Creating a schema : Before reading/writing data, let's create a keyspace and a table similar to UserProfiles in the facebook application we built earlier: // Create Keyspace session.execute("CREATE KEYSPACE facebook WITH replication = " + "{'class':'SimpleStrategy','replication_factor':1};"); session.execute("USE facebook"); // Create table session.execute("CREATE TABLE UserProfiles(" + "email_id text," + "password text,"+ "name text," + "age int," + "profile_picture blob," + "PRIMARY KEY(email_id)" + ");" ); Reading/writing data : We can insert a couple of records as follows: session.execute("USE facebook"); session.execute("INSERT INTO UserProfiles(email_id, password, name, age, profile_picture) VALUES('john.smith@example.com','p4ssw0rd','John Smith',32,0x8e37);"); session.execute("INSERT INTO UserProfiles(email_id, password, name, age, profile_picture) VALUES('david.bergin@example.com','guess1t','David Bergin',42,0xc9f1);"); Finding and printing records : A SELECT query returns an instance of com.datastax.driver.core.ResultSet. You can fetch individual rows by iterating over it using the com.datastax.driver.core.Row object: ResultSet results = session.execute ("SELECT * FROM facebook.UserProfiles " + "WHERE email_id = 'john.smith@example.com';"); for (Row row : results) { System.out.println ("Email: " + row.getString("email_id") + "tName: " + row.getString("name")+ "t Age : " + row.getInt("age")); } Deleting records : We can delete a record as follows: session.execute("DELETE FROM facebook.UserProfiles WHERE email_id='john.smith@example.com';"); Using high-level clients In addition to the libraries based on Thrift and binary protocols, some high-level clients are built with the purpose to ease development and provide additional services, such as connection pooling, load balancing, failover, secondary indexing, and so on. Some of them are listed here: Astyanax (https://github.com/Netflix/astyanax): Astyanax is a high-level Java client for Cassandra. It allows you to run both simple and prepared CQL queries. Hector (https://github.com/hector-client/hector): Hector is a high-level client for Cassandra. At the time of writing this book, it supported CQL 2 only (not CQL 3). Kundera (https://github.com/impetus-opensource/Kundera): Kundera is a JPA 2.0-based object datastore mapping library for Cassandra and many other NoSQL datastores. CQL 3 queries are run with Kundera using the native queries as described in JPA specification. Summary From this article, we basically learn about using CQL in queries using three different preceding methods. Resources for Article : Further resources on this subject: Quick start – Creating your first Java application [Article] Apache Cassandra: Libraries and Applications [Article] Getting Started with Apache Cassandra [Article]
Read more
  • 0
  • 0
  • 2129
Modal Close icon
Modal Close icon